经典排序算法实现

一、直接插入排序                                                                                                                     点击此处返回总目录

二、希尔排序

三、冒泡排序

四、快速排序

五、选择排序

六、堆排序

七、归并排序

八、基数排序

九、计数排序

十、桶排序

十一、总结

 

 

推荐:https://www.cnblogs.com/guoyaohua/p/8600214.html

 

 

 

一、直接插入排序

【思想】

每次把当前元素插入到前面已经排好序的数组中。

 

 

【代码】

package cn.itcast.demo01;

public class InsertSort {
    public static void main(String[] args) {
        int[] array = {2,4,1,3,4,6,7,5,9,9,8,6,5,4};
        insertSort(array);
        
        for(int i: array){
            System.out.print(i+" ");
        }
    }
        
    public static void insertSort(int[] array){
        if(array.length <=1){ return; }
        
        int current;
        int j;
        for(int i = 1; i<array.length;i++){  
            current = array[i];                            
            for(j = i-1;j>=0 && array[j]>current ;j--){   //从i-1开始往前找第一个小于等于array[i]的元素。判断条件的顺序不能互换。
                    array[j+1]=array[j];
            }
            array[j+1] = current;
        }
    }    
}

【分析】

时间复杂度:o(n^2)

 

 

 

二、希尔排序

                                                0      1     2       3      4      5       6       7      8      9

原始                                         8      2      5       7     9       6       3      4      11    1  

 

第1趟排序,gap=10/2=5                   5       7     9       6       3      4      11    1

第1趟排序后:                          6          4       7     1       8       3      5      11    9

 

第2趟排序,gap=5/2 = 2          6      2      4       7          8           5      11    9

第2趟排序后:                         1      2      3       5     4       7       6      8      11    9

 

第3趟排序,gap=2/2 = 1         1      2      3       5     4       7       6      8      11    9

第3趟排序后:                        1      2      3       4      5      6       7       8      9     11

 

 

 

package cn.itcast.demo04;

public class Test {
    public static void main(String[] args) {
        int[] array = {2,4,1,3,4,6,7,5,9,9,8,6,5,4};
        shellSort(array);
        
        for(int i: array){
            System.out.print(i+" ");
        }
    }
    
    public static void shellSort(int[] array){
        int current,i,j;
        for(int gap = array.length/2; gap >= 1 ; gap /= 2){
            for(i = gap; i<array.length ;i++){
                current = array[i];
                for(j = i-gap ; j>=0 && array[j]>current;j -= gap){   
                    array[j+gap] = array[j];
                }
                array[j+gap] = current;
            }
        }   
    }   
}

跟直接插入排序代码差不多。只不过直接插入排序的gap是1。

 

不稳定排序。时间复杂度o(n^1.5),有的书上写o(n^1.3)

 

 

三、冒泡排序

 

【思想】

原始:           48   62   35   77    55    14    35   98    22    40   

第1趟排序      48   35   62   55    14    35    77   22   40    98    change = true  

第2趟排序      35   48   55   14    35    62    22   40   77    98    change = true  

第3趟排序      35   48   14   35    55    22    40   62   77    98    change = true  

第4趟排序      35   14   35   48    22    40    55   62   77    98    change = true  

第5趟排序      14   35   35   22    40    48    55   62   77    98    change = true  

第6趟排序      14   35   22   35    40    48    55   62   77    98    change = true  

第7趟排序      14   22   35   35    40    48    55   62   77    98    change = true  

第8趟排序      14   22   35   35    40    48    55   62   77    98    change = false    结束。

 

【代码】

package cn.itcast.demo03;

 

public class Test {
    public static void main(String[] args) {
        int[] array = {2,4,1,3,4,6,7,5,9,9,8,6,5,4};
        bubbleSort(array);
        
        for(int i: array){
            System.out.print(i+" ");
        }
    }
    
    public static void bubbleSort(int[] array){
        boolean change = true;
        for(int i = 0;i<array.length-1;i++){   //共array.length-1趟排序
            change = false;
            for(int j=0;j<array.length-i-1;j++){ //第1趟,i=0,j到length-2
                if(array[j]>array[j+1]){
                    int tmp=array[j];array[j]=array[j+1];array[j+1]=tmp;
                    change = true;
                }
            }
            if(change == false){
                return;
            }
        }
           
    }   
}

 

 

 

四、快速排序

 

记住。没啥解释的。不理解就手动画一遍。

 

package cn.itcast.demo05;

public class Test {
    public static void main(String[] args) {
        int[] array = {2,4,1,3,4,6,7,5,9,9,8,6,5,4};
        quickSort(array,0,array.length-1);
        
        for(int i: array){
            System.out.print(i+" ");
        }
    }
    
    public static void quickSort(int[] array, int low , int high){
        if(low < high){
            int pos = partition(array,low ,high);
            quickSort(array,low,pos-1);
            quickSort(array,pos+1,high);
        }
    }
    
    public static int partition(int[] array, int low , int high){
        int pivot = array[low];
        while(low<high){
            while(low < high && array[high] >= pivot){
                high--;
            }
            array[low] = array[high];
            while(low < high && array[low] <= pivot){
                low++;
            }
            array[high] = array[low];
        }
        array[low] = pivot;
        return low;
    }
          
}

 

 

五、选择排序

【思想】

每次选出最小的一个数。

 

待    排:5,6,4,3 
第一趟:3,6,4,5

第二趟:3,4,6,5

第三趟:3,4,5,6

 

 

【代码】

package cn.itcast.demo02;

 

public class Test {
    public static void main(String[] args) {
        int[] array = {2,4,1,3,4,6,7,5,9,9,8,6,5,4};
        selectionSort(array);        
        for(int i: array){
            System.out.print(i+" ");
        }
    }
    
    public static void selectionSort(int[] array){
        for(int i=0;i<array.length-1;i++){    //每次把第i个摆放好。所以只需要摆放好前i-1个,最后一个自然就好了。
            int tmpMin = i;
        
            for(int j=i+1;j<array.length;j++){  //找到从第i个到最后一个中,最下的值的下标
                if(array[j]<array[tmpMin]){
                    tmpMin = j;
                }
            }
            
            if(tmpMin !=i){                    //交换
                int tmp=array[i];array[i]=array[tmpMin];array[tmpMin]=tmp;
            }
        }
        
        
    }   
}

运行结果:

1 2 3 4 4 4 5 5 6 6 7 8 9 9 

 

【分析】

时间复杂度 o(n^2)

 

 

六、堆排序

【思想】

共两步:

1)初始化堆。从一半开始一直到0调整,把左右孩子中的大的那个拿上来。

2)调整堆。每次都是把堆顶元素与最后一个元素交换,然后调整堆顶元素。

 

 

【代码】

注意:代码中数组下标从0开始的。

package cn.itcast.demo09;

public class Test {
    public static void main(String[] args) {
        int[] arr = {48,62,35,77,55,14,35,98};
        heapSort(arr);
        for(int i:arr){
            System.out.print(i+" ");
        }
    }
    
    public static void heapSort(int[] arr){
        int len = arr.length;
        buildMaxHeap(arr,len);                           //第一步,初始化堆。
        
        while(len!=1){                                         //第二步,堆顶与最后一个元素交换,然后调整堆。
            int tmp = arr[0];
            arr[0] = arr[len-1];
            arr[len-1] = tmp;
            len--;
            adjustDownHeap(arr,0,len);
        }
        
    }
    
    public static void buildMaxHeap(int[] arr,int len){         //初始化堆的时候,从中间元素到0,依次调整堆。
        for(int i = (len-1)/2;i>=0;i--){
            adjustDownHeap(arr,i,len);
        }
    }
    
    public static void adjustDownHeap(int[] arr, int k, int len){   //调整堆。调整arr[k]
        int num = arr[k];                                               //首先记下来。
        for(int i = k*2+1;i<len;i=2*i+1){
            if(i+1<len && arr[i]<arr[i+1]){                      //如果右孩子比做孩子大,i就是右孩子;否则i不变,还是左孩子。
                i = i+1;
            }
            if(arr[i]<=num){                             //num比较大的孩子还大,就不用再交换了。
                break;
            }
            arr[k] = arr[i];                                //交换。
            k = i;
        }
        arr[k] = num;
    }

}

结果:

时间复杂度o(nlgn)

 

 

七、归并排序

 

 

 

 

 

 

八、基数排序

 

 

 

 

九、计数排序

  3 5 4 4 6 8 10 8  共8个元素。最小值为3,最大值为10。需要建立的桶长度为8。分别存储3的个数,4的个数,5的个数,...,10的个数。

最后遍历一遍桶。3的个数有几个就输出几次,4的个数有几个就输出几次,...,10的个数有几个就输出几次。最后得到排序结果。

 

即:

1. 扫描一下整个数组array,获取最小值 min 和最大值 max。比如3~10共8种元素。

2. 创建新的桶(就是一个数组),长度为  max - min + 1

3. 桶中 index 的元素记录的值是 A 中某元素出现的次数。即:第一个桶存放元素min的个数,第二个桶存放min+1的个数...

4. 最后输出目标整数序列,具体的逻辑是遍历数组 B,输出相应元素以及对应的个数

 

代码:

package cn.itcast.demo01;

public class Test {
    public static void main(String[] args) {
        int[] array = {2,4,1,3,4,6,7,5,9,9,8,6,5,4};
        countingSort(array);
        for(int i=0;i<array.length;i++){
            System.out.print(array[i]+" ");
        }
    }
    
    public static void countingSort(int[] array){
        int n=array.length;
        if(n<=1) return;
        
        int min=array[0],max=array[0];
        for(int i=1;i<n;i++){                 //统计一下最大值和最小值
            if(array[i]<min){
                min = array[i];
            }
            if(array[i]>max){
                max = array[i];
            }
        }
        
        int[] bucket = new int[max-min+1];   //根据最大值最小值创建桶
        for(int i=0;i<bucket.length;i++){    //桶元素置空
            bucket[i]=0;
        }
        for(int i=0;i<n;i++){                //根据数组元素对对应桶进行计数
            bucket[array[i]-min]++;
        }
 
        int j=0;
        for(int i=0;i<bucket.length;i++){     //输出
            while(bucket[i]!=0){
                array[j++] = i+min;
                bucket[i]--;
            }
        }
    }   
}

 

 

 

 

十、桶排序

 

 

 

 

十一、总结

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值