睡不著覺起來尋思尋思幹點啥吧,好像好久沒寫堆排了。於是寫了個索引從0開始的堆排,這次把建堆函式略了並在heapsort主函式裡,索引從0開始到size-1結束,長度size。
這個堆排和索引從1開始的堆排區別就是對於節點i,兩個子節點分別為2i+1和2i+2。另外建堆時從索引size/2-1開始倒序維護大頂堆。下面證明下這個起始索引的節點一定對應著二叉樹的最後的乙個或兩個葉子節點。
1.siz是偶數,那麼最後乙個內部節點只有左子樹。siz/2-1乘2等於siz-2,siz-2加1為最後乙個節點的索引,是siz-1末尾沒問題。
2.siz是奇數,最後乙個內部節點有左右子樹。siz/2-1乘2等於((siz-1)/2-1)乘2等於siz-1-2等於siz-3,那麼左子節點siz-3+1=siz-2,右子節點siz-3+2=siz-1是末尾也沒問題。
void
max_heap
(vector<
int>
& nums,
int i,
int limit)
;void
heap_sort
(vector<
int>
& nums)
for(
int i =
1; i < nums.
size()
;++i)
}void
max_heap
(vector<
int>
& nums,
int i,
int limit)if(
2* i +
2< limit and nums[
2* i +2]
> nums[max_index])if
(i != max_index)
}
最近演算法群裡有人問堆排序的問題,我一想沒想出來,就又看看演算法導論堆排那章,跟著敲了一遍,感覺印象算是深刻了一些。
堆排序的幾個函式:
首先我們陣列從1開始編號,為了方便。即i為父節點,nums[i]的左右孩子分別為2i和2i+1,算算對不?這個函式假設i的左右子樹都已經為最大堆,只有nums[i]這個根節點可能有問題,下面上**:
void maxheap(vector& nums,int i,int limit)
//把以ri為根的子樹調整為最大堆,假設其左右子樹都已是最大堆
}
c的陣列下標0開始的,那麼我們前面插個0(插幾都行),然後對1~n進行堆排序。
siz/2是最後乙個非葉節點(就是編號最大的非葉節點),畫個圖好理解的,這就不提了。然後從這個節點開始依次往1靠,每次都把這個節點作為根節點的樹變成最大堆,最後整個1~n就是最大堆了。
這個更簡單了:
void heapsort(vector& nums)
}
先建最大堆,然後把nums[1]和nums[n]交換,然後對nums[1,n-1]繼續maxheap,就是每次調整為最大堆,最大的就是第乙個元素,把它和當前堆排序區間的末尾元素交換,這樣迴圈n-1次就排好了(剩乙個最小的就不用排了)。
c++:
#include#include#includeusing namespace std;
void maxheap(vector& nums,int i,int limit)
//把以ri為根的子樹調整為最大堆,假設其左右子樹都已是最大堆
}void heapsort(vector& nums)
}int main()
{int l=100;
srand(time(null));
vectorp(l,0);
for(int i=0;ipython:
import random
data_list=
for i in range(100):
def max_heapify(data_list,i,limit):
temp=i
if 2*i<=limit and data_list[temp]>data_list[2*i]:
temp=2*i
if 2*i+1<=limit and data_list[temp]>data_list[2*i+1]:
temp=2*i+1
if temp!=i:
data_list[temp],data_list[i]=data_list[i],data_list[temp]
max_heapify(data_list,temp,limit)
def create_heap(data_list):
list_len=len(data_list)
data_list.insert(0,0)
for i in range((list_len-1)//2,0,-1):
max_heapify(data_list,i,list_len-1)
def heap_sort(data_list):
create_heap(data_list)
list_len=len(data_list)
for i in range(1,list_len-1):
data_list[1],data_list[list_len-i]=data_list[list_len-i],data_list[1]
max_heapify(data_list,1,list_len-i-1)
heap_sort(data_list)
for i in data_list:
print(i)
堆排序演算法(C 實現)
在軟體設計相關領域,堆 heap 的概念主要涉及到兩個方面 一種是資料結構,邏輯上是一顆完全二叉樹,儲存上是乙個陣列物件 二叉堆 另一種是垃圾收集儲存區,是軟體系統可以程式設計的記憶體區域。堆排序的時間複雜度是 堆排序 堆排序是一種選擇排序。是不穩定的排序方法。時間複雜度為o nlog2n 堆排序的...
堆排序演算法的實現
1.實現了乙個大根堆類。為方便呼叫定義成了static靜態類成員函式。沒有資料成員變數。乙個建堆函式,乙個調整函式。include stdafx.h 定義兩個有參巨集來尋找陣列中的數之間的關係 define left x 2 x 1 獲得左節點在陣列中的下標 define right x 2 x 1...
排序演算法的C語言實現 堆排序
堆 優先佇列 可以用於花費nlogn 時間的排序,基於該想法的演算法叫做堆排序。因為堆的根總是最大的或者最小的,所以我們可以先將輸入陣列轉換為最大或者最小堆,然後刪除最大 最小值 也就是刪除根。這在二叉堆的介紹中已經實現了。一種方法是將刪除的元素放入另乙個陣列,但是這樣會浪費一倍的記憶體空間。由於每...