六大排序算法及Java实现

冒泡排序

基本思想:

冒泡排序,类似于水中冒泡,较大的数沉下去,较小的数慢慢冒起来,假设从小到大,即为较大的数慢慢往后排,较小的数慢慢往前排。

算法平均时间复杂度为O(n^2),且较为稳定

img

代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BubbleSort {
  public static int[] Data = new int[20];   // 数据数组

  public static void main(String[] args) {

    int Index;   // 数组下标变量

    System.out.println("Input the values(Exit for 0):");

    Index = 0;

    InputStreamReader is = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(is);
    StringTokenizer st;

    do {
      System.out.print("Data:" + Index + ":");
      try {
        String myLine = br.readLine();
        st = new StringTokenizer(myLine);
        Data[Index] = Integer.parseInt(st.nextToken());
      } catch (IOException ioe) {
        System.out.print("IO Error:" + ioe);
      }
      Index++;
    } while (Data[Index - 1] != 0);

    Index--;

    System.out.println("Index:" + Index);
    printArray(Data, Index);

    bubblesort(Index);

    System.out.println("");
    printArray(Data, Index);
  }

  public static void printArray(int[] array, int Index) {
    for (int i = 0; i < Index; i++) {
      System.out.print(array[i] + " ");
    }
    System.out.println("");
  }

  public static void bubblesort(int Index) {
    for (int i = 0; i < Index - 1; i ++) {
      for (int j = i + 1; j < Index; j ++) {
        if (Data[i] > Data[j]) {
          swap(Data, i, j);
        }
      }
    }
  }

  private static void swap(int[] array, int ind1, int ind2) {
    int temp = array[ind1];
    array[ind1] = array[ind2];
    array[ind2] = temp;
  }
}

选择排序

主要目标:

每次遍历找到剩余数组中最小的元素

中心思想:

1.第一个循环初始化最小值和最小值索引

2.在第一个循环内部再进行一次循环,对数组元素遍历比较,交换最小值及其索引

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class SelectSort {
  public static int[] Data = new int[20];   // 数据数组

  public static void main(String[] args) {

    int Index;   // 数组下标变量

    System.out.println("Input the values(Exit for 0):");

    Index = 0;

    InputStreamReader is = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(is);
    StringTokenizer st;

    do {
      System.out.print("Data:" + Index + ":");
      try {
        String myLine = br.readLine();
        st = new StringTokenizer(myLine);
        Data[Index] = Integer.parseInt(st.nextToken());
      } catch (IOException ioe) {
        System.out.print("IO Error:" + ioe);
      }
      Index++;
    } while (Data[Index - 1] != 0);

    Index--;

    System.out.println("Index:" + Index);
    printArray(Data, Index);

    selectsort(Index);

    System.out.println("");
    printArray(Data, Index);
  }

  public static void printArray(int[] array, int Index) {
    for (int i = 0; i < Index; i++) {
      System.out.print(array[i] + " ");
    }
    System.out.println("");
  }

  public static void selectsort(int Index) {
    int min = 32767;
    int minIndex = 0;

    for(int i = 0; i < Index - 1; i++) {
      min = 32767;
      minIndex = i;
      for (int j =i;j < Index; j++) {
        if (min > Data[j]) {
          min = Data[j];
          minIndex = j;
        }
      }
      swap(Data, minIndex, i);
    }
  }

  private static void swap(int[] array, int ind1, int ind2) {

    int temp = array[ind1];
    array[ind1] = array[ind2];
    array[ind2] = temp;
  }

}

插入排序

插入排序是一种简单直观而且稳定的排序算法,时间复杂度O(n^2 ),若列表初始排序为正序,则时间复杂度为O(n),反序或无序均为O(n^2 )

插入排序对几乎已经排好序的数据操作时,效率很高

1 基本思想

将数组的第一个数认为是有序数组,从后往前(从前往后)扫描该有序数组,把数组中其余n-1个数,根据数值的大小,插入到有序数组中,直至数组中的所有数有序排列为止。这样的话,n个元素需要进行n-1趟排序!!!

img

Java代码实现

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;

public class insertsort {
  public static int[] Data = new int[10];   // 数据数组

  public static void main(String[] args) {

    int i;   // 循环变量
    int Index;   // 数组下标变量

    System.out.println("Input the values(Exit for 0):");

    Index = 0;

    Scanner input = new Scanner(System.in);

    InputStreamReader is = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(is);
    StringTokenizer st;

    do {
      System.out.print("Data:" + Index + ":");
      try {
        String myLine = br.readLine();
        st = new StringTokenizer(myLine);
        Data[Index] = Integer.parseInt(st.nextToken());
      } catch (IOException ioe) {
        System.out.print("IO Error:" + ioe);
      }
      Index++;
    } while (Data[Index - 1] != 0);

    Index--;

    System.out.println("Index:" + Index);
    printArray(Data, Index);

    InsertSort(Index);

    System.out.println("");
    printArray(Data, Index);
  }

  public static void printArray(int[] array, int Index) {
    for (int i = 0; i < Index; i++) {
      System.out.print(array[i] + " ");
    }
    System.out.println("");
  }

  public static void InsertSort(int Index) {
    int i, j, l;
    int InsertNode;   // 哨兵

    for (i = 1; i < Index; i++) {
      InsertNode = Data[i];

      System.out.println("\n---开始寻找哨兵---");
      j = i - 1;
      while (j >= 0 && Data[j] > InsertNode) {
        Data[j + 1] = Data[j];
        j--;
        printArray(Data, Index);
      }
      System.out.println("---开始插入哨兵---");
      Data[j + 1] = InsertNode;
      printArray(Data, Index);
    }
  }
}

堆排序

​ 堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最好、最坏、平均时间复杂度均为O(nlogn),它也是不稳定排序。

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

img

基本思想

将排序序列构造成一个大(小)顶堆,此时整个序列的最大值就是堆顶的根节点。将末尾元素进行交换,此时末尾就为最大值。然后将剩余元素重新构造堆,反复执行。

步骤一: 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。

步骤二: 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

不错的博客讲解

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;


public class HeapSort {
  public static int[] Data = new int[20];   // 数据数组

  public static void main(String[] args) {

    int Index = 0;   // 数组下标变量

    System.out.println("Input the values(Exit for 0):");

    InputStreamReader is = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(is);
    StringTokenizer st;

    do {
      System.out.print("Data:" + Index + ":");
      try {
        String myLine = br.readLine();
        st = new StringTokenizer(myLine);
        Data[Index] = Integer.parseInt(st.nextToken());
      } catch (IOException ioe) {
        System.out.print("IO Error:" + ioe);
      }
      Index++;
    } while (Data[Index - 1] != 0);

    Index--;

    System.out.println("Index:" + Index);
    printArray(Data, Index);

    heapsort(Index);

    System.out.println("");
    printArray(Data, Index);
  }

  public static void printArray(int[] array, int Index) {
    for (int i = 0; i < Index; i++) {
      System.out.print(array[i] + " ");
    }
    System.out.println("");
  }

  /**
   * 将数组排列为大顶堆
   *
   * @param arr    数组
   * @param ind    根节点
   * @param length 数组长度
   */
  public static void adjustHeap(int[] arr, int ind, int length) {

    int temp = arr[ind];

    for(int i = ind * 2 + 1; i < length; i = 2 * i + 1) {

      if (i + 1 < length && arr[i] < arr[i + 1]) {
        i++;
      }

      if (arr[i] > temp) {
        arr[ind] = arr[i];
        ind = i;
      } else {
        break;
      }
    }
    arr[ind] = temp;
  }

  public static void heapsort(int Index) {

    // 构建大顶堆
    for (int i = Index / 2 - 1; i >= 0; i--) {
      adjustHeap(Data, i, Index);
    }

    for (int j = Index - 1; j > 0; j--) {
      swap(Data, 0, j);   // 将堆顶元素与末尾元素进行交换
      adjustHeap(Data, 0, j);   //重新对堆进行调整
    }
  }

  private static void swap(int[] array, int ind1, int ind2) {

    int temp = array[ind1];
    array[ind1] = array[ind2];
    array[ind2] = temp;
  }
}

希尔排序

希尔排序也是插入排序的一种,它是经过改进之后的一个更高效的版本。

基本思想:

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

img

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class ShellSort {
  public static int[] Data = new int[20];   // 数据数组

  public static void main(String[] args) {

    int Index;   // 数组下标变量

    System.out.println("Input the values(Exit for 0):");

    Index = 0;

    InputStreamReader is = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(is);
    StringTokenizer st;

    do {
      System.out.print("Data:" + Index + ":");
      try {
        String myLine = br.readLine();
        st = new StringTokenizer(myLine);
        Data[Index] = Integer.parseInt(st.nextToken());
      } catch (IOException ioe) {
        System.out.print("IO Error:" + ioe);
      }
      Index++;
    } while (Data[Index - 1] != 0);

    Index--;

    System.out.println("Index:" + Index);
    printArray(Data, Index);

    shellsort(Index);

    System.out.println("");
    printArray(Data, Index);
  }

  public static void printArray(int[] array, int Index) {
    for (int i = 0; i < Index; i++) {
      System.out.print(array[i] + " ");
    }
    System.out.println("");
  }

  public static void shellsort(int Index) {
    int temp;

    for (int gap = Index/2; gap > 1; gap /= 2) {

      // 插入排序
      System.out.println("---插入排序gap:" + gap + " ---");
      for(int i = gap; i < Index; i++) {
        System.out.println("i:" + i);
        int j = i;

        while (j - gap >= 0 && Data[j] < Data[j - gap]) {
          System.out.println("j:" + j);

          temp = Data[j];
          Data[j] = Data[j - gap];
          Data[j - gap] = temp;

          printArray(Data, Index);

          j -= gap;
        }

      }
      System.out.println("");
    }
  }
}

快速排序

主要目标:

找到每个数组元素正确的索引值

中心思想:
  1. 将数组第一个元素设为基准元素

  2. 设两个变量 哨兵i 和 哨兵j,先从j开始,使其从最后一位索引开始递减(j必须大于等于i),直至找到小于基准元素的值,暂停

  3. 哨兵i从第一位索引开始递增(i必须小于等于j),直至找到大于基准元素的值,暂停,若i!= j,则交换 i 和 j 所在位置的数组元素

  4. 若 i==j ,则交换基准元素和i所在位置的数组元素,并且此时根据 索引i 将数组分为前后两部分,将这两个数组进行递归操作。

这篇博客讲的还不错 通俗易懂

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class QuickSort {
  public static int[] Data = new int[20];   // 数据数组

  public static void main(String[] args) {

    int Index;   // 数组下标变量

    System.out.println("Input the values(Exit for 0):");

    Index = 0;

    InputStreamReader is = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(is);
    StringTokenizer st;

    do {
      System.out.print("Data:" + Index + ":");
      try {
        String myLine = br.readLine();
        st = new StringTokenizer(myLine);
        Data[Index] = Integer.parseInt(st.nextToken());
      } catch (IOException ioe) {
        System.out.print("IO Error:" + ioe);
      }
      Index++;
    } while (Data[Index - 1] != 0);

    Index--;

    System.out.println("Index:" + Index);
    printArray(Data, Index);

    quicksort(0, Index - 1);

    System.out.println("");
    printArray(Data, Index);
  }

  public static void printArray(int[] array, int Index) {
    for (int i = 0; i < Index; i++) {
      System.out.print(array[i] + " ");
    }
    System.out.println("");
  }

  public static void quicksort(int left, int right) {
    int i = left, j = right;
    int base = Data[left];

//    System.out.print("\n===该数组为");
//    for (int k = left; k <= right; k ++) {
//      System.out.print(" " + Data[k]);
//    }
//    System.out.println(" ===\n");

    while (i < j) {
      while (Data[j] >= base && j > i) {
        j--;
      }

      while (Data[i] <= base && i < j) {
        i++;
      }

      if (i == j) {
        swap(Data, left, i);
//        System.out.println("\n---改变哨兵---");
//        printArray(Data, Data.length);
        quicksort(left, i - 1);
        quicksort(i + 1, right);
        break;
      } else {
        swap(Data, i, j);
//        System.out.printf("\n---交换哨兵i: %d j: %d---\n", i, j);
//        printArray(Data, Data.length);
      }
    }
  }

  private static void swap(int[] array, int ind1, int ind2) {

    int temp = array[ind1];
    array[ind1] = array[ind2];
    array[ind2] = temp;
  }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值