排序

冒泡排序

 

 

代码:

 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     }

 

posted @ 2021-11-30 23:18  一根大腿毛  阅读(54)  评论(0)    收藏  举报