排序

八大排序算法

一、归并排序

递归及非递归的JAVA实现

public static void MergeSort(int[] arr, int low, int high)
{
    //使用递归的方式进行归并排序,所需要的空间复杂度是O(N+logN)
    int mid = (low + high)/2;
    if(low < high)
    {
        //递归地对左右两边进行排序
        MergeSort(arr, low, mid);
        MergeSort(arr, mid+1, high);
        //合并
        merge(arr, low, mid, high);
    }
}

//merge函数实际上是将两个有序数组合并成一个有序数组
//因为数组有序,合并很简单,只要维护几个指针就可以了
private static void merge(int[] arr, int low, int mid, int high)
{
    //temp数组用于暂存合并的结果
    int[] temp = new int[high - low + 1];
    //左半边的指针
    int i = low;
    //右半边的指针
    int j = mid+1;
    //合并后数组的指针
    int k = 0;
    
    //将记录由小到大地放进temp数组
    for(; i <= mid && j <= high; k++)
    {
        if(arr[i] < arr[j])
            temp[k] = arr[i++];
        else
            temp[k] = arr[j++];
    }
    
    //接下来两个while循环是为了将剩余的(比另一边多出来的个数)放到temp数组中
    while(i <= mid)
        temp[k++] = arr[i++];
    
    while(j <= high)
        temp[k++] = arr[j++];
    
    //将temp数组中的元素写入到待排数组中
    for(int l = 0; l < temp.length; l++)
        arr[low + l] = temp[l];
}

二、快速排序

快排算法JAVA实现

/**
 * 快速排序
 * 基本思想:
 * 1.在待排序的元素任取一个元素作为基准(通常选第一个元素,但最佳选择方法是从待排序元素中随机选取一个作为基准),称为基准元素;
 * 2.将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边;
 * 3.对左右两个分区重复以上步骤直到所有元素都是有序的。
 */
public void quick_sort(int[] arr,int _left,int _right){
    int left=_left;
    int right=_right;
    int temp=0;
    //待排序元素至少有1个
    if(left<=right){
       temp=arr[left]; //待排序的第一个元素作为基准元素
        while(left!=right){ //从左右两边交替扫描,直到left = right

            while(right>left && arr[right]>=temp)
                right--;  //从右往左扫描,找到第一个比基准元素小的元素
            arr[left]=arr[right]; //找到这种元素arr[right]后与arr[left]交换

            while(left<right && arr[left]<=temp)
                left++;   //从左往右扫描,找到第一个比基准元素大的元素
            arr[right]=arr[left]; //找到这种元素arr[left]后,与arr[right]交换
        }
        arr[right]=temp; // 基准元素归位
        quick_sort(arr,_left,left-1); //对基准元素左边的元素进行递归排序
        quick_sort(arr,right+1,_right); //对基准元素右边的进行递归排序
    }
}

三、堆排序

堆排序
堆排序算法JAVA实现

/**
 * 堆排序
 * 基本思想:
 * 首先,堆分为最大堆和最小堆,最大堆则是指在一棵树中,父结点总是比子结点大,堆顶是整棵树中的最大值,
 * 同样的最小堆则是父结点都比子结点要小,堆顶则是最小值。
 *
 * 排序的过程则是将数组根据要排列的顺序去决定是排最大堆还是最小堆,建完堆以后将堆顶的值取出后,
 * 重新将堆进行调整,调整后的值同样满足堆的性质,接着再取出,以此类推。
 */
/**
 * (最大)堆的向下调整算法
 * 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 * 其中,N为数组下标索引值,如数组中第1个数对应的N为0。
 * @param arr
 * @param start
 * @param end
 */
public void maxHeapDown(int[] arr,int start,int end){
    int current=start; //当前节点位置,即父亲节点
    int left=2*current+1; //左孩子的位置
    while(left<=end){ //子节点在范围内才进行调整
        //选择子节点中大的值
        if(left+1<=end && arr[left]<arr[left+1])
            left++;
        if(arr[current]>arr[left])
            break; //调整结束
        else{  //否则继续和孙节点进行比较
            swap(arr,current,left);
            current=left;
            left=2*current+1;
        }
    }
}

public void heap_sort(int[] arr,int len){
    //初始化,从i最后一个父亲节点开始调整
    for(int i=len/2-1;i>=0;i--)
        maxHeapDown(arr,i,len-1);
    //先将第一个元素和后面的元素进行交换,再调整
    for(int i=len-1;i>0;i--){
        swap(arr,0,i);
        maxHeapDown(arr,0,i-1);
    }
}

四、冒泡排序

冒泡排序算法JAVA实现

  /**
 * 冒泡排序
 * 基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,
 *         让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
 * @param arr
 * @param len
 */
public void bubble_sort(int[] arr,int len){
    //躺数
    for(int i=0;i<len-1;i++){
        for(int j=0;j<len-1-i;j++){
            if(arr[j]>arr[j+1]){
                swap(arr,j,j+1);
            }
        }
    }
}

五、直接插入排序

直接插入排序算法JAVA实现

/**
 * 直接插入排序
 * 基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。
 * 设数组为arr[0…n-1]。
 * 1.初始时,arr[0]自成1个有序区,无序区为arr[1..n-1]。令i=1
 * 2.将arr[i]并入当前的有序区arr[0…i-1]中形成arr[0…i]的有序区间。
 * 3.i++并重复第二步直到i==n-1。排序完成。
 * @param arr
 * @param len
 */
public void insert_sort(int[] arr,int len){
    int i,j;
    for(i=1;i<len;i++){
        //如果arr[i]>arr[i-1],无需调整
       if(arr[i]<arr[i-1]){
           int temp=arr[i];
           //为arr[i]找位置,找到第一个比arr[i]小的元素,然后把arr[i]放在其后即可
           for(j=i-1;j>=0&&arr[j]>temp;j--){
               arr[j+1]=arr[j]; //移动
           }
           arr[j+1]=temp;
       }
   }
}

六、简单选择排序

  /**
 * 简单选择排序
 * 基本思想:
 * 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,
 * 然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
 * @param arr
 * @param len
 */
public void select_sort(int[] arr,int len){
    for(int i=0;i<len-1;i++){
        int min=i;
        for(int j=i+1;j<len;j++){
            if(arr[j]<arr[min])
                min=j;
        }
        swap(arr,i,min);
    }
}

七、排序算法比较

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的...
    Luc_阅读 2,255评论 0 35
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,164评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,727评论 0 15
  • 排序的基本概念 在计算机程序开发过程中,经常需要一组数据元素(或记录)按某个关键字进行排序,排序完成的序列可用于快...
    Jack921阅读 1,416评论 1 4
  • 1 初级排序算法 排序算法关注的主要是重新排列数组元素,其中每个元素都有一个主键。排序算法是将所有元素主键按某种方...
    深度沉迷学习阅读 1,391评论 0 1