9.八大排序

一、冒泡排序
 1 package com.duan.array;
 2 
 3 import java.util.Arrays;
 4 //两两比较,大的往后边放,经过一轮比较,最大的元素就会出现在最后面。
 5 public class BubbleSort {
 6     public static void main(String[] args) {
 7         int [] arr={24,69,80,57,13};
 8         //i代表比较轮次
 9         for (int i = 0; i < arr.length - 1; i++) {
10             for (int j = 0; j < arr.length - 1-i; j++) {
11                 //arr[j]代表要比较的元素,arr[j+1]代表它后边的元素
12                 if(arr[j]>arr[j+1]){
13                     int t=arr[j];
14                     arr[j]=arr[j+1];
15                     arr[j+1]=t;
16                 }
17             }
18         }
19         System.out.println(Arrays.toString(arr));
20     }
21 }
二、选择排序:
 1 package com.duan.array;
 2 
 3 import java.util.Arrays;
 4 //每一次拿一个元素,跟后面的元素挨个比较,小的往前换,经过一轮后,最小的就会换在最前面
 5 public class SelectSort {
 6     public static void main(String[] args) {
 7         int [] arr={24,69,80,57,13};
 8         for (int index = 0; index < arr.length - 1; index++) {//index代表比较轮次和要比较元素的索引
 9             for (int j = 1+index; j < arr.length; j++) {
10                 //j=1+index 下一个元素的索引,不用和自己比。
11                 //arr[index]代表要比较的元素,arr[j]表示下一个元素
12                 if(arr[index]>arr[j]) {
13                     int t = arr[index];
14                     arr[index] = arr[j];
15                     arr[j] = t;
16                 }
17             }
18         }
19         System.out.println(Arrays.toString(arr));
20     }
21 }
三、直接插入:
 1 package com.duan.array;
 2 
 3 import java.util.Arrays;
 4 //将后面的元素,插入之前的有序列表,使其仍然保持有序。
 5 public class StraightInsertionSort {
 6     public static void main(String[] args) {
 7         int []arr={1,2,0,3,4,6,10,-1};
 8         Sort1(arr);
 9         System.out.println(Arrays.toString(arr));
10         sort2(arr);
11         System.out.println(Arrays.toString(arr));
12     }
13 
14     private static void sort2(int[] arr) {
15         //外层控制循环次数
16         for (int i = 0; i < arr.length; i++) {
17             //里边比前一项小就换,直到有序为止。
18             for (int j = i; j >0; j--) {
19                 if(arr[j]<arr[j-1]){
20                     int t=arr[j];
21                     arr[j]=arr[j-1];
22                     arr[j-1]=t;
23                 }
24             }
25         }
26     }
27 
28     private static void Sort1(int[] arr) {
29         for (int i = 1; i < arr.length;i++) {
30             int j=i;
31             while (j>0&&arr[j]<arr[j-1]){
32                 int t=arr[j];
33                 arr[j]=arr[j-1];
34                 arr[j-1]=t;
35                 j--;
36             }
37         }
38     }
39 }
四、希尔排序:

 

 

 1 package com.duan.array;
 2 
 3 import java.util.Arrays;
 4 //选择一个合适的增量,经过一轮插入排序后,让数组大致有序,然后缩小增量进行插入排序,直到增量为1结束排序。
 5 public class ShellSort {
 6     public static void main(String[] args) {
 7         int[] arr={46,55,13,42,17,94,5,70};
 8         //kunth克努特序列选增量
 9         int zengliang =1;
10         while (zengliang<arr.length/3){
11             zengliang=3*zengliang+1;
12         }
13         //增量为一半h=arr.lenth/2;
14         for (int h = zengliang; h >0; h=(h-1)/3) {
15             for (int i =h; i < arr.length;i++) {
16                 //j>增量-1;j=j-zengliang;
17                 for (int j = i; j >h-1; j-=h) {
18                     if(arr[j]<arr[j-h]) {
19                         int t = arr[j];
20                         arr[j] = arr[j-h];
21                         arr[j-h] = t;
22                     }
23                 }
24             }
25         }
26         System.out.println(Arrays.toString(arr));
27     }
28 }
五、快速排序:

 

 

 1 package com.duan.array;
 2 
 3 import java.util.Arrays;
 4 //比大小再分区。从数组中取出一个数,作为基准数,将大的数放右边,小的放左边。
 5 //再对左右分区重复第二步,直到各分区只有一个数为止。
 6 //挖坑填数。
 7 //1.挖出一个基准数,形成第一个坑。
 8 //2.从后往前挖比它小的数填到上一个坑中(挖基准数的坑)
 9 //3.从前往后挖一个大于或等于它的数填到上一个坑中
10 //4.重复2.3步。
11 public class QuickSort {
12     public static void main(String[] args) {
13         int[]arr={2,3,5,8,4,1,7,6,9,10};
14         chaifen(arr,0,arr.length-1);
15         System.out.println(Arrays.toString(arr));
16     }
17 
18     private static void chaifen(int[] arr, int start, int end) {
19         if(start<end){
20             int index=getIndex(arr,start,end);
21             //左右拆分
22             chaifen(arr,start,index-1);
23             chaifen(arr,index+1,end);
24         }
25     }
26 
27     /**
28      * @param arr   传进来的数组
29      * @param start 开始索引
30      * @param end   结束索引
31      * @return      返回基准数的索引
32      */
33     private static int getIndex(int[] arr, int start, int end) {
34         //定义起始结束索引
35         int i=start;
36         int j=end;
37         //定义基准数
38         int x=arr[i];
39         //循环
40         while (i<j){
41             //从后往前找比基准数小的数
42             while(i<j&&arr[j]>=x){
43                 j--;
44             }
45             //填数到上一个坑中
46             if(i<j){
47                 arr[i]=arr[j];
48                 i++;
49             }
50             //从前往后找大于等于基准数的数
51             while(i<j&&arr[i]<x){
52                 i++;
53             }
54             //填数到上一个坑中
55             if(i<j){
56                 arr[j]=arr[i];
57                 j--;
58             }
59         }
60         //循环结束,把基准数填进最后一个坑(i=j)中,也就以基准数为界限分成左右两部分
61         arr[i]=x;//填进去
62         return i;//返回基准数所在位置的索引
63     }
64 }
六、归并排序:

 

 

 1 package com.duan.array;
 2 
 3 import java.util.Arrays;
 4 //分而治之。假设初始序列有N个记录,则可以看成N个有序的子序列,每个子序列的长度为1,然后两两合并得到一个N/2
 5 //个长度为2或1的有序子序列,再两两归并...如此重复直到得到一个长度为N的有序序列为止。
 6 public class MergeSort {
 7     public static void main(String[] args) {
 8         int[]arr={2,3,5,8,4,1,7,6,9,10};
 9         chaifen(arr,0,arr.length-1);
10         System.out.println(Arrays.toString(arr));
11     }
12 
13     private static void chaifen(int[] arr, int startIndex, int endIndex) {
14         int centerIndex=(startIndex+endIndex)/2;
15         if(startIndex<endIndex){
16         //左边递归拆
17         chaifen(arr,startIndex,centerIndex);
18         //右边递归拆
19         chaifen(arr,centerIndex+1,endIndex);
20         //合并
21         hebing(arr,startIndex,centerIndex,endIndex);
22         }
23     }
24 
25     private static void hebing(int[] arr, int startIndex, int centerIndex, int endIndex) {
26         //定义一个临时数组
27         int[] tempArray=new int [endIndex-startIndex+1];
28         //定义临时数组起始索引
29         int index=0;
30         //定义第一个数组起始索引
31         int i=startIndex;
32         //定义第二个数组起始索引
33         int j=centerIndex+1;
34         //遍历数组开始归并
35         while(i<=centerIndex&&j<=endIndex){
36          if(arr[i]<=arr[j]){
37              tempArray[index]=arr[i];
38              i++;//增加索引
39          }else{
40              tempArray[index]=arr[j];
41              j++;//增加索引
42          }
43            index++;//临时数组增加索引
44         }
45         //处理左边剩余元素
46         while (i<=centerIndex){
47             tempArray[index]=arr[i];
48             i++;
49             index++;
50         }
51         //处理右边剩余元素
52         while (j<=endIndex){
53             tempArray[index]=arr[j];
54             j++;
55             index++;
56         }
57         //遍历临时数组赋值到原始数组
58         for (int m = 0; m < tempArray.length; m++) {
59             arr[m+startIndex]=tempArray[m];
60         }
61     }
62 }
七、基数排序LSD:

 

 

 1 package com.duan.array;
 2 
 3 import java.util.Arrays;
 4 
 5 //分配再收集。按个位-十位-百位-... 位数从低位开始排序。LSD法。
 6 public class RadixSort {
 7     public static void main(String[] args) {
 8         int []arr={0,2,11,30,49,50,100,123,187,543 };
 9         Sort(arr);
10         System.out.println(Arrays.toString(arr));
11     }
12 
13     private static void Sort(int[] arr) {
14         //定义一个二维数组
15         int[][]tempArr=new int [10][arr.length];//里面一维数组的长度和待排数组的长度一样
16         //定义一个统计的一维数组,用来统计二维数组中放的数字个数
17         int[]count=new int [10];//长度和二维数组保持一致
18         //获取数组中的最大数
19         int max=getMax(arr);
20         //计算数组中最大的数有几位,这也是我们需要比较的轮次
21         int lunci = String.valueOf(max).length();
22         for (int i = 0, n = 1; i < lunci; i++, n *= 10) {
23             for (int j = 0; j < arr.length; j++) {
24                 //获取每个位上的数字
25                 int shu = arr[j] / n % 10;
26                 //我们找一个二维数组,数组中放10个桶,这个桶就是一维数组
27                 // count[shu]++ 意思是,二维数组的桶中放一个数字,那么统计数组对于的位置就统计一下
28                 tempArr[shu][count[shu]++] = arr[j];
29             }
30             //我们遍历统计数组,取出二维数组中的元素,放回原数组
31             int index = 0;
32             for (int k = 0; k < count.length; k++) {
33                 if (count[k] != 0) {
34                     for (int h = 0; h < count[k]; h++) {
35                         arr[index] = tempArr[k][h];
36                         index++;
37                     }
38                     //一轮过后统计的个数
39                     count[k] = 0;
40                 }
41             }
42         }
43 
44 
45     }
46 
47     private static int getMax(int[] arr) {
48         int max=arr[0];
49         for (int i = 1; i < arr.length; i++) {
50            if(arr[i]>max){
51                max=arr[i];
52            }
53         }
54         return max;
55     }
56 }
八、堆排序:
思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
 1 package com.duan.array;
 2 
 3 import java.util.Arrays;
 4 
 5 public class HeapSort {
 6     public static void main(String[] args) {
 7         int[] nums = {16,7,3,20,17,8};
 8         headSort(nums);
 9         for (int num : nums) {
10             System.out.print(num + " ");
11         }
12     }
13 
14     /**
15      * 堆排序
16      */
17     public static void headSort(int[] list) {
18         //构造初始堆,从第一个非叶子节点开始调整,左右孩子节点中较大的交换到父节点中
19         for (int i = (list.length) / 2 - 1; i >= 0; i--) {
20             headAdjust(list, list.length, i);
21         }
22         //排序,将最大的节点放在堆尾,然后从根节点重新调整
23         for (int i = list.length - 1; i >= 1; i--) {
24             int temp = list[0];
25             list[0] = list[i];
26             list[i] = temp;
27             headAdjust(list, i, 0);
28         }
29     }
30     
31     private static void headAdjust(int[] list, int len, int i) {
32         int k = i, temp = list[i], index = 2 * k + 1;
33         while (index < len) {
34             if (index + 1 < len) {
35                 if (list[index] < list[index + 1]) {
36                     index = index + 1;
37                 }
38             }
39             if (list[index] > temp) {
40                 list[k] = list[index];
41                 k = index;
42                 index = 2 * k + 1;
43             } else {
44                 break;
45             }
46         }
47         list[k] = temp;
48     }
49 }

 

 

posted @ 2020-01-21 17:09  断浮  阅读(159)  评论(0编辑  收藏  举报