一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 老生常談比較排序之堆排序

老生常談比較排序之堆排序

2020-11-23 10:52Java教程網 Java教程

下面小編就為大家帶來一篇老生常談比較排序之堆排序。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

對于堆排序會涉及一些完全二叉樹知識。對于待排序列{10, 2, 11, 8, 7},把它看成是一顆完全二叉樹,如下圖所示。

老生常談比較排序之堆排序

堆分為大根堆和小根堆:大根堆表示每個根節點均大于其子節點(l(i) >= l(2i) && l(i) >= l(2i + 1)),小根堆表示每個根節點均小于其子節點(l(i) <= l(2i) && l(i) <= l(2i + 1))。(在完全二叉樹中第i個節點的左子節點為2i,其右字節點為2i + 1

本文將以大根堆的構建作為示例進行講解。

堆排序的第一步——構建初始堆。如何構建初始堆呢?根據定義,關鍵點在于每個根節點。觀察上述待排序列的完全二叉樹,不難發現存在節點2和節點10有子節點,它們是需要關注的節點。

老生常談比較排序之堆排序

如何定位節點2呢?發現它是葉子節點,或者最后一個節點的父節點,根據完全二叉樹的性質可知,除根節點外任意節點的父節點的編號為⌊n / 2⌋。已知n = 5,易知節點2的編號為⌊5 / 2⌋ = ②。比較它與左右子節點的大小并調整。

老生常談比較排序之堆排序

最后剩下根節點10,已知節點2的編號為② - 1 = ①即得到根節點10的編號。比較它與左右子節點的大小并調整。

老生常談比較排序之堆排序

調整完畢后發現已經構成了一個大根堆,示例中的待排序列較為簡單,再給出一個較為復雜的待排序列,觀察其構建大根堆的過程。對于待排序列{53, 17, 78, 09, 45, 65, 87, 32},將它看成一顆完全二叉樹。

老生常談比較排序之堆排序

同樣我們來看它所需要關注的節點有哪些。

老生常談比較排序之堆排序

根據第一個例子,我們很容易能定位節點09的編號為⌊8 / 2⌋ = ④,節點78的編號為④ - 1 = ③……,依次類推,發現了一定的規律,即需要調整的節點位置從n / 2開始依次遞減直到根節點結束(n / 2 ~ 1)。現在開始調整。

老生常談比較排序之堆排序

老生常談比較排序之堆排序

老生常談比較排序之堆排序

老生常談比較排序之堆排序

在第四次調整結束后發現節點53不滿足大根堆的定義,其右子節點大于它,此時需要做進一步的向下調整。

老生常談比較排序之堆排序

注意向下調整是每次向上調整的時候都需要做的判斷是否需要向下調整,而不是在所有的向上調整結束過后再回過頭來向下調整。這樣大根堆就建立好了,此時待排序列數組情況已經發生了改變:{87, 45, 78, 32, 17, 65, 53, 09}。接下來是如何進行排序的問題。將大根堆的根節點與最后一個節點互換,并調整二叉樹使其仍然滿足大根堆。

老生常談比較排序之堆排序

可以看到將根節點與最后一個節點呼喚后,待排序列的最大值已經放到了數組的最后一個位置{……, 87},此時完成了第一趟排序,但這第一趟排序還沒有結束,此時除節點87外,其余節點并不滿足大根堆的條件,所以需要對其余節點進行調整為大根堆。排序過程不再給出,javapython3的代碼實現如下。

java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.algorithm.sort.heap;
 
import java.util.arrays;
 
/**
 * 堆排序
 * created by yulinfeng on 6/20/17.
 */
public class heap {
  
  public static void main(string[] args) {
    int[] nums = {53, 17, 78, 09, 45, 65, 87, 32};
    nums = heapsort(nums);
    system.out.println(arrays.tostring(nums));
  }
  
  /**
   * 堆排序
   * @param nums 待排序數組序列
   * @return 排好序的數組序列
   */
  private static int[] heapsort(int[] nums) {
  
    for (int i = nums.length / 2 - 1; i >= 0; i--) {
      heapadjust(nums, i, nums.length);
    }
    for (int i = nums.length - 1; i > 0; i--) {
      int temp = nums[i];
      nums[i] = nums[0];
      nums[0] = temp;
      heapadjust(nums, 0, i);
    }
    return nums;
  }
  
  /**
   * 調整堆
   *
   * @param nums  待排序序列
   * @param parent   待調整根節點
   * @param length 數組序列長度
   */
  private static void heapadjust(int[] nums, int parent, int length) {
    int temp = nums[parent];
    int childindex = 2 * parent + 1//完全二叉樹節點i從編號1開始的左子節點位置在2i,此處數組下標從0開始,即左子節點所在數組索引位置為:2i + 1
    while (childindex < length) {
      if (childindex + 1 < length && nums[childindex] < nums[childindex + 1]) {
        childindex++;  //節點有右子節點,且右子節點大于左子節點,則選取右子節點
      }
      if (temp > nums[childindex]) {
        break; //如果選中節點大于其子節點,直接返回
      }
      nums[parent] = nums[childindex];
      parent = childindex;
      childindex = 2 * parent + 1//繼續向下調整
    }
    nums[parent] = temp;
  }
}

python3

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#堆排序
def heap_sort(nums):
 
  for i in range(int(len(nums) / 2 - 1), -1, -1):
    heap_adjust(nums, i, len(nums))
  
  for i in range(len(nums) - 1, -1, -1):
    temp = nums[i]
    nums[i] = nums[0]
    nums[0] = temp
    heap_adjust(nums, 0, i)
  
  return nums
 
#調整堆
def heap_adjust(nums, parent, length):
  
  temp = nums[parent]
  childindex = 2 * parent + 1
  while childindex < length:
    if childindex + 1 < length and nums[childindex] < nums[childindex + 1]:
      childindex += 1
    if temp > nums[childindex]:
      break
    nums[parent] = nums[childindex]
    parent = childindex
    childindex = 2 * parent + 1
  
  nums[parent] = temp
    
nums = [53, 17, 78, 09, 45, 65, 87, 32]
nums = heap_sort(nums)
print(nums)

以上這篇老生常談比較排序之堆排序就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 四虎影视永久在线观看 | 夫妻性生活免费在线观看 | 忘忧草在线 | 美日韩一区二区三区 | 色综合综合色 | 日韩视频免费一区二区三区 | 精精国产xxxx视频在线播放器 | 日本韩国无矿砖码 | 美女脱得一二净无内裤全身的照片 | 亚洲欧美成人综合在线 | 欧美成人午夜片一一在线观看 | jizz农村野外jizz农民 | 亚洲区精品久久一区二区三区 | 日本精品久久久久久久久免费 | 欧美日韩亚洲另类人人澡 | 欧美人与禽杂交大片 | 交换朋友夫妇3中文字幕 | 亚洲娇小videos | 91狠狠| 桃乃木香奈作品在线 | 日本黄a | 色碰视频 | 极端 成熟 性别 视频 | 男人含玉势出嫁束器 | 亚洲国产果果在线播放在线 | 亚洲欧美一区二区三区在线观看 | 国产91精选学生在线观看 | 香蕉精品| 亚洲日本va午夜中文字幕 | 4s4s4s4s色大众影视 | 四虎精品视频在线永久免费观看 | 免费国产高清精品一区在线 | 极端 成熟 性别 视频 | 国色天香社区视频在线观看免费完整版 | 日本xxxx在线视频免费 | 久久国产精品二区99 | 国产麻豆91网在线看 | 五月天网站 | 国产免费久久精品 | 欧美不卡一区二区三区免 | 日本在线播放 |