優先佇列:特殊的」佇列」,取出元素的順序是依照元素的優先權(關鍵字)大小,而不是元素進入佇列的先後順序
堆是優先佇列的完全二叉樹表示。
堆的兩個特性:
①結構性:用陣列表示的完全二叉樹
②有序性:任意結點的關鍵字是其子樹所有結點的最大值,叫最大堆(或最小值,叫最小堆)(注意從根結點到任意結點路徑上結點序列的有序性)
下面舉乙個最大堆的例子。
/** 最大堆的操作 */
typedef struct heapstruct *maxheap;
struct heapstruct ;
maxheap create(int maxsize)
void insert(maxheap h,elementtype item)
i = ++h->size;//i指向插入後堆中的最後乙個元素的位置
for( ; h->elements[i/2] > item && i > 1; i /= 2)
h->elements[i] = item;//將item插入
}elementtype deletemax(maxheap h)
maxitem = h->elements[1];//取出根結點最大值
/** 用最大堆中最後乙個元素從根節點開始向上過濾下層結點 */
temp = h->elements[h->size--];
for(parent = 1 ; parent*2
<= h->size; parent = child)
h->elements[parent] = temp;
return maxitem;
}
選擇排序(selection sort)的基本思想是:每一趟在n-i+1(i=1,2,…,n-1)個記錄中選取關鍵字最小的記錄作為有序序列中第i個記錄。
簡單選擇排序:沒啥好說的,**如下
void selectsort(sqlist &l)
}//selectsort
樹形選擇排序:可被堆排序替代,故不再詳述
先看一種使用堆的簡單的o(nlogn)演算法
void heap_sort(elementtype a,int n)
真正的堆排序不是建立最小堆而是建立最大堆,每次將最大堆的根和最後乙個元素交換,再維護成最大堆,這樣直到都交換完畢。**如下
void heap_sort(elementtype a,int n)
}
下面來做乙個排序實驗,將
int s[20] = ;
這組資料分別用簡單選擇排序和堆排序處理,分別重複一千萬次,
結果如下
如果我們把資料加到30個:
這也說明,對於大資料(當然這裡只是假設)堆排序是高效的。
下面是實驗**:
#include #include int main()
; for(int i = 0 ; i < 29 ; i ++)
}if(i != k)
}}/** 簡單選擇排序 */
int _end = clock();
printf("簡單選擇排序需要%dms\n",_end-start);
t = 10000000;
start = clock();
while(t--) ;
for(int i = 14; i >= 0 ; i --)
par = child;}}
for(int i = 29 ; i >= 1 ; i --)
par = child;}}
}/** 堆排序 */
_end = clock();
printf("堆排序需要%dms\n",_end-start);
return
0;}
資料結構 堆(堆排序和模擬堆)
輸入乙個長度為n的整數數列,從小到大輸出前m小的數。輸入格式 第一行包含整數n和m。第二行包含n個整數,表示整數數列。輸出格式 共一行,包含m個整數,表示整數數列中前m小的數。資料範圍 1 m n 10 5,1 數列中元素 10 9 輸入樣例 5 34 5 1 3 2 輸出樣例 1 2 3 演算法的...
java版資料結構與演算法 堆 堆排序
優先順序佇列 用有序陣列實現,刪除最大數最快o 1 插入最慢 用堆實現優先順序佇列,插入和刪除都很快o logn 堆 是一種樹,一種特殊的二叉樹 特點 1.他是完全的二叉樹,除了樹的最後一層節點不需要是滿的,其他一層從左到右都是滿的。2.它常常用乙個陣列實現。3.堆中每乙個節點都滿足堆的條件,父節點...
資料結構之二叉堆 堆排序
很久以前排序演算法的時間複雜度一直是o n 2 當時學術界充斥著 排序演算法不可能突破o n 2 的聲音,直到1959年,由d.l.shell提出了一種排序演算法,希爾排序 shell sort 才打破了這種不可能的聲音,把排序演算法的時間複雜度提公升到了o n 3 2 當科學家們知道這種 不可能 ...