常见排序算法

假设含有n个记录的序列为{r1​,r2​,…,rn​},其相应的关键字分别为{k1​,k2​,…,kn​},需确定1,2, 3, …, n的一种排列p1​,p2​,…,pn​,使其相应的关键字满足kp1​ ≤kp2​≤…≤kpn​非递减(或非递增)关系,即使得序列变成一个按关键字有序的序列{rp1​,rp2​,…,rpn​}

[1, 2, 32, 23, 321, 45, 8, 90, 227, 99]从小到大排列(堆排序 我自己还没搞懂 先放着)

常见排序

冒泡排序
先拿第1第2个数比较,谁大谁后面,接着第2个跟第3个,继续...,最后的那个数一定是最大的。接下来混乱的序列就少了一位,继续剩下的序列继续上面的一轮。这个过程就像一个波浪一次把最大值从前面推到后面

public static void main(String[] args) { // TODO Auto-generated method stub int []arr= {1, 2, 32, 23, 321, 45, 8, 90, 227, 99}; for(int i=0;i<arr.length-1;i++) { for(int j=0;j<arr.length-i-1;j++) { if(arr[j]>arr[j+1]) { int temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } for(int a:arr) { System.out.print(a+" "); } } //1 2 8 23 32 45 90 99 227 321

选择排序
冒泡排序每次比较后符合要求的都去交换,有些处于中间值的,不是要不断的被交换,不是很浪费时间?能不能选出这段序列中最大的那个数,然后放到最后边? 这就是选择排序。

public static void main(String[] args) { int []arr= {1, 2, 32, 23, 321, 45, 8, 90, 227, 99}; for(int i=0;i<arr.length-1;i++) { int k=i; //位置还不确定的数据 for(int j=i+1;j<arr.length;j++) { if(arr[j]<arr[k]) { k=j; //遍历找到比k小的索引,然后把j赋给k; } } if(i!=k) { int temp=arr[i]; arr[i]=arr[k]; arr[k]=temp; } } for(int a:arr) { System.out.print(a+" "); } } //1 2 8 23 32 45 90 99 227 321

插入排序
举个例子,假设现在桌面有几张牌,每次拿起一张,我们在排序的时候会很自然的将牌按照顺序插入合适的位置。这个思想就是插入排序。

public static void insertSort(int[] arr) { int j = 0; for (int i = 1; i < arr.length; i++) { int temp = arr[i];//要插入的值,i位置空出来了 for (j = i; j > 0 && arr[j - 1] > temp; j--) { arr[j] = arr[j - 1];//j-1 扔到空出来的位置 } arr[j] = temp;//temp 扔到空出来的位置 } } //1 2 8 23 32 45 90 99 227 321

希尔排序
希尔排序排序是插入排序的改进算法,实现原理是将整个无序列分割成若干小的子序列分别进行插入排序,希尔排序并不稳定。该方法又称缩小增量排序。

public static void shellSort(int[] a) { int dk;//步长 for (dk = a.length / 2; dk > 0; dk /= 2) { for (int i = dk; i < a.length; i++) { int temp = a[i];//要插入的值,i位置空出来了 int j; for (j = i; j >= dk && temp < a[j - dk]; j -= dk)//步长为dk的插入排序 a[i] = a[j - dk]; //j - dk 扔到空出来的位置 a[j] = temp;//temp 扔到空出来的位置 } } } //1 2 8 23 32 45 90 99 227 321

归并排序
将带排序序列分成小组,每个小组自己先弄成有序的,再汇总,这样这种分而治之思想的实际上就是归并排序。

public static void mergerSort(int arr[], int low, int high) { int mid = (low + high) >> 1; if (low < high) { mergerSort(arr, low, mid); mergerSort(arr, mid + 1, high); merger(arr, low, mid, high); } } public static void merger(int arr[], int low, int mid, int high) { int temp[] = new int[high - low + 1]; //临时数组 int t = 0;//临时数组的首索引 int first = low;//第一个数组的首索引 int second = mid + 1;//第二个数组的首索引 // 将练个有序数组比较插入临时数组 while (first <= mid && second <= high) { temp[t++] = arr[first] < arr[second] ? arr[first++] : arr[second++]; } // 将数组剩余部分接到临时数组尾部 while (first <= mid) { temp[t++] = arr[first++]; } while (second <= high) { temp[t++] = arr[second++]; } // 将临时数据合并到原始数组 for (int i = 0; i < temp.length; i++) { arr[i + low] = temp[i]; } } //1 2 8 10 23 32 45 90 99 227 321

快速排序
举个例子:上体育课的时候要高个子站后面矮个子站前面,教练没办法一开始就一眼看出谁高谁矮对,那么多人,肯定是随便逮一个逮个人,来以他为基准进行排序。要求小个子的站这人的前边,大个子的站后边。
而这就是快速排序的核心思想。

public static void quickSort(int arr[], int low, int high) { if (low < high) { int index = part(arr, low, high); quickSort(arr, low, index - 1); quickSort(arr, index + 1, high); } } public static int part(int arr[], int low, int high) { int s1=low,s2=high;//定义哨兵 int key = arr[low]; while (s1 < s2) { while (s1 < s2 && (arr[s2] >= key)) {//哨兵2 向左巡逻 查找小于arr[low]的位置 停下 s2--; } swap(arr,s1, s2); while (s1 < s2 && arr[s1] <= key) {//哨兵1 向右巡逻 查找大于arr[low]的位置 停下 s1++; } swap(arr, s1, s2); } return s1; } public static void swap(int arr[], int s1, int s2) { int temp = arr[s1]; arr[s1] = arr[s2]; arr[s2] = temp; } //1 2 2 6 8 10 23 32 45 90 99 321

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfpff.html