成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

Java數(shù)據(jù)結構常見排序算法(總結分享)

本篇文章給大家?guī)砹岁P于java的相關知識,其中主要介紹了一些常見的排序算法,包括了直接插入排序、希爾排序(縮小增量排序)、選擇排序以及堆排序等內容,下面一起來看一下,希望對大家有幫助。

Java數(shù)據(jù)結構常見排序算法(總結分享)

1、 認識排序

在學校中,如果我們要參加運動會,或者軍訓的時候,會按照身高從矮到高進行站隊,比如上課老師手上拿的考勤表,通常是按照學號從低到高進行排序的。再比如編程語言排行榜,也是在排序。

Java數(shù)據(jù)結構常見排序算法(總結分享)

生活中有相當多的排序場景,由此可知,排序還是很重要的, 本章就會介紹常見的一些排序算法。

所謂排序呢,就拿我們上面的舉例來說,會按照某個或某些關鍵字的大小,遞增或者遞減排列起來的操作,這就是排序,這里面也涉及到排序的穩(wěn)定性,舉個例子:

比如有這樣的一組數(shù)據(jù):B D A C A F,要按照他們的 ascll 碼來排序,這里出現(xiàn)了兩個 A,我們把第一個出現(xiàn)的 A 稱為 A1,第二個出現(xiàn)的 A 稱為 A2。

假定排序后結果為:A1 A2 B C D F,那么這個排序算法就是穩(wěn)定的。

假設排序后結果為:A2 A1 B C D F,那么這個排序算法就是不穩(wěn)定的。

簡而言之,如果待排序的數(shù)據(jù)中,有兩個相同的元素,排序結束后,這兩個元素的關系沒有發(fā)生改變,比如 A1 排序前在 A2 前面,排完序后,A1 還在 A2 前面,這就是穩(wěn)定的排序算法。

注意:一個不穩(wěn)定的排序算法,天生就是不穩(wěn)定的,但是一個穩(wěn)定的排序算法,你可以把它設計成不穩(wěn)定的。

2、常見排序的分類

Java數(shù)據(jù)結構常見排序算法(總結分享)

這張圖,概括了我們后續(xù)要講的排序算法,接著正式進入本章的學習吧!(排序算法章節(jié),默認都是升序排序) 注:后續(xù)所說的復雜度 log,都是以2為底,特殊的會標注出來。

3、直接插入排序

現(xiàn)在想請各位小伙伴,想象一下自己在摸撲克牌,摸了第一張牌放在了自己的手中,接著再摸一張,把這張牌跟手上的一張牌進行比較,把它放到合適的位置, 接著再摸一張,把這張牌跟手上的兩張牌進行比較,放到合適的位置。

這就是直接插入排序,簡單來說,我們每次取的元素,會往一個有序的序列中插入,也就是每次摸牌之前,手上的牌都是排好序的,我們只需要把新摸到的牌,依次與手上有序的牌進行比較,把它放入合適的位置就行!

這里我們用一副靜態(tài)的圖來簡單演示下:

Java數(shù)據(jù)結構常見排序算法(總結分享)

大致的思想我們已經(jīng)明白了,接下來我們就需要用代碼來實現(xiàn)他:

public void insertSort(int[] array) {     // 外循環(huán)控制趟數(shù), 第一張牌默認有序, 所以 i 從 1 開始     for (int i = 1; i < array.length; i++) {         int tmp = array[i]; //當前摸到的牌         // 每次從手中牌的最后一張牌開始比較, 一直比到第一張牌         int j = i - 1;         for (; j >= 0; j--) {             //如果當前位置的牌,大于我摸到的牌,就往后挪             if (array[j] > tmp) {                 array[j + 1] = array[j];             } else {                 break;             }         }         // 把摸到的牌放到對應位置上         array[j + 1] = tmp;     } }
登錄后復制

  • 時間復雜度分析:外循環(huán)一共要 n – 1 次,內循環(huán)每次最差的情況下要比較 1….n 次,那么去掉 n 前面的小項,也就是 (n – 1) * n 次,即 n^2 – n,去掉最小項,最后的時間復雜度為 O(n^2)
  • 空間復雜度分析:只是開辟了一個 tmp 的變量 i,j,常數(shù),即空間復雜度:O(1)
  • 穩(wěn)定性:穩(wěn)定
  • 該排序再數(shù)據(jù)越接近有序的情況,時間效率越高。

4、希爾排序(縮小增量排序)

這個排序是直接插入排序的一種優(yōu)化,你可以想象一下,你面前有并排放好的 8 個愛心號碼牌,但是它們是無序的,我們要給號碼牌分組,按要求,第一次間隔為 4 個號碼牌的為一組,分完組后進行直接插入排序,第二次間隔為 2 個號碼牌的為一組,進行直接插入排序,第三次間隔為 1 個號碼牌為一組,進行直接插入排序。

聽到這有點沒理解,沒關系,我們就通過畫圖來把我上述說的內容再次理解下:

Java數(shù)據(jù)結構常見排序算法(總結分享)

由上圖我們可以發(fā)現(xiàn),當間隔 > 1 的時候,都是預排序,也就是讓我們的數(shù)據(jù)更接近有序,但是當間隔為 1 的時候,就是直接插入排序了,前面我們說過,直接插入排序,再數(shù)據(jù)接近有序的時候時間效率是很快的。由此可見,希爾排序,是直接插入排序的優(yōu)化版。

如何在代碼中實現(xiàn)呢?間隔的值如何取呢?代碼中把這個間隔的值稱為 gap,這個 gap 的取值方法有很多,有的人提出 gap 為奇數(shù)好,有的提出 gap 為偶數(shù)好,我們就采取一種比較簡單的方法來取 gap 值,首次取數(shù)組長度一半的值為 gap,后續(xù) gap /= 2,即可。當 gap 為 1,也就是直接插入排序了。

代碼實現(xiàn)如下:

public void shellSort(int[] array) {     // gap初始值設置成數(shù)組長度的一半     int gap = array.length >> 1;     // gap 為 1 的時候直接插入排序     while (gap >= 1) {         shell(array, gap);         gap >>= 1; // 更新 gap 值 等價于 -> gap /= 2;     } } private void shell(int[] array, int gap) {     for (int i = gap; i < array.length; i++) {         int tmp = array[i];         int j = i - gap;         for (; j >= 0; j -= gap) {             if (array[j] > tmp) {                 array[j + gap] = array[j];             } else {                 break;             }         }         array[j + gap] = tmp;     } }
登錄后復制

如果實在是不好理解,就結合上邊講的直接插入排序來理解,相信你能理解到的。

  • 時間復雜度分析:希爾排序的時間復雜度不好分析, 這里我們就大概記一下,約為 O(n^1.3),感興趣的話,可以查閱一下相關書籍。
  • 空間復雜度分析:仍然開辟的是常數(shù)個變量,空間復雜度為 O(1)
  • 穩(wěn)定性:不穩(wěn)定

5、選擇排序

這個排序是個很簡單的排序,你想象一下,有個小屁孩,喜歡玩小球,我給他安排了個任務,把這一排小球從小到大排列起來,擺給我看,于是小屁孩就找,每次從一排小球中找出最大的,放到最后,固定不動,那是不是也就是說,每次能確定一個最大的石子的最終位置了。我們來看圖:

Java數(shù)據(jù)結構常見排序算法(總結分享)

通過圖片我們也能看出來,每次找到最大值于最后一個值交換,所以每趟都能把最大的放到最后固定不動,每趟能排序一個元素出來,那這樣用代碼來實現(xiàn)就很簡單了:

public void selectSort(int[] array) {     int end = array.length - 1;     // 剩最后一個元素的時候, 不用比較了, 已經(jīng)有序了     // 所以 i < array.length - 1     for (int i = 0; i < array.length - 1; i++) {         int max = 0;         int j = 0;         while (j <= end) {             if (array[j] > array[max]) {                 max = j;             }             j++;         }         //找到了最大值的下標, 把最大值與最后一個值交換         swap(array, max, end--); // end-- 最后一個元素固定了, 不用參與比較     } }
登錄后復制

這個算法有沒有可以優(yōu)化的空間呢?

有!那么既然小屁孩能一次找出最大的球,那能不能讓小屁孩一次找出兩個球出來呢?分別是這些球中,最大的和最小的,最大的放在最右邊,最小的放在最左邊,那么我們每次就能確定兩個球的最終位置,也就是我們一次能排序兩個元素。圖解:

Java數(shù)據(jù)結構常見排序算法(總結分享)

代碼實現(xiàn)如下:

public void selectSort(int[] array) {     int left = 0;     int right = array.length - 1;     while (left < right) {         int maxIndex = left;         int minIndex = left;         // i = left + 1 -> 每次找最大最小值下標的時候, 可以不用算默認給的最大值和最小值下標         for (int i = left + 1; i <= right; i++) {             if (array[i] > array[maxIndex]) {                 maxIndex = i;             }             if (array[i] < array[minIndex]) {                 minIndex = i;             }         }         swap(array, minIndex, left);         // 如果最大值為 left 的位置情況的話, 走到這, 最大值已經(jīng)被交換到 min 位置上了         if (maxIndex == left) {             // 更新最大值的位置             maxIndex = minIndex;         }         swap(array, maxIndex, right);         left++;         right--;     } }
登錄后復制

  • 時間復雜度分析:雖然是優(yōu)化了,但去小項之后,還是 O(n^2)
  • 空間復雜度分析:O(1)
  • 穩(wěn)定性:不穩(wěn)定
  • 實際開發(fā)中用的不多

6、堆排序

如果你有學習過優(yōu)先級隊列,或者看過博主優(yōu)先級隊列的文章,那么這個排序對于你來說還是很輕松的,當然在堆排序的講解中,不會過多的去介紹堆的概念,如果對這部分概念還不理解,可以移至博主的上一篇文章進行學習。

堆排序,簡單來說,就是把一組數(shù)據(jù),看成一個完全二叉樹,再把這棵樹,建大堆或者建小堆,接著進行排序的一種思路。至于如何建大堆或小堆,和向上調整算法以及向下調整算法,這里也不多介紹了,博主的上篇文章都詳細介紹過。

這里我們來分析一下,排升序應該建什么堆?大堆!排降序建小堆!

這里我們來排升序,建大堆,因為大堆堆頂元素一定是堆中最大的,所以我們可以把堆頂元素和最后一個元素進行交換,這樣我們就確認了最大值的位置,接著將交換后的堆頂元素進行向下調整,仍然使得該數(shù)組滿足大堆的特性!圖解如下:

Java數(shù)據(jù)結構常見排序算法(總結分享)

Java數(shù)據(jù)結構常見排序算法(總結分享)

如上圖步驟也很簡單,先是將數(shù)組建成大堆,然后利用大堆來進行堆排序,首先將堆頂元素和最后一個元素交換,由此最大的元素就有序了,接著將該堆進行向下調整,使繼續(xù)滿足大堆性質,依次進行下去即可。

代碼實現(xiàn):

public void heapSort(int[] array) {     // 建大堆 從最后一個非葉子節(jié)點開始向下調整     // 非葉子節(jié)點下標 = (孩子節(jié)點下標 - 1) / 2     for (int parent = (array.length - 1 - 1) / 2; parent >= 0; parent--) {         shiftDown(array, parent, array.length);     }     // 建大堆完成后, 每次堆頂元素與最后一個元素交換, 鎖定最大元素的位置     for (int len = array.length - 1; len > 0; len--) {         swap(array, 0, len); //根節(jié)點與最后一個元素交換         shiftDown(array, 0, len); //根節(jié)點位置向下調整     } } private void shiftDown(int[] array, int parent, int len) {     int child = parent * 2 + 1;     while (child < len) {         if (child + 1 < len && array[child + 1] > array[child]) {             child++;         }         // 判斷父節(jié)點是否大于較大的孩子節(jié)點         if (array[parent] < array[child]) {             swap(array, parent, child);             // 更新下標的位置             parent = child;             child = parent * 2 + 1;         } else {             return;         }     } }
登錄后復制

  • 時間復雜度分析:建堆的時間復雜度優(yōu)先級隊列那期有說過為 O(n),排序調整堆的時候,一共要調整 n-1 次,每次向下調整的時間復雜度是 logn,所以即 logn(n – 1),即 O(n*logn),加上面建堆的時間復雜度:O(n) + O(n*logn),最終時間復雜度也就是:O(n*logn)。
  • 空間復雜度分析:O(1)
  • 穩(wěn)定性:不穩(wěn)定

推薦學習:《java視頻教程》

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
男人的天堂AV网站| 麻花传媒CEO免费观看| 亚洲AV无码专区里番在线观看| 精品免费AV一区二区三区| 新版АⅤ资源新版在线天堂 | 亚洲国产精品成人久久蜜臀| 欧美亚洲一区二区三区| 撒尿PISSINGⅤIDEEO| 亚洲中文字幕乱码电影| 日韩AV一区二区在线| 国产精品乱子乱XXXX| 亚洲狠狠色成人综合网 | 粉嫩小泬无遮挡久久久久久小说| 18禁黄网站禁片免费观看香港| 少妇无码一区二区三区| 好男人资源在线WWW免费| 国产在线无遮挡免费观看| 双腿被绑成M型调教PⅠAY照片| 国产一精品一AV一免费| √BT天堂网WWW中文在线| 偷看自己婆给别人玩经过| 欧精国精产品一区| 久久久久久国产精品无码超碰 | 好爽毛片一区二区三区四| 看全色黄大色黄女片爽在线看| 人妻少妇精品视频专区| 好儿子你插得太深了| FREE性欧美18ⅩXOO极品| 亚洲AV乱码一区二区三区林ゆな | 精选AV种子无码专区| 52色擼99热99RE超碰| 小妖精好爽H快穿共妻| 小宝贝下面的小嘴流水了| 久久天天躁夜夜躁狠狠2018| 国产精品国产三级国产试看| 99久久夜色精品国产网站| 欧美丰满少妇人妻精品| 国内少妇偷人精品免费| 差差漫画页面在线阅读弹窗在线看| 亚洲成A人V在线蜜臀| 色噜噜狠狠狠综合曰曰曰| 欧美A片XⅩX黑人性受| 久久精品亚洲中文无东京热| 国产精品久久久久久久久电影网| 无码熟妇人妻AV在线影片| 麻花传媒剧国产MV在线观看 | 无码人妻精品一区二区三区99不 | 区二区三区国产精华液区别大吗| 麻豆果冻传媒新剧国产短视频| 黑人巨大精品欧美| 欧美丰满多毛少妇XXXXX性| 午夜人妻久久久久久久久| 3分19秒砍人手脚血腥场面| 国产精品亚洲А∨无码播放不卡 | 国产精品一国产精品| 妺妺窝人体色WWW国产馆在线 | 国产卡一卡二无线乱码| 能让我流水水的一千字| 欧美精产国品一二三区别| 性色AV浪潮AV色欲AV| JAPANESE 大战黑人| 激情综合五月丁香五月激情| 日本丰满熟妇55乱偷| 亚洲一区二区三区乱码AⅤ蜜桃女 亚洲一区二区三区乱码AⅤ蜜桃 | 国产真实伦在线观看| 亚洲午夜无码片在线观看影院| 压在窗户上C给别人看窗前| 手机在线永久免费观看AV片| 强壮公弄得我次次高潮小说| 女人的选择HD中字| 欧美性狂猛AAAAAA| 日日摸日日碰夜夜爽暖暖视频| 亚洲欧美日韩国产手机在线| 擦老太BBB擦BBB擦BBB擦| 精品人妻无码区二区三区密桃| 三级无码在钱AV无码在钱| 在线爱色视频观看免费视频| 国产我和子的与子乱视频| 日本适合十八岁以上人群的护肤品| 一本大道一卡2卡三卡4卡国产| 国产精品亚洲综合网熟女| 狂野欧美激情性XXXX在线观看| 久久人人爽人人人人爽AV| 女人18毛片A级毛片嫰阝| 人人澡人人妻人人爽少妇| 天天摸夜夜添夜夜无码| 性一交一乱一性一在线观看| 亚洲欧美另类在线观看| 一本无线乱码不卡一二三四| 狠狠色婷婷久久综合频道毛片 | А√天堂资源地址在线官网| 成人区人妻精品一区二区网站 | 大地韩国日本HD免费完整| 厨房里的激战2李明人物介绍| 精品成在人线AV无码免费看| 亚洲AV无码成人网站WWW| 亚洲AV日韩精品久久久久久A| 床震吃胸膜奶免费视频| 欧美黑人暴力深喉囗交| 亚洲无人区码一码二码三码区别 | 无码丰满人妻熟妇区| 大香煮伊区一二三四区2021| 啪啪无码人妻丰满熟妇| 国产精品久久久久电影院| 国精品无码一区二区三区在线| 久久久久久精品免费无码无| 日本三线和韩国三线的市场定位 | 少妇厨房愉情理伦片BD在线观看| 亚洲人成网站18禁止| 老妇饥渴XXHDⅩXXOOO| 日本入室强伦姧BD在线观看| 7777色鬼XXXX欧美色妇| 久久综合九色综合欧美狠狠| 亚洲亚洲人成无码网WWW| 精品国精品无码自拍自在线 | 人与善交XUANWEN18| ACCA少女SDANVI| 欧美成人一区二区三区不卡| 18性欧美XXXⅩ性满足| 免费观看男女AV入口网站| 中国 韩国 日本 免费看片| 久久亚洲AV午夜福利精品一区| 亚洲色偷偷综合亚洲AV伊人蜜桃| 黑人狂桶女人高潮嗷嗷叫小说| 亚洲AV无码专区精品无码| 黑人狂桶女人高潮嗷嗷叫小说| 亚洲成AV人片在线观看无APP| 国内精品久久人妻互换| 亚洲AV成人无码影视网| 国产亚洲AV无码AV男人的天堂| 亚瑟国产精品久久| 国内精品久久久久久久97牛牛 | 激情综合婷婷丁香五月俺来也 | 高清国产亚洲精品自在久久| 色综合天天综合狠狠爱_| 高清不卡亚洲日韩AV在线| 铜铜铜铜铜铜铜铜好大好深色星空 | 挺进美妇肉蚌深处| 国产精成人品日日拍夜夜免费| 国产麻花豆剧传媒精品免费| 国产熟人AV一二三区| 性刺激性色爽爱小说| 爆乳一区二区三区无码| 天天天天躁天天爱天天碰2018| 高清不卡亚洲日韩AV在线| 清纯校花挨脔日常H惩罚视频| 19岁MACBOOKPRO日本| 久久人人爽人人爽人人片AV高清 | 免费午夜爽爽爽WWW视频十八禁| 玩乡下黄花小处雏女| 国产精品自产Av一区二区三区| 人妻熟女一区二区AⅤ| 亚洲一区二区三区偷拍女厕| 国色天香卡一卡2卡3卡4卡5 | 人妻无码一区二区三区蜜桃视频| 中国女人内谢69XXXX免费视| 狠狠综合久久综合88亚洲| 特级做A爰片毛片免费看| 波多野结衣在线观看av| 日本XXXⅩ色视频免费观看| 菠萝菠萝蜜菠萝菠萝5| 日产精品一区二区| 97精品伊人久久大香线蕉| 美女裸体十八禁免费网站 | CHINESE0LDMAN老汉| 免费精品一区二区三区第35 | 月光影视WWW在线观看| 韩国的无码AV看免费大片在线| ⅩXXⅩ互换人妻四人互换| 欧精国精产品一区| www亚洲一级AV仑片| 婷婷色婷婷开心五月四房播播| 国产怡春院无码一区二区| 一二三四在线视频社区8| 热RE99久久精品国99热| 国产精品亚洲АV久久| 亚洲中国最大AV网站| 人妻熟妇久久久久久精品无码专区 | 少妇高潮XXXⅩ白浆699| 狠狠噜天天噜日日噜AV| 亚洲欧美日韩久久精品第一区| 久久久久精品国产三级美国美女| 成人免费无码大片A毛片18| 久久天天躁夜夜躁狠狠| 亚洲乱妇老熟女爽到高潮的片| 妺妺窝人体色WWW在线观看| 成人国产精品一区二区免费看 | 女人夜夜春高潮爽A∨片| 国产成人精品一区二区三区无码| 亚洲色精品三区二区一区| 人人妻久久人人澡人人爽人人精品| 国产精选午睡沙发系列999| 永久亚洲成A人片777777| 日韩在线一区二区三区| 精品久久久久久国产| XOXOXO性ⅩYY欧美人与人| 亚洲AV极品熟妇一品二品三品| 欧美A片XⅩX黑人性受| 国产熟女一区二区| AAAA级少妇高潮大片在线观看 |