三数中值法快速排序的Java实现

排序算法也是算法的一个重头戏,里面涉及的算法按时间复杂度可以分为两大类:

时间复杂度为O(n^2): 冒泡排序、选择排序、插入排序
时间复杂度为O(nlogn): 快速排序、归并排序

本文将重点介绍快速排序及其实现。

时间复杂度:

快速排序是目前已有的排序算法中最快的算法,它的平均时间复杂度为O(nlogn),最坏时间复杂度为O(n^2)。

核心思路:分治思想

将原问题划分成若干子问题解决:数组A中选一个基准点pivot,数组中其他的元素与pivot逐个比较,每遇到一个大于pivot的元素和一个小于pivot的元素,两者交换位置,大的右移,小的左移,直至所有元素不再进行上述步骤。

pivot的选择:

常见的有以下三种方案:
首/尾法:如果数组是排好序的,那么选首/尾元素为pivot,可能会把所有元素移到另外一边,带来最坏时间复杂度为O(n^2)。
随机选择法:最坏时间复杂度为O(n^2)产生的概率小于头/尾法。
三数中值法:求数组的第一个元素、中间位置元素、最后一个元素的中值,将中值与最后一个元素交换即可,这样做的好处是降低了最坏时间复杂度产生的概率。
下面我们一起来看一下具体的实现:
part 1

思路分析:
pivot.png
代码:
//   三数中值法是为了防止最坏情况的出现,找到三数中值,并与right-1 交换,能减少一次交换次数,因为right 确定> 中值;
    public int midValue(int a[], int left, int right){
//        先确定数组里的数>=3个,这样才能选三个数里的中值:
        if(right-left+1>=3){
            int center =(left+right)/2;
            if(a[left]> a[center]){
                swap(a,left,center);
            }
            if(a[center]> a[right]){
                swap(a,center,right);
        }
//            这一步是防止原先的顺序为:321,相当于比较了原来的left、right;
            if(a[left]>a[center]){
                swap(a,left,center);
            }
            swap(a,center,right-1);
            return a[right-1];
        }else{
            if(a[left]>a[right]){
                swap(a,left,right);
            }
            return 0;
        }
    }

part 2

思路分析:
QuickSort.png
代码:
public int[] quickSortNew(int[] a, int left ,int right){

        int pivot = midValue(a,left,right);
//        首先分析数组的数目大于3时
        if(right-left+1>3){
            int i= left;
            int j= right -1;
            while (i<j){
//                如果满足括号里的条件,会一直继续下去 ,目的:a[i]>pivot 时才停下,所以条件取反时一直往右移:
                while (i<j && a[i]<= pivot){i+=1;}
//                同上,找到a[j]<pivot
                while (i<j && a[j]>= pivot){j-=1;}
//                以上循环停下的时候 ,如果正好i<j,交换a[i] a[j]的位置
                if(i<j){
                    swap(a, i, j);
                }else {
                    break;
                }
            }
            swap(a,i,right-1);
            quickSortNew(a,left,i-1);
            quickSortNew(a, i+1, right);
        }
        return a;
}

小结:
排序算法的很多都用了分治思想,把一个大问题划分成若干子问题来解决,在我们自己学习的时候,也可以把思考的过程划分成若干子过程来仔细研究,就像我刚刚只是思路分析了例子中排序的第一步,如果你感兴趣,且想把快速排序这个问题啃下,建议小伙伴们可以自己分析演练出后序过程,这样可以更好地帮助你理解这个问题。

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