gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

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

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

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

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

1、 認(rèn)識(shí)排序

在學(xué)校中,如果我們要參加運(yùn)動(dòng)會(huì),或者軍訓(xùn)的時(shí)候,會(huì)按照身高從矮到高進(jìn)行站隊(duì),比如上課老師手上拿的考勤表,通常是按照學(xué)號(hào)從低到高進(jìn)行排序的。再比如編程語言排行榜,也是在排序。

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

生活中有相當(dāng)多的排序場(chǎng)景,由此可知,排序還是很重要的, 本章就會(huì)介紹常見的一些排序算法。

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

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

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

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

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

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

2、常見排序的分類

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

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

3、直接插入排序

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

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

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

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

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

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

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

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

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

聽到這有點(diǎn)沒理解,沒關(guān)系,我們就通過畫圖來把我上述說的內(nèi)容再次理解下:

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

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

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

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

public void shellSort(int[] array) {     // gap初始值設(shè)置成數(shù)組長(zhǎng)度的一半     int gap = array.length >> 1;     // gap 為 1 的時(shí)候直接插入排序     while (gap >= 1) {         shell(array, gap);         gap >>= 1; // 更新 gap 值 等價(jià)于 -> 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;     } }
登錄后復(fù)制

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

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

5、選擇排序

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

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

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

public void selectSort(int[] array) {     int end = array.length - 1;     // 剩最后一個(gè)元素的時(shí)候, 不用比較了, 已經(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++;         }         //找到了最大值的下標(biāo), 把最大值與最后一個(gè)值交換         swap(array, max, end--); // end-- 最后一個(gè)元素固定了, 不用參與比較     } }
登錄后復(fù)制

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

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

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

代碼實(shí)現(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 -> 每次找最大最小值下標(biāo)的時(shí)候, 可以不用算默認(rèn)給的最大值和最小值下標(biāo)         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--;     } }
登錄后復(fù)制

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

6、堆排序

如果你有學(xué)習(xí)過優(yōu)先級(jí)隊(duì)列,或者看過博主優(yōu)先級(jí)隊(duì)列的文章,那么這個(gè)排序?qū)τ谀銇碚f還是很輕松的,當(dāng)然在堆排序的講解中,不會(huì)過多的去介紹堆的概念,如果對(duì)這部分概念還不理解,可以移至博主的上一篇文章進(jìn)行學(xué)習(xí)。

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

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

這里我們來排升序,建大堆,因?yàn)榇蠖讯秧斣匾欢ㄊ嵌阎凶畲蟮模晕覀兛梢园讯秧斣睾妥詈笠粋€(gè)元素進(jìn)行交換,這樣我們就確認(rèn)了最大值的位置,接著將交換后的堆頂元素進(jìn)行向下調(diào)整,仍然使得該數(shù)組滿足大堆的特性!圖解如下:

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

Java數(shù)據(jù)結(jié)構(gòu)常見排序算法(總結(jié)分享)

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

代碼實(shí)現(xiàn):

public void heapSort(int[] array) {     // 建大堆 從最后一個(gè)非葉子節(jié)點(diǎn)開始向下調(diào)整     // 非葉子節(jié)點(diǎn)下標(biāo) = (孩子節(jié)點(diǎn)下標(biāo) - 1) / 2     for (int parent = (array.length - 1 - 1) / 2; parent >= 0; parent--) {         shiftDown(array, parent, array.length);     }     // 建大堆完成后, 每次堆頂元素與最后一個(gè)元素交換, 鎖定最大元素的位置     for (int len = array.length - 1; len > 0; len--) {         swap(array, 0, len); //根節(jié)點(diǎn)與最后一個(gè)元素交換         shiftDown(array, 0, len); //根節(jié)點(diǎn)位置向下調(diào)整     } } 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é)點(diǎn)是否大于較大的孩子節(jié)點(diǎn)         if (array[parent] < array[child]) {             swap(array, parent, child);             // 更新下標(biāo)的位置             parent = child;             child = parent * 2 + 1;         } else {             return;         }     } }
登錄后復(fù)制

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

推薦學(xué)習(xí):《java視頻教程》

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
天堂8在线天堂资源bt| 啊啊啊一区二区| 久久免费一级片| 91香蕉视频导航| 亚洲熟妇av一区二区三区漫画| 色噜噜狠狠一区二区三区狼国成人| 天天色综合社区| 777一区二区| 狠狠干视频网站| 久色视频在线播放| 福利在线一区二区三区| 伊人精品视频在线观看| www.-级毛片线天内射视视| av网站大全免费| www.亚洲视频.com| 免费无码av片在线观看| 污污网站在线观看视频| 911av视频| 国产大尺度在线观看| 黄色一级大片免费| 欧美性大战久久久久xxx| 欧美日韩亚洲一| 亚洲少妇第一页| 亚洲精品偷拍视频| 青青草精品视频在线| 亚洲一二三区av| 亚洲免费999| 无码日本精品xxxxxxxxx| 日本免费色视频| 欧美少妇一区二区三区| 免费看国产一级片| 91人人澡人人爽人人精品| 亚洲天堂av免费在线观看| 亚洲精品无码久久久久久| 91欧美视频在线| 成人国产一区二区三区| 精品久久久久久久免费人妻| 久无码久无码av无码| 亚洲成人动漫在线| 37pao成人国产永久免费视频| 久久人人爽av| 免费看一级大黄情大片| 欧美性视频在线播放| 男人天堂网视频| 国产资源第一页| 天天视频天天爽| 91专区在线观看| 亚洲色图偷拍视频| 日本一二三四区视频| 亚洲自偷自拍熟女另类| 亚洲高潮无码久久| 午夜精品久久久久久久99热影院| 国产1区2区3区中文字幕| 岛国av免费在线| 国产综合免费视频| 欧美一区二区中文字幕| 午夜啪啪福利视频| 在线视频日韩欧美| 亚洲一区精品视频在线观看| 可以免费观看av毛片| 福利视频一二区| 亚洲第一综合网站| 国产又粗又猛大又黄又爽| 另类小说第一页| 日本成人黄色网| 欧美在线aaa| 久久久久久三级| 午夜免费高清视频| www.激情小说.com| 欧美视频第三页| 男人插女人下面免费视频| 激情综合网婷婷| 国产一级不卡毛片| 国产真人无码作爱视频免费| 日本精品免费在线观看| 亚洲成熟丰满熟妇高潮xxxxx| 国产亚洲精品网站| av污在线观看| 吴梦梦av在线| 六月婷婷激情综合| 国产精品69页| 国产精品久久久毛片| 91aaa精品| 成人免费a级片| 免费av网址在线| 青青视频在线播放| 深夜黄色小视频| 日韩视频 中文字幕| 日韩人妻精品无码一区二区三区| 鲁一鲁一鲁一鲁一色| 国产a级片免费观看| а 天堂 在线| 国产成人无码a区在线观看视频| 黄色片久久久久| 日本黄色播放器| 2019日韩中文字幕mv| 国产一区二区在线免费播放| 少妇熟女一区二区| 日韩在线xxx| 五月天激情图片| 亚洲综合在线网站| 99久久免费观看| 亚洲一二三区av| 国产xxxx振车| 亚洲黄色片免费看| 免费看一级大黄情大片| 天天做天天干天天操| 欧美成人xxxxx| 国产一二三四五| 中文字幕有码av| 色综合久久久久无码专区| 亚欧精品在线视频| 人妻无码视频一区二区三区| 在线观看污视频| 免费精品99久久国产综合精品应用| 国产一级不卡视频| 天堂av8在线| 黄色在线视频网| 欧美日韩中文在线视频| 91国在线高清视频| 亚洲一区日韩精品| 天美星空大象mv在线观看视频| 男人添女荫道口女人有什么感觉| 岛国av在线免费| 999在线观看| 日本免费色视频| 欧美三级理论片| 日本888xxxx| 亚洲天堂网一区| 99视频在线视频| 欧美婷婷精品激情| 青青青国产在线视频| 国产精品久久久久9999小说| 久久人妻精品白浆国产| 北条麻妃在线观看| 日韩一级免费在线观看| 一级特黄性色生活片| 91最新在线观看| 成人av毛片在线观看| 最新黄色av网站| 999一区二区三区| 国产免费观看高清视频| 一本大道熟女人妻中文字幕在线| 日韩激情免费视频| 天天操天天爽天天射| 中文字幕 日韩 欧美| 伊人成人免费视频| 91网站在线观看免费| 成年人网站国产| 日本黄网站免费| 91亚洲精品久久久蜜桃借种| 日韩人妻精品一区二区三区| 久久这里只有精品18| aa免费在线观看| 精品亚洲视频在线| 经典三级在线视频| 给我免费播放片在线观看| 欧美xxxxx在线视频| 国产免费色视频| 国产午夜福利在线播放| 三级视频中文字幕| 在线观看污视频| 黄色a级片免费| 中文字幕av导航| 91av资源网| 中文字幕乱码免费| 亚洲三级视频网站| 毛片av在线播放| 欧美美女性视频| 成人免费在线小视频| 中文字幕一区二区三区四区五区人| 免费在线精品视频| 波多结衣在线观看| 成人午夜视频在线观看免费| 天天操天天干天天做| 9久久9毛片又大又硬又粗| 天天色天天干天天色| www日韩视频| 国产xxxx振车| 国产又大又黄又粗又爽| 国产免费内射又粗又爽密桃视频| 国产九九在线视频| 日日碰狠狠添天天爽超碰97| 久久天天东北熟女毛茸茸| 免费一区二区三区在线观看| 极品美女扒开粉嫩小泬| 日本美女高潮视频| 91猫先生在线| av女优在线播放| 精品国产一区二区三区无码| 欧美日韩视频免费在线观看| 亚洲这里只有精品| 天天爱天天操天天干| 欧美一级黄色片视频| 那种视频在线观看| 日韩人妻精品无码一区二区三区| 日本手机在线视频| 欧美黑人经典片免费观看| 日韩xxxx视频| 亚洲人成无码网站久久99热国产 |