排序
冒泡排序

代码:
1 public static void ArraySortTest() { 2 3 int[] ages= {21,27,31,19,50,32,16,25}; 4 System.out.println(Arrays.toString(ages)); 5 //控制比较轮数 6 for(int i=1;i<ages.length;i++) { 7 //每轮比较多少 8 for(int j=0;j<ages.length-i;j++) { 9 if(ages[j]>ages[j+1]) { 10 int tmp=0; 11 tmp=ages[j]; 12 ages[j]=ages[j+1]; 13 ages[j+1]=tmp; 14 } 15 } 16 } 17 System.out.println(Arrays.toString(ages));
选择排序
1、记录数组第一个元素的值(数组长度n)。
2、遍历n-1次,用该值与其他元素比较,找到最大或者最小的一个数交换。
3、记录数组第二个元素的值。
4、遍历n-2次,用该值与其他元素比较,找到最大或者最小的一个数交换。
5、重复上述步骤,遍历N次,直到没有要比较的数。
代码:
1 int array[] = { 7,10,12,3,9,5 }; 2 for (int i = 0; i < 6; i++) 3 { 4 int minkey = array[i]; 5 for (int j = i + 1; j < 6; j++) 6 { 7 if (minkey < array[j]) 8 { 9 int tamp = array[j]; 10 array[j] = minkey; 11 minkey = tamp; 12 } 13 } 14 array[i] = minkey; 15 }
插入排序
基本思想:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表只包含一个元素,无序表中包含
有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,
将它插入到有序表中的适当位置,使之成为新的有序表。
代码:
1 publicstaticvoidinsertSort(intarr[]) { 2 for (inti = 1; i < arr.length; i++) { 3 //定义待插入的值 4 intinsertVal = arr[i]; 5 intinsertIndex = i - 1; 6 while (insertIndex >= 0 && insertVal < arr[insertIndex]) { 7 //说明待排序的值小于前面的值,所以前面的要往后移 8 arr[insertIndex + 1] = arr[insertIndex]; 9 insertIndex--; 10 } 11 //当退出while循环时,说明找到插入位置,insertIndex+1 12 arr[insertIndex + 1] = insertVal; 13 System.out.println("第" + i + "轮插入:"); 14 System.out.println(Arrays.toString(arr)); 15 } 16 }
希尔排序
基本思想:希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,
每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
交换时使用交换法:
代码:
1 publicstaticvoidShellSort(int[] arr) { 2 inttemp = 0; 3 intcount = 0; 4 //根据元素总长进行分步长 5 for (intgap = arr.length / 2; gap > 0; gap /= 2) { 6 //遍历各组元素中所有的元素 7 for (inti = gap; i < arr.length; i++) { 8 for (intj = i - gap; j >= 0; j -= gap) { 9 //如果前面的元素比后面的元素大就进行换位 10 if (arr[j] > arr[j + gap]) { 11 temp = arr[j]; 12 arr[j] = arr[j + gap]; 13 arr[j + gap] = temp; 14 } 15 } 16 } 17 System.out.println("第" + (++count) + "轮排序:"); 18 System.out.println(Arrays.toString(arr)); 19 } 20 }
交换时使用移位法:
代码:
1 publicstaticvoidShellShot2(int[] arr) { 2 intcount = 0; 3 for (intgap = arr.length / 2; gap > 0; gap /= 2) { 4 //从第gap个元素,逐个对其所在的组进行直接插入排序 5 for (inti = gap; i < arr.length; i++) { 6 intj = i; 7 inttemp = arr[j]; 8 if (arr[j] < arr[j - gap]) { 9 while (j - gap >= 0 && temp < arr[j - gap]) { 10 arr[j] = arr[j - gap]; 11 j -= gap; 12 } 13 //当退出while循环时,就给temp找到插入的位置 14 arr[j] = temp; 15 } 16 } 17 System.out.println("第" + (++count) + "轮排序:"); 18 System.out.println(Arrays.toString(arr)); 19 } 20 }
快速排序
基本思想:快速排序是对冒泡排序的一种改进。通过一趟排序将要排序的数据分割成独立的两部分,
其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行
快速排序,整个排序过程可以递归进行以此达到整个数据变成有序序列。
代码:
1 publicstaticvoidQuickSort(int[] arr, intleft, intright) { 2 intl = left; 3 intr = right; 4 intmid = arr[(right - left) / 2];//中间值 5 inttemp = 0;//记录交换时的值 6 while (l < r) { 7 //当左边的值比中间的值大下标就往右移 8 while (arr[l] < mid) { 9 l += 1; 10 } 11 //当右边的值比中间的值小下标就往左移 12 while (arr[r] > mid) { 13 r -= 1; 14 } 15 //当左边的下标大于或等于时退出循环 16 if (l >= r) { 17 break; 18 } 19 //交换 20 temp = arr[l]; 21 arr[l] = arr[r]; 22 arr[r] = temp; 23 //当交换完后arr[l]==mid时,r-- 24 if (arr[l] == mid) { 25 r -= 1; 26 } 27 //当交换完后arr[r]==mid时,l++ 28 if (arr[r] == mid) { 29 l += 1; 30 } 31 } 32 //如果r==l就必须让r--l++否则会出现栈溢出 33 if (l == r) { 34 l += 1; 35 r -= 1; 36 } 37 //向左递归 38 if (left < r) { 39 QuickSort(arr, left, r); 40 } 41 //向右递归 42 if (right > l) { 43 QuickSort(arr, l, right); 44 } 45 }
归并排序
归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治策略成一些小的问题然后递归求解,
而治的阶段则将分的阶段得到的各答案“修补”在一起,即分而治之。
代码:
1 publicclassMergeSort { 2 publicstaticvoidmain(String[]args){ 3 int[] arr = {8, 4, 5, 7, 1, 3, 6, 2}; 4 int[] temp = newint[arr.length];//归并排序需要额外的空间 5 mergeShot(arr, 0, arr.length - 1, temp); 6 System.out.println("归并排序后=" + Arrays.toString(arr)); 7 } 8 //分+合的方法 9 publicstaticvoidmergeShot( int[] arr, intleft, intright, int[] temp){ 10 if (left < right) { 11 intmid = (left + right) / 2;//中间索引 12 //向左递归 13 mergeShot(arr, left, mid, temp); 14 //向右递归 15 mergeShot(arr, mid + 1, right, temp); 16 //合并 17 merge(arr, left, mid, right, temp); 18 } 19 } 20 21 /** 22 * 23 *@paramarr传入的数组 24 *@paramleft左边的索引值 25 *@parammid中间的索引值 26 *@paramright右边的索引值 27 *@paramtemp临时数组保存已排序的数组 28 */ 29 //将数组合并 30 publicstaticvoidmerge( int[] arr, intleft, intmid, intright, int[] temp){ 31 inti = left; 32 intj = mid + 1; 33 intt = 0;//记录temp的位置 34 35 //将左右两边(有序)按照规则填充到temp中 36 //直到有一边填充完毕 37 while (i <= mid && j <= right) { 38 if (arr[i] <= arr[j]) { 39 //如果左边的值小于右边的值,就将左边的值记录到temp中 40 temp[t] = arr[i]; 41 t += 1; 42 i += 1; 43 } else { 44 //如果右边的值小于左边的值,就将右边的值记录到temp中 45 temp[t] = arr[j]; 46 t += 1; 47 j += 1; 48 } 49 } 50 //将剩余数依次填充到temp中 51 while (i <= mid) { 52 //左边还有剩余的数组,要依次填充到temp中 53 temp[t] = arr[i]; 54 t += 1; 55 i += 1; 56 } 57 while (j <= right) { 58 //右边还有剩余的数组,要依次填充到temp中 59 temp[t] = arr[j]; 60 t += 1; 61 j += 1; 62 } 63 //将temp中的数组拷到arr中 64 //不是每次都拷所有的 65 t = 0; 66 inttempLeft = left; 67 while (tempLeft <= right) { 68 arr[tempLeft] = temp[t]; 69 t += 1; 70 tempLeft += 1; 71 } 72 } 73 }
基数排序
基数排序属于“分配式排序”,又称“桶子法”,它是通过键值得各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用。
基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法。
基数排序是1887年赫尔曼何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字。然后按每个位数分别比较。
基数排序是对传统的桶排序的扩展,速度很快,基数排序是经典的空间换时间的方式,占用内存很大,当对海量数据排序是容易造成OutMemoryError。
代码:
1 importjava.util.Arrays; 2 3 publicclassRadixSort { 4 publicstaticvoidmain(String[]args){ 5 int[] arr = {53, 3, 542, 748, 14, 214}; 6 radixSort(arr); 7 } 8 publicstaticvoidradixSort( int[] arr){ 9 //根据推导可以得出最终的代码 10 //先找出数组中最大数的最大位数 11 intmax = arr[0];//假定第一个数为最大的数 12 for (inti = 0; i < arr.length; i++) { 13 if (arr[i] > max) { 14 max = arr[i]; 15 } 16 } 17 //得到最大数的位数 18 intmaxLength = (max + "").length(); 19 20 //定义一个二维数组,表示10个桶,每个桶就是一个一维数组 21 int[][] bucket = newint[10][arr.length]; 22 23 //定义一个一维数组,记录每次在一维数组中放入的数据个数 24 int[] bucketElementCounts = newint[10]; 25 26 //使用循环将代码整合 27 for (intl = 0, x = 1; l < maxLength; l++, x *= 10) { 28 //每一次循环取出对应的位数 29 for (inti = 0; i < arr.length; i++) { 30 intdigitOfElement = arr[i] / x % 10; 31 32 //将这个数放入对应的桶中 33 bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[i]; 34 bucketElementCounts[digitOfElement]++; 35 } 36 //定义一个index记录原数组当前位置 37 intindex = 0; 38 //按照桶的顺序把每个数按顺序取出到原数组中 39 for (intj = 0; j < bucket.length; j++) { 40 //如果桶中有数据就按顺序取出 41 if (bucketElementCounts[j] != 0) { 42 //循环第j个桶,放入 43 for (intk = 0; k < bucketElementCounts[j]; k++) { 44 arr[index] = bucket[j][k]; 45 index++; 46 } 47 } 48 //在每第一轮过后需要将bucketElementCounts[]置零 49 bucketElementCounts[j] = 0; 50 } 51 System.out.println("第" + (l + 1) + "轮排序的结果" + Arrays.toString(arr)); 52 } 53 } 54 }

浙公网安备 33010602011771号