八大排序算法

插入排序:

  • 直接插入排序

基本原理:对于给定的一组记录,初始时假设第一个记录自成一个有序序列,其余记录为无序序列,接着从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直至最后一个记录插入到有序序列中为止。

public class InsertSort {
    
    public static int[] sort(int[] n){
        
        if(n.length<=0){
            return null;
        }
        //从第二个元素开始进行对比判断
        for(int i=1;i<n.length;i++){
            int temp=n[i];
            int j=i;
            if(n[j-1]>temp){//当n[j-1]>temp时,才进入循环进行判断
            while(j>=1&&n[j-1]>temp){
                    n[j]=n[j-1];
                    j--;
                }
            }
            n[j]=temp;
            }
        
        return n;
    }
}
  • 希尔排序(从小到大)

基本原理:先将待排序的数组元素分成多个子序列,使得每个子序列的元素个数相对较少,然后对各个子序列分别进行直接插入排序,待整个待排序序列“基本有序后”,最后再对所有元素进行一次直接插入排序。

public class ShellSort {

    public static void sort(int[]n){
        int len=n.length;
        int d=len/2;//初始步长
        int j=0;
        while(d>0){
            for(int i=d;i<n.length;i++){
               //从索引值为d的数组元素开始,依次与子序列中前面的元素进行对比
                int temp=n[i];
                for(j=i;j>=d;j-=d){//对比的索引减量为d
                    if(n[j-d]>temp){
                        n[j]=n[j-d];
                    }else{
                        break;
                    }
                }
                n[j]=temp;
            }
            d=d/2;
        }
    }
}

选择排序:

  • 选择排序

基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换;接着对不包括第一个记录以外的其他记录进行第二轮比较,得到最小的记录并与第二个记录进行位置交换;重复该过程,直到进行比较的记录只有一个时为止。

public class SelectSort {

    public static int[] sort(int[] n){
        int temp=0;
        for(int i=0;i<n.length-1;i++){
            int flag=i;
            temp=n[i];
            for(int j=i+1;j<n.length;j++){
                if(temp>n[j]){
                    temp=n[j];
                    flag=j;
                }
            }
            if(flag!=i){
            n[flag]=n[i];
            n[i]=temp;
            }
        }
        return n;
    }
}
  • 堆排序

基本思想:对于给定的n个记录,初始时把这些记录看作一棵顺序存储的二叉树,然后将其调整为一个大顶堆,然后将堆的最后一个元素与堆顶元素(即二叉树的根节点)进行交换后,堆的最后一个元素即为最大记录;接着将前(n-1)个元素(即不包括最大记录)重新调整为一个大顶堆,再将堆顶元素与当前堆的最后一个元素进行交换后得到次大的记录,重复该过程直到调整的堆中只剩一个元素时为止,该元素即为最小记录,此时可得到一个有序序列。

public class HeapSort {
    //排序
    public static void sort(int[]n){
        for(int i=0;i<n.length-1;i++){
            buildMaxHeap(n, n.length-1-i);//循环建堆
            exchange(n, 0, n.length-1-i);//交换堆顶与堆中最后一个元素
            System.out.println(Arrays.toString(n));
        }
    }

    //建立大顶堆
    public static void buildMaxHeap(int[]n,int lastindex){
        //从最后一个结点的父节点开始构建
        for(int i=(lastindex-1)/2;i>=0;i--){
            while(2*i+1<=lastindex){//判断i结点是否有子结点
                int k=2*i+1;//i结点的左子树
                int max=k;//标记最大子树的索引值
                int temp=n[k];//标记最大子树的值
             if(k<lastindex){//判断i结点是否有右子树
                 if(n[k]<n[k+1]){
                     temp=n[k+1];
                     max=k+1;
                 }
             }
             if(n[max]>n[i]){//子结点的值大于父结点
                 exchange(n,i,max);
                 k=max;
             }else{
                 break;
             }
            }
        }
        
    }
    //交换数组中的两个元素
    public static void exchange(int[]n,int i,int j ){
        int temp=0;
        temp=n[i];
        n[i]=n[j];
        n[j]=temp;
    }
}

交换排序:

  • 冒泡排序

基本思想:(由小到大)对于给定的n个记录,从第一个记录开始依次对相邻的两个记录进行比较,当前面的记录大于后面的记录时,交换位置,进行一轮比较和换位后,n个记录中的最大记录将位于第n位;然后对前(n-1)个记录进行第二轮比较;重复该过程直到进行比较的记录只剩下一个为止。

public class BubbleSort {

    public static int[] sort(int[] n){
        if(n.length<=0){
            return null;
        }
        int temp=0;
        for(int i=0;i<n.length-1;i++){//比较的趟数
            for(int j=0;j<n.length-i-1;j++){//每趟比较的次数
                //按从小到大的顺序排序
                if(n[j]>n[j+1]){
                    temp=n[j];
                    n[j]=n[j+1];
                    n[j+1]=temp;
                }
            }
        }
        return n;
    }
}
  • 快速排序

基本思想:对于一组给定的记录,通过一趟排序后,将原序列分为两部分,其中前一部分的所有记录均比后一部分的所有记录小,然后再依次对前后两部分的记录进行快速排序,递归该过程,直到序列中的所有记录均有序为止。

public class QuickSort {

   public static void sort(int[]n,int start,int end){
       int flag=0;//对数组进行分解的基准值的索引
       if(start<end){
           flag=partition(n,start,end);
           sort(n,start,flag-1);//递归对基准值左边的子数组进行排序
           sort(n,flag+1,end);//递归对基准值右边的子数组进行排序
       }
   }
   
   public static int partition(int[]n,int start,int end){
       int temp=n[start];//将数组最左边的值设置为基准值
       while(start<end){
           while(start<end&&temp<n[end]){//从右往左找到第一个比基准值小的值
               end--;
           }
           if(start<end){
               n[start]=n[end];//将第一个比基准值小的值赋值给start位置索引
               start++;//start指针前移一个位置
           }
           while(start<end&&temp>n[start]){//从左往右找到第一个比基准值大的值
               start++;
           }
           if(start<end){
               n[end]=n[start];//将第一个比基准值大的值赋值给end位置索引
               end--;//end指针后移一个位置
           }
       }
       //此时start=end
       n[end]=temp;
       return end;
   }
}
  • 归并排序

基本思想:对于给定的一组记录(假设共有n个记录),首先将每两个相邻的长度为1的子序列进行归并,得到n/2(向上取整)个长度为2或1的有序子序列,再将其两两归并,反复执行此过程,直到得到一个有序序列。

public class MergeSort {

    public static void sort(int[] n,int left,int right){
        if(left<right){
        int mid=(left+right)/2;//计算数组中间元素索引位置
        sort(n, left, mid);//对左半部分进行递归排序
        sort(n, mid+1, right);//对右半部分进行递归排序
        merge(n, left, mid, right);//合并
        }
    }
    public static void merge(int[]n,int start,int mid,int end){
        int[] temp=new int[n.length];//定义一个临时数组用于存放排好序的数组元素
        int p=start;
        int k=start;
        int left=start;//左指针
        int right=mid+1;//右指针
        while(left<=mid&&right<=end){
            if(n[left]>n[right]){
                temp[p++]=n[left++];
            }else{
                temp[p++]=n[right++];
            }
        }
        //将剩余元素填充到temp数组中
        while(left<=mid){
            temp[p++]=n[left++];
        }
        while(right<=end){
            temp[p++]=n[right++];
        }
        //将temp数组中的元素复制到数组n中
        while(k<=end){
            n[k]=temp[k];
            k++;
        }
        
    }
}
  • 基数排序

基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位比较短的数前面补零。然后,从最低位开始,依次进行依次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。


public class RadixSort {

   public static void sort(int[]n){
       //获取数组中最大的数
       int temp=0;
       for(int i=0;i<n.length;i++){
           if(n[i]>temp){
               temp=n[i];
           }
       }
       //得到需要比较的次数
       int count=0;
       while(temp>0){
           temp=temp/10;
           count++;
       }
       //创建十个数组
       List<ArrayList<Integer>> queue=new ArrayList<ArrayList<Integer>>();
       for(int i=0;i<10;i++){
           ArrayList<Integer> list=new ArrayList<Integer>();
           queue.add(list);
       }
       //每一数组中元素的排序
       for(int i=0;i<count;i++){
           for(int j=0;j<n.length;j++){
               //获取数值中的各位数字
               int x=n[j]%(int)Math.pow(10, i+1)/(int)Math.pow(10, i);
               ArrayList<Integer> list1=queue.get(x);//获取queue中索引值为x的集合
               list1.add(n[j]);//将原数组中的数值添加到集合中
           }
           //按照数组中值的各位大小进行排序
           int num=0;//元素计数器
           for(int k=0;k<10;k++){
               while(queue.get(k).size()>0){//遍历数组中各个集合中的元素值
                   ArrayList<Integer>list2=queue.get(k);//获取索引值k所对应的集合
                   n[num]=list2.get(0);//依次移除集合中的各个元素
                   list2.remove(0);
                   num++;
               }
           }
       }
   }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,812评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,626评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,144评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,052评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,925评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,035评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,461评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,150评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,413评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,501评论 2 307
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,277评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,159评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,528评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,868评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,143评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,407评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,615评论 2 335

推荐阅读更多精彩内容

  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,149评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,723评论 0 15
  • 前言 八大排序,三大查找是《数据结构》当中非常基础的知识点,在这里为了复习顺带总结了一下常见的八种排序算法。常见的...
    LeeLom阅读 96,904评论 41 662
  • 常见的八大排序算法,他们之间关系如下: *排序算法.png 比较 稳定性是指如果存在多个具有相同排序码的记录,经过...
    捂不暖的石头阅读 458评论 2 4
  • 本文用Python实现了插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。 1、插...
    撸大师阅读 386评论 0 3