堆排序


 

概要

本章介紹排序算法中的堆排序。

目錄
1. 堆排序介紹
2. 堆排序圖文說明
3. 堆排序的時間復雜度和穩定性
4. 堆排序實現
4.1 堆排序C實現
4.2 堆排序C++實現
4.3 堆排序Java實現

轉載請注明出處:http://www.cnblogs.com/skywang12345/p/3602162.html


更多排序和算法請參考:數據結構與算法系列 目錄

 

堆排序介紹

堆排序(Heap Sort)是指利用堆這種數據結構所設計的一種排序算法。
因此,學習堆排序之前,有必要了解堆!若讀者不熟悉堆,建議先了解(建議可以通過二叉堆左傾堆斜堆二項堆斐波那契堆等文章進行了解),然后再來學習本章。

我們知道,堆分為"最大堆"和"最小堆"。最大堆通常被用來進行"升序"排序,而最小堆通常被用來進行"降序"排序。
鑒於最大堆和最小堆是對稱關系,理解其中一種即可。本文將對最大堆實現的升序排序進行詳細說明。

 

最大堆進行升序排序的基本思想:
① 初始化堆:將數列a[1...n]構造成最大堆。
② 交換數據:將a[1]和a[n]交換,使a[n]是a[1...n]中的最大值;然后將a[1...n-1]重新調整為最大堆。 接着,將a[1]和a[n-1]交換,使a[n-1]是a[1...n-1]中的最大值;然后將a[1...n-2]重新調整為最大值。 依次類推,直到整個數列都是有序的。

 

下面,通過圖文來解析堆排序的實現過程。注意實現中用到了"數組實現的二叉堆的性質"。
在第一個元素的索引為 0 的情形中:
性質一:索引為i的左孩子的索引是 (2*i+1);
性質二:索引為i的左孩子的索引是 (2*i+2);
性質三:索引為i的父結點的索引是 floor((i-1)/2);

例如,對於最大堆{110,100,90,40,80,20,60,10,30,50,70}而言:索引為0的左孩子的所有是1;索引為0的右孩子是2;索引為8的父節點是3。

 

堆排序圖文說明

堆排序(升序)代碼

/* 
 * (最大)堆的向下調整算法
 *
 * 注:數組實現的堆中,第N個節點的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 *     其中,N為數組下標索引值,如數組中第1個數對應的N為0。
 *
 * 參數說明:
 *     a -- 待排序的數組
 *     start -- 被下調節點的起始位置(一般為0,表示從第1個開始)
 *     end   -- 截至范圍(一般為數組中最后一個元素的索引)
 */
void maxheap_down(int a[], int start, int end)
{
    int c = start;            // 當前(current)節點的位置
    int l = 2*c + 1;        // 左(left)孩子的位置
    int tmp = a[c];            // 當前(current)節點的大小
    for (; l <= end; c=l,l=2*l+1)
    {
        // "l"是左孩子,"l+1"是右孩子
        if ( l < end && a[l] < a[l+1])
            l++;        // 左右兩孩子中選擇較大者,即m_heap[l+1]
        if (tmp >= a[l])
            break;        // 調整結束
        else            // 交換值
        {
            a[c] = a[l];
            a[l]= tmp;
        }
    }
}

/*
 * 堆排序(從小到大)
 *
 * 參數說明:
 *     a -- 待排序的數組
 *     n -- 數組的長度
 */
void heap_sort_asc(int a[], int n)
{
    int i;

    // 從(n/2-1) --> 0逐次遍歷。遍歷之后,得到的數組實際上是一個(最大)二叉堆。
    for (i = n / 2 - 1; i >= 0; i--)
        maxheap_down(a, i, n-1);

    // 從最后一個元素開始對序列進行調整,不斷的縮小調整的范圍直到第一個元素
    for (i = n - 1; i > 0; i--)
    {
        // 交換a[0]和a[i]。交換后,a[i]是a[0...i]中最大的。
        swap(a[0], a[i]);
        // 調整a[0...i-1],使得a[0...i-1]仍然是一個最大堆。
        // 即,保證a[i-1]是a[0...i-1]中的最大值。
        maxheap_down(a, 0, i-1);
    }
}

heap_sort_asc(a, n)的作用是:對數組a進行升序排序;其中,a是數組,n是數組長度。
heap_sort_asc(a, n)的操作分為兩部分:初始化堆 和 交換數據。
maxheap_down(a, start, end)是最大堆的向下調整算法。

 

下面演示heap_sort_asc(a, n)對a={20,30,90,40,70,110,60,10,100,50,80}, n=11進行堆排序過程。下面是數組a對應的初始化結構:

 

 

1 初始化堆

在堆排序算法中,首先要將待排序的數組轉化成二叉堆。
下面演示將數組{20,30,90,40,70,110,60,10,100,50,80}轉換為最大堆{110,100,90,40,80,20,60,10,30,50,70}的步驟。

 

1.1 i=11/2-1,即i=4

上面是maxheap_down(a, 4, 9)調整過程。maxheap_down(a, 4, 9)的作用是將a[4...9]進行下調;a[4]的左孩子是a[9],右孩子是a[10]。調整時,選擇左右孩子中較大的一個(即a[10])和a[4]交換。

 

1.2 i=3

上面是maxheap_down(a, 3, 9)調整過程。maxheap_down(a, 3, 9)的作用是將a[3...9]進行下調;a[3]的左孩子是a[7],右孩子是a[8]。調整時,選擇左右孩子中較大的一個(即a[8])和a[4]交換。

 

1.3 i=2


上面是maxheap_down(a, 2, 9)調整過程。maxheap_down(a, 2, 9)的作用是將a[2...9]進行下調;a[2]的左孩子是a[5],右孩子是a[6]。調整時,選擇左右孩子中較大的一個(即a[5])和a[2]交換。

 

1.4 i=1


上面是maxheap_down(a, 1, 9)調整過程。maxheap_down(a, 1, 9)的作用是將a[1...9]進行下調;a[1]的左孩子是a[3],右孩子是a[4]。調整時,選擇左右孩子中較大的一個(即a[3])和a[1]交換。交換之后,a[3]為30,它比它的右孩子a[8]要大,接着,再將它們交換。

 

1.5 i=0


上面是maxheap_down(a, 0, 9)調整過程。maxheap_down(a, 0, 9)的作用是將a[0...9]進行下調;a[0]的左孩子是a[1],右孩子是a[2]。調整時,選擇左右孩子中較大的一個(即a[2])和a[0]交換。交換之后,a[2]為20,它比它的左右孩子要大,選擇較大的孩子(即左孩子)和a[2]交換。

調整完畢,就得到了最大堆。此時,數組{20,30,90,40,70,110,60,10,100,50,80}也就變成了{110,100,90,40,80,20,60,10,30,50,70}。

 

 

第2部分 交換數據

在將數組轉換成最大堆之后,接着要進行交換數據,從而使數組成為一個真正的有序數組。
交換數據部分相對比較簡單,下面僅僅給出將最大值放在數組末尾的示意圖。

上面是當n=10時,交換數據的示意圖。
當n=10時,首先交換a[0]和a[10],使得a[10]是a[0...10]之間的最大值;然后,調整a[0...9]使它稱為最大堆。交換之后:a[10]是有序的!
當n=9時, 首先交換a[0]和a[9],使得a[9]是a[0...9]之間的最大值;然后,調整a[0...8]使它稱為最大堆。交換之后:a[9...10]是有序的!
...
依此類推,直到a[0...10]是有序的。

 

堆排序的時間復雜度和穩定性

堆排序時間復雜度
堆排序的時間復雜度是O(N*lgN)。
假設被排序的數列中有N個數。遍歷一趟的時間復雜度是O(N),需要遍歷多少次呢?
堆排序是采用的二叉堆進行排序的,二叉堆就是一棵二叉樹,它需要遍歷的次數就是二叉樹的深度,而根據完全二叉樹的定義,它的深度至少是lg(N+1)。最多是多少呢?由於二叉堆是完全二叉樹,因此,它的深度最多也不會超過lg(2N)。因此,遍歷一趟的時間復雜度是O(N),而遍歷次數介於lg(N+1)和lg(2N)之間;因此得出它的時間復雜度是O(N*lgN)。

堆排序穩定性
堆排序是不穩定的算法,它不滿足穩定算法的定義。它在交換數據的時候,是比較父結點和子節點之間的數據,所以,即便是存在兩個數值相等的兄弟節點,它們的相對順序在排序也可能發生變化。
算法穩定性 -- 假設在數列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;並且排序之后,a[i]仍然在a[j]前面。則這個排序算法是穩定的!

 

堆排序實現

下面給出堆排序的三種實現:C、C++和Java。這三種實現的原理和輸出結果都是一樣的,每一種實現中都包括了"最大堆對應的升序排列"和"最小堆對應的降序排序"。
堆排序C實現
實現代碼(heap_sort.c)

  1 /**
  2  * 堆排序:C 語言
  3  *
  4  * @author skywang
  5  * @date 2014/03/12
  6  */
  7 
  8 #include <stdio.h>
  9 
 10 // 數組長度
 11 #define LENGTH(array) ( (sizeof(array)) / (sizeof(array[0])) )
 12 #define swap(a,b) (a^=b,b^=a,a^=b)
 13 
 14 /* 
 15  * (最大)堆的向下調整算法
 16  *
 17  * 注:數組實現的堆中,第N個節點的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 18  *     其中,N為數組下標索引值,如數組中第1個數對應的N為0。
 19  *
 20  * 參數說明:
 21  *     a -- 待排序的數組
 22  *     start -- 被下調節點的起始位置(一般為0,表示從第1個開始)
 23  *     end   -- 截至范圍(一般為數組中最后一個元素的索引)
 24  */
 25 void maxheap_down(int a[], int start, int end)
 26 {
 27     int c = start;            // 當前(current)節點的位置
 28     int l = 2*c + 1;        // 左(left)孩子的位置
 29     int tmp = a[c];            // 當前(current)節點的大小
 30     for (; l <= end; c=l,l=2*l+1)
 31     {
 32         // "l"是左孩子,"l+1"是右孩子
 33         if ( l < end && a[l] < a[l+1])
 34             l++;        // 左右兩孩子中選擇較大者,即m_heap[l+1]
 35         if (tmp >= a[l])
 36             break;        // 調整結束
 37         else            // 交換值
 38         {
 39             a[c] = a[l];
 40             a[l]= tmp;
 41         }
 42     }
 43 }
 44 
 45 /*
 46  * 堆排序(從小到大)
 47  *
 48  * 參數說明:
 49  *     a -- 待排序的數組
 50  *     n -- 數組的長度
 51  */
 52 void heap_sort_asc(int a[], int n)
 53 {
 54     int i;
 55 
 56     // 從(n/2-1) --> 0逐次遍歷。遍歷之后,得到的數組實際上是一個(最大)二叉堆。
 57     for (i = n / 2 - 1; i >= 0; i--)
 58         maxheap_down(a, i, n-1);
 59 
 60     // 從最后一個元素開始對序列進行調整,不斷的縮小調整的范圍直到第一個元素
 61     for (i = n - 1; i > 0; i--)
 62     {
 63         // 交換a[0]和a[i]。交換后,a[i]是a[0...i]中最大的。
 64         swap(a[0], a[i]);
 65         // 調整a[0...i-1],使得a[0...i-1]仍然是一個最大堆。
 66         // 即,保證a[i-1]是a[0...i-1]中的最大值。
 67         maxheap_down(a, 0, i-1);
 68     }
 69 }
 70 
 71 /* 
 72  * (最小)堆的向下調整算法
 73  *
 74  * 注:數組實現的堆中,第N個節點的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 75  *     其中,N為數組下標索引值,如數組中第1個數對應的N為0。
 76  *
 77  * 參數說明:
 78  *     a -- 待排序的數組
 79  *     start -- 被下調節點的起始位置(一般為0,表示從第1個開始)
 80  *     end   -- 截至范圍(一般為數組中最后一個元素的索引)
 81  */
 82 void minheap_down(int a[], int start, int end)
 83 {
 84     int c = start;            // 當前(current)節點的位置
 85     int l = 2*c + 1;        // 左(left)孩子的位置
 86     int tmp = a[c];            // 當前(current)節點的大小
 87     for (; l <= end; c=l,l=2*l+1)
 88     {
 89         // "l"是左孩子,"l+1"是右孩子
 90         if ( l < end && a[l] > a[l+1])
 91             l++;        // 左右兩孩子中選擇較小者
 92         if (tmp <= a[l])
 93             break;        // 調整結束
 94         else            // 交換值
 95         {
 96             a[c] = a[l];
 97             a[l]= tmp;
 98         }
 99     }
100 }
101 
102 /*
103  * 堆排序(從大到小)
104  *
105  * 參數說明:
106  *     a -- 待排序的數組
107  *     n -- 數組的長度
108  */
109 void heap_sort_desc(int a[], int n)
110 {
111     int i;
112 
113     // 從(n/2-1) --> 0逐次遍歷每。遍歷之后,得到的數組實際上是一個最小堆。
114     for (i = n / 2 - 1; i >= 0; i--)
115         minheap_down(a, i, n-1);
116 
117     // 從最后一個元素開始對序列進行調整,不斷的縮小調整的范圍直到第一個元素
118     for (i = n - 1; i > 0; i--)
119     {
120         // 交換a[0]和a[i]。交換后,a[i]是a[0...i]中最小的。
121         swap(a[0], a[i]);
122         // 調整a[0...i-1],使得a[0...i-1]仍然是一個最小堆。
123         // 即,保證a[i-1]是a[0...i-1]中的最小值。
124         minheap_down(a, 0, i-1);
125     }
126 }
127 
128 void main()
129 {
130     int i;
131     int a[] = {20,30,90,40,70,110,60,10,100,50,80};
132     int ilen = LENGTH(a);
133 
134     printf("before sort:");
135     for (i=0; i<ilen; i++)
136         printf("%d ", a[i]);
137     printf("\n");
138 
139     heap_sort_asc(a, ilen);            // 升序排列
140     //heap_sort_desc(a, ilen);        // 降序排列
141 
142     printf("after  sort:");
143     for (i=0; i<ilen; i++)
144         printf("%d ", a[i]);
145     printf("\n");
146 }
View Code

堆排序C++實現
實現代碼(HeapSort.cpp)

  1 /**
  2  * 堆排序:C++
  3  *
  4  * @author skywang
  5  * @date 2014/03/11
  6  */
  7 
  8 #include <iostream>
  9 using namespace std;
 10 
 11 /* 
 12  * (最大)堆的向下調整算法
 13  *
 14  * 注:數組實現的堆中,第N個節點的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 15  *     其中,N為數組下標索引值,如數組中第1個數對應的N為0。
 16  *
 17  * 參數說明:
 18  *     a -- 待排序的數組
 19  *     start -- 被下調節點的起始位置(一般為0,表示從第1個開始)
 20  *     end   -- 截至范圍(一般為數組中最后一個元素的索引)
 21  */
 22 void maxHeapDown(int* a, int start, int end)
 23 {
 24     int c = start;            // 當前(current)節點的位置
 25     int l = 2*c + 1;        // 左(left)孩子的位置
 26     int tmp = a[c];            // 當前(current)節點的大小
 27     for (; l <= end; c=l,l=2*l+1)
 28     {
 29         // "l"是左孩子,"l+1"是右孩子
 30         if ( l < end && a[l] < a[l+1])
 31             l++;        // 左右兩孩子中選擇較大者,即m_heap[l+1]
 32         if (tmp >= a[l])
 33             break;        // 調整結束
 34         else            // 交換值
 35         {
 36             a[c] = a[l];
 37             a[l]= tmp;
 38         }
 39     }
 40 }
 41 
 42 /*
 43  * 堆排序(從小到大)
 44  *
 45  * 參數說明:
 46  *     a -- 待排序的數組
 47  *     n -- 數組的長度
 48  */
 49 void heapSortAsc(int* a, int n)
 50 {
 51     int i,tmp;
 52 
 53     // 從(n/2-1) --> 0逐次遍歷。遍歷之后,得到的數組實際上是一個(最大)二叉堆。
 54     for (i = n / 2 - 1; i >= 0; i--)
 55         maxHeapDown(a, i, n-1);
 56 
 57     // 從最后一個元素開始對序列進行調整,不斷的縮小調整的范圍直到第一個元素
 58     for (i = n - 1; i > 0; i--)
 59     {
 60         // 交換a[0]和a[i]。交換后,a[i]是a[0...i]中最大的。
 61         tmp = a[0];
 62         a[0] = a[i];
 63         a[i] = tmp;
 64         // 調整a[0...i-1],使得a[0...i-1]仍然是一個最大堆。
 65         // 即,保證a[i-1]是a[0...i-1]中的最大值。
 66         maxHeapDown(a, 0, i-1);
 67     }
 68 }
 69 
 70 /* 
 71  * (最小)堆的向下調整算法
 72  *
 73  * 注:數組實現的堆中,第N個節點的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 74  *     其中,N為數組下標索引值,如數組中第1個數對應的N為0。
 75  *
 76  * 參數說明:
 77  *     a -- 待排序的數組
 78  *     start -- 被下調節點的起始位置(一般為0,表示從第1個開始)
 79  *     end   -- 截至范圍(一般為數組中最后一個元素的索引)
 80  */
 81 void minHeapDown(int* a, int start, int end)
 82 {
 83     int c = start;            // 當前(current)節點的位置
 84     int l = 2*c + 1;        // 左(left)孩子的位置
 85     int tmp = a[c];            // 當前(current)節點的大小
 86     for (; l <= end; c=l,l=2*l+1)
 87     {
 88         // "l"是左孩子,"l+1"是右孩子
 89         if ( l < end && a[l] > a[l+1])
 90             l++;        // 左右兩孩子中選擇較小者
 91         if (tmp <= a[l])
 92             break;        // 調整結束
 93         else            // 交換值
 94         {
 95             a[c] = a[l];
 96             a[l]= tmp;
 97         }
 98     }
 99 }
100 
101 /*
102  * 堆排序(從大到小)
103  *
104  * 參數說明:
105  *     a -- 待排序的數組
106  *     n -- 數組的長度
107  */
108 void heapSortDesc(int* a, int n)
109 {
110     int i,tmp;
111 
112     // 從(n/2-1) --> 0逐次遍歷每。遍歷之后,得到的數組實際上是一個最小堆。
113     for (i = n / 2 - 1; i >= 0; i--)
114         minHeapDown(a, i, n-1);
115 
116     // 從最后一個元素開始對序列進行調整,不斷的縮小調整的范圍直到第一個元素
117     for (i = n - 1; i > 0; i--)
118     {
119         // 交換a[0]和a[i]。交換后,a[i]是a[0...i]中最小的。
120         tmp = a[0];
121         a[0] = a[i];
122         a[i] = tmp;
123         // 調整a[0...i-1],使得a[0...i-1]仍然是一個最小堆。
124         // 即,保證a[i-1]是a[0...i-1]中的最小值。
125         minHeapDown(a, 0, i-1);
126     }
127 }
128 
129 int main()
130 {
131     int i;
132     int a[] = {20,30,90,40,70,110,60,10,100,50,80};
133     int ilen = (sizeof(a)) / (sizeof(a[0]));
134 
135     cout << "before sort:";
136     for (i=0; i<ilen; i++)
137         cout << a[i] << " ";
138     cout << endl;
139 
140     heapSortAsc(a, ilen);            // 升序排列
141     //heapSortDesc(a, ilen);        // 降序排列
142 
143     cout << "after  sort:";
144     for (i=0; i<ilen; i++)
145         cout << a[i] << " ";
146     cout << endl;
147 
148     return 0;
149 }
View Code

堆排序Java實現
實現代碼(HeapSort.java)

  1 /**
  2  * 堆排序:Java
  3  *
  4  * @author skywang
  5  * @date 2014/03/11
  6  */
  7 
  8 public class HeapSort {
  9 
 10     /* 
 11      * (最大)堆的向下調整算法
 12      *
 13      * 注:數組實現的堆中,第N個節點的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 14      *     其中,N為數組下標索引值,如數組中第1個數對應的N為0。
 15      *
 16      * 參數說明:
 17      *     a -- 待排序的數組
 18      *     start -- 被下調節點的起始位置(一般為0,表示從第1個開始)
 19      *     end   -- 截至范圍(一般為數組中最后一個元素的索引)
 20      */
 21     public static void maxHeapDown(int[] a, int start, int end) {
 22         int c = start;            // 當前(current)節點的位置
 23         int l = 2*c + 1;        // 左(left)孩子的位置
 24         int tmp = a[c];            // 當前(current)節點的大小
 25 
 26         for (; l <= end; c=l,l=2*l+1) {
 27             // "l"是左孩子,"l+1"是右孩子
 28             if ( l < end && a[l] < a[l+1])
 29                 l++;        // 左右兩孩子中選擇較大者,即m_heap[l+1]
 30             if (tmp >= a[l])
 31                 break;        // 調整結束
 32             else {            // 交換值
 33                 a[c] = a[l];
 34                 a[l]= tmp;
 35             }
 36         }
 37     }
 38 
 39     /*
 40      * 堆排序(從小到大)
 41      *
 42      * 參數說明:
 43      *     a -- 待排序的數組
 44      *     n -- 數組的長度
 45      */
 46     public static void heapSortAsc(int[] a, int n) {
 47         int i,tmp;
 48 
 49         // 從(n/2-1) --> 0逐次遍歷。遍歷之后,得到的數組實際上是一個(最大)二叉堆。
 50         for (i = n / 2 - 1; i >= 0; i--)
 51             maxHeapDown(a, i, n-1);
 52 
 53         // 從最后一個元素開始對序列進行調整,不斷的縮小調整的范圍直到第一個元素
 54         for (i = n - 1; i > 0; i--) {
 55             // 交換a[0]和a[i]。交換后,a[i]是a[0...i]中最大的。
 56             tmp = a[0];
 57             a[0] = a[i];
 58             a[i] = tmp;
 59             // 調整a[0...i-1],使得a[0...i-1]仍然是一個最大堆。
 60             // 即,保證a[i-1]是a[0...i-1]中的最大值。
 61             maxHeapDown(a, 0, i-1);
 62         }
 63     }
 64 
 65     /* 
 66      * (最小)堆的向下調整算法
 67      *
 68      * 注:數組實現的堆中,第N個節點的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 69      *     其中,N為數組下標索引值,如數組中第1個數對應的N為0。
 70      *
 71      * 參數說明:
 72      *     a -- 待排序的數組
 73      *     start -- 被下調節點的起始位置(一般為0,表示從第1個開始)
 74      *     end   -- 截至范圍(一般為數組中最后一個元素的索引)
 75      */
 76     public static void minHeapDown(int[] a, int start, int end) {
 77         int c = start;            // 當前(current)節點的位置
 78         int l = 2*c + 1;        // 左(left)孩子的位置
 79         int tmp = a[c];            // 當前(current)節點的大小
 80 
 81         for (; l <= end; c=l,l=2*l+1) {
 82             // "l"是左孩子,"l+1"是右孩子
 83             if ( l < end && a[l] > a[l+1])
 84                 l++;        // 左右兩孩子中選擇較小者
 85             if (tmp <= a[l])
 86                 break;        // 調整結束
 87             else {            // 交換值
 88                 a[c] = a[l];
 89                 a[l]= tmp;
 90             }
 91         }
 92     }
 93 
 94     /*
 95      * 堆排序(從大到小)
 96      *
 97      * 參數說明:
 98      *     a -- 待排序的數組
 99      *     n -- 數組的長度
100      */
101     public static void heapSortDesc(int[] a, int n) {
102         int i,tmp;
103 
104         // 從(n/2-1) --> 0逐次遍歷每。遍歷之后,得到的數組實際上是一個最小堆。
105         for (i = n / 2 - 1; i >= 0; i--)
106             minHeapDown(a, i, n-1);
107 
108         // 從最后一個元素開始對序列進行調整,不斷的縮小調整的范圍直到第一個元素
109         for (i = n - 1; i > 0; i--) {
110             // 交換a[0]和a[i]。交換后,a[i]是a[0...i]中最小的。
111             tmp = a[0];
112             a[0] = a[i];
113             a[i] = tmp;
114             // 調整a[0...i-1],使得a[0...i-1]仍然是一個最小堆。
115             // 即,保證a[i-1]是a[0...i-1]中的最小值。
116             minHeapDown(a, 0, i-1);
117         }
118     }
119 
120     public static void main(String[] args) {
121         int i;
122         int a[] = {20,30,90,40,70,110,60,10,100,50,80};
123 
124         System.out.printf("before sort:");
125         for (i=0; i<a.length; i++)
126             System.out.printf("%d ", a[i]);
127         System.out.printf("\n");
128 
129         heapSortAsc(a, a.length);            // 升序排列
130         //heapSortDesc(a, a.length);        // 降序排列
131 
132         System.out.printf("after  sort:");
133         for (i=0; i<a.length; i++)
134             System.out.printf("%d ", a[i]);
135         System.out.printf("\n");
136     }
137 }
View Code

 

它們的輸出結果:

before sort:20 30 90 40 70 110 60 10 100 50 80 
after  sort:10 20 30 40 50 60 70 80 90 100 110 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM