一、冒泡排序
1、定义:比较相邻的元素。从最后一个数跟倒数倒二个数两两比较,大的往后排。
2、代码
import java.util.Arrays; public class BubbleTest { public static void main(String[] args){ int[] a=new int[]{6,9,1,4,5,8,7,0,2,3}; System.out.println("排序前: " + Arrays.toString(a)); BubbleSort(a); System.out.println("排序后: " + Arrays.toString(a)); } public static void BubbleSort(int[] arr){ int len = arr.length; //外循环表示趟数 for(int i = 0; i < len; i++){ boolean flag = false; //内循环进行排序比较 for(int j = len-1; j > i; j--){ if(arr[j-1] > arr[j]){ int temp = arr[j-1]; arr[j-1] = arr[j]; arr[j] = temp; flag = true; } } // 如果没有发生交换,则已经有序,结束冒泡 if(flag == false){ return; } System.out.println("第"+ i +"趟: " + Arrays.toString(arr)); } } }
二、选择排序
1、定义:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止
2、流程
(1)从待排序序列中,找到关键字最小的元素;
(2)如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
(3)从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。

3、代码
import java.util.Arrays; public class ChooseTest { public static void main(String[] args){ int[] a=new int[]{6,9,1,4,5,8,7,0,2,3}; System.out.println("排序前: " + Arrays.toString(a)); ChooseSort(a); System.out.println("排序后: " + Arrays.toString(a)); } public static void ChooseSort(int[] arr){ int len = arr.length; //遍历获取最小值 //要排序N个数,当排到N-1遍遍历之后,已经是有序 for(int i = 0; i < len-1; i++){ int temp = 0; int index = i;//用来存放最小值的索引 //内循环进行排序比较 for(int j = i+1; j <len; j++){ if(arr[index] > arr[j]){ index = j; } } // 将找到的第i个最小值放在i位 temp = arr[index]; arr[index] = arr[i]; arr[i] = temp; System.out.println("第"+ i +"趟: " + Arrays.toString(arr)); } } }
三、快速排序
1、定义:通过一趟排序将要排序的数据分割成独立的两部分:分割点左边都是比它小的数,右边都是比它大的数。然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
例如:
分别从初始序列“6 1 2 7 9 3 4 5 10 8”两端开始“探测”。先从右往左找一个小于6的数,再从左往右找一个大于6的数,然后交换他们。这里可以用两个变量i和j,分别指向序列最左边和最右边。

哨兵j一步一步地向左挪动(即j–),直到找到一个小于6的数停下来。接下来哨兵i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后哨兵j停在了数字5面前,哨兵i停在了数字7面前。然后交换哨兵i和哨兵j所指向的元素的值。

第一次交换结束,接下来开始哨兵j继续向左挪动,发现了4(比基准数6要小,满足要求)之后停了下来。哨兵i也继续向右挪动的,他发现了9(比基准数6要大,满足要求)之后停了下来。此时再次进行交换。

第二次交换结束,“探测”继续。哨兵j继续向左挪动,他发现了3(比基准数6要小,满足要求)之后又停了下来。哨兵i继续向右移动,糟啦!此时哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。说明此时“探测”结束。我们将基准数6和3进行交换。

到此第一轮“探测”真正结束。此时以基准数6为分界点,6左边的数都小于等于6,6右边的数都大于等于6。回顾一下刚才的过程,其实哨兵j的使命就是要找小于基准数的数,而哨兵i的使命就是要找大于基准数的数,直到i和j碰头为止。
现在基准数6已经归位,它正好处在序列的第6位。此时我们已经将原来的序列,以6为分界点拆分成了两个序列,左边的序列是“3 1 2 5 4”,右边的序列是“9 7 10 8”。接下来分别用场面的方面处理6左边序列和右边序列。左边的序列是“3 1 2 5 4”。请将这个序列以3为基准数进行调整,使得3左边的数都小于等于3,3右边的数都大于等于3。
import java.util.Arrays; public class FastSort{ public static void main(String []args){ int[] a = {10,7,2,4,7,62,3,4,2,1,8,9,19}; int start = 0; int end = a.length-1; System.out.println("排序前: " + Arrays.toString(a)); sort(a,start,end); System.out.println("排序后: " + Arrays.toString(a)); } public static void sort(int[] a,int low,int high){ int start = low; int end = high; int key = a[low]; while(end>start){ //从后往前比较 while(end>start&&a[end]>=key)//如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较 end--; if(a[end]<=key){ int temp = a[end]; a[end] = a[start]; a[start] = temp; } //从前往后比较 while(end>start&&a[start]<=key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置 start++; if(a[start]>=key){ int temp = a[start]; a[start] = a[end]; a[end] = temp; } //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用 } //递归 if(start>low) sort(a,low,start-1);//左边序列。第一个索引位置到关键值索引-1 if(end<high) sort(a,end+1,high);//右边序列。从关键值索引+1到最后一个 } }
四、直接插入排序
1、定义:每一趟将一个待排序的记录,按照其关键字的大小插入到有序队列的合适位置里,知道全部插入完成。

2、代码
例子一:
import java.util.Random; public class InsertSort { public void insertSort(int[] list) { // 打印第一个元素 System.out.format("i = %d:\t", 0); printPart(list, 0, 0); // 第1个数肯定是有序的,从第2个数开始遍历,依次插入有序序列 for (int i = 1; i < list.length; i++) { int j = 0; int temp = list[i]; // 取出第i个数,和前i-1个数比较后,插入合适位置 // 因为前i-1个数都是从小到大的有序序列,所以只要当前比较的数(list[j])比temp大,就把这个数后移一位 for (j = i - 1; j >= 0 && temp < list[j]; j--) { list[j + 1] = list[j]; } list[j + 1] = temp; System.out.format("i = %d:\t", i); printPart(list, 0, i); } } // 打印序列 public void printPart(int[] list, int begin, int end) { for (int i = 0; i < begin; i++) { System.out.print("\t"); } for (int i = begin; i <= end; i++) { System.out.print(list[i] + "\t"); } System.out.println(); } public static void main(String[] args) { // 初始化一个随机序列 /**final int MAX_SIZE = 10; int[] array = new int[MAX_SIZE]; Random random = new Random(); for (int i = 0; i < MAX_SIZE; i++) { array[i] = random.nextInt(MAX_SIZE); }*/ int[] array=new int[]{6,9,1,4,5,8,7,0,2,3}; // 调用插入排序方法 InsertSort insert = new InsertSort(); System.out.print("排序前:\t"); insert.printPart(array, 0, array.length - 1); insert.insertSort(array); System.out.print("排序后:\t"); insert.printPart(array, 0, array.length - 1); } }
例子2:
import java.lang.reflect.Array; import java.util.Arrays; public class Solution { public static void main(String[] args) { int[] a=new int[]{6,9,1,4,5,8,7,0,2,3}; System.out.println("排序前: " + Arrays.toString(a)); InsertSort(a); System.out.println("排序前: " + Arrays.toString(a)); } public static void InsertSort(int [] arr){ int value;//待插入元素 int index;//初始值为待插入元素前一个元素的索引 //i从第二个元素开始,默认第一个元素是有序的 for(int i= 1 ; i< arr.length;i++){ value = arr[i]; index = i - 1;//初始为前一个元素 while(index >=0 && value < arr[index]){ //需要保证index合法 //每当前面的元素比待插入元素大,就向后移动 arr[index + 1] = arr[index]; //不用怕覆盖,因为value保存着待插入的值 index--; } //当退出循环,表明已经找到了待插入位置,即index + 1 arr[index + 1] = value; System.out.println("第"+i+"次排序: "+Arrays.toString(arr)); } } }
五、希尔排序
1、定义:又称为缩小增量排序,它是一种插入排序。即把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。希尔排序的一个特点是:子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。

2、流程
(1)在第一趟排序中,我们不妨设 gap1 = N / 2 ,然后分为段排序;
(2)我们把上次的 gap 缩小一半,即 gap2 = gap1 / 2(取整);
(3)在第三趟排序中,再次把 gap 缩小一半,即gap3 = gap2 / 2。
3、代码:、
import java.util.Arrays; public class ShellTest { public static void main(String[] args){ int[] a = {5,2,4,1,3,9,8,6,7,0}; System.out.println("排序前: " + Arrays.toString(a)); ShellSort(a); System.out.println("排序后: " + Arrays.toString(a)); } public static void ShellSort(int[] arr){ //只有一个元素或者元素为空时,直接返回数组 /**if(arr.length<2){ return arr; }*/ // 获得每次分组的步长 int len = arr.length/2; while(len >= 1){ for(int i = len; i < arr.length; i++){ int shellcCode = arr[i]; int j = i-len; while(j >= 0 && shellcCode < arr[j]){ arr[j+len] = arr[j]; j -= len; } arr[j+len] = shellcCode; } System.out.println("gap = "+len+":"+ Arrays.toString(arr)); len = len/2; } //return arr; } }
六、二分插入排序(又称折半插入排序)
直接插入需要将有序数据一个个进行查找,效率较慢,二分插入的中心思想就是使用二分查找法在有序区间进行查找,减少查找量。
import java.util.Arrays; class Untitled { public static void main(String[] args) { //定义一个长度为10的数组 int[] arr = { 1, 3, 4, 2, 6, 7, 8, 0, 5 }; System.out.println("排序前:" + Arrays.toString(arr)); long startTime = System.nanoTime(); // 获取排序开始时间 for(int i=1;i<=arr.length-1;i++) { if(arr[i]<arr[i-1]) { int low=0; int hight=i-1; int temp=arr[i]; while(low<=hight) { int mid=(low+hight)/2; if(temp<arr[mid]) { hight=mid-1; }else { low=mid+1; } } for(int j=i-1;j>=low;j--) { arr[j+1]=arr[j]; } arr[low]=temp; } } long endTime = System.nanoTime(); // 获取排序结束时间 System.out.println("排序結果:" + Arrays.toString(arr)); System.out.println("程序运行时间: " + (endTime - startTime) + "ns"); } }
浙公网安备 33010602011771号