堆排序是一種樹形選擇排序方法,它的特點是:在排序的過程中,將array[0,...,n-1]看成是一顆完全二叉樹的順序儲存結構,利用完全二叉樹中雙親節點和孩子結點之間的內在關係,在當前無序區中選擇關鍵字最大(最小)的元素。
1. 若array[0,...,n-1]表示一顆完全二叉樹的順序儲存模式,則雙親節點指標和孩子結點指標之間的內在關係如下:
任意一節點指標 i:父節點:i==0 ? null : (i-1)/2
左孩子:2*i + 1
右孩子:2*i + 2
2. 堆的定義:n個關鍵字序列array[0,...,n-1],當且僅當滿足下列要求:(0 <= i <= (n-1)/2)
① array[i] <= array[2*i + 1] 且 array[i] <= array[2*i + 2]; 稱為小根堆;
② array[i] >= array[2*i + 1] 且 array[i] >= array[2*i + 2]; 稱為大根堆;
3. 建立大根堆:
n個節點的完全二叉樹array[0,...,n-1],最後乙個節點n-1是第(n-1-1)/2個節點的孩子。對第(n-1-1)/2個節點為根的子樹調整,使該子樹稱為堆。
對於大根堆,調整方法為:若【根節點的關鍵字】小於【左右子女中關鍵字較大者】,則交換。
之後向前依次對各節點((n-2)/2 - 1)~ 0為根的子樹進行調整,看該節點值是否大於其左右子節點的值,若不是,將左右子節點中較大值與之交換,交換後可能會破壞下一級堆,於是繼續採用上述方法構建下一級的堆,直到以該節點為根的子樹構成堆為止。
反覆利用上述調整堆的方法建堆,直到根節點。
4.堆排序:(大根堆)
①將存放在array[0,...,n-1]中的n個元素建成初始堆;
②將堆頂元素與堆底元素進行交換,則序列的最大值即已放到正確的位置;
③但此時堆被破壞,將堆頂元素向下調整使其繼續保持大根堆的性質,再重複第②③步,直到堆中僅剩下乙個元素為止。
堆排序演算法的效能分析:
空間複雜度:o(1);
時間複雜度:建堆:o(n),每次調整o(log n),故最好、最壞、平均情況下:o(n*logn);
穩定性:不穩定
建立大根堆的方法:
//構建大根堆:將array看成完全二叉樹的順序儲存結構
private int buildmaxheap(int array)
return array;
}//將元素array[k]自下往上逐步調整樹形結構
private void adjustdowntoup(int array,int k,int length)else
}array[k] = temp; //被調整的結點的值放人最終位置
}
堆排序:
//堆排序
public int heapsort(int array)
return array;
}
刪除堆頂元素(即序列中的最大值):先將堆的最後乙個元素與堆頂元素交換,由於此時堆的性質被破壞,需對此時的根節點進行向下調整操作。
//刪除堆頂元素操作
public int deletemax(int array)
對堆的插入操作:先將新節點放在堆的末端,再對這個新節點執行向上調整操作。
假設陣列的最後乙個元素array[array.length-1]為空,新插入的結點初始時放置在此處。
//插入操作:向大根堆array中插入資料data
public int insertdata(int array, int data)else
}array[k] = data; //將插入的結點放到正確的位置
return array;
}
測試:
public void tostring(int array)
}public static void main(string args);
system.out.print("構建大根堆:");
hs.tostring(hs.buildmaxheap(array));
system.out.print("\n"+"刪除堆頂元素:");
hs.tostring(hs.deletemax(array));
system.out.print("\n"+"插入元素63:");
hs.tostring(hs.insertdata(array, 63));
system.out.print("\n"+"大根堆排序:");
hs.tostring(hs.heapsort(array));
}
1 構建大根堆:122 87 78 45 17 65 53 9 32
2 刪除堆頂元素:87 45 78 32 17 65 53 9 -99999
3 插入元素63:87 63 78 45 17 65 53 9 32
4 大根堆排序:9 17 32 45 53 63 65 78 87
堆排序(大根堆)
堆排序是利用堆的性質進行的一種選擇排序。下面先討論一下堆。1.堆堆實際上是一棵完全二叉樹,其任何一非葉節點滿足性質 key i key 2i 1 key i key 2i 2 或者key i key 2i 1 key key 2i 2 即任何一非葉節點的關鍵字不大於或者不小於其左右孩子節點的關鍵字。...
堆排序 大根堆
include include using namespace std define max 100010 int heap max heap i 的孩子是 2 i 1 2 i 2 父親是 i 1 2 int heapsize 0 初始化堆的大小 void heapinsert int index ...
堆排序(大根堆 小根堆)
堆 堆實際上是一棵完全二叉樹,其任何一非葉節點滿足性質 key i key 2i 1 key i key 2i 2 或者key i key 2i 1 key key 2i 2 即任何一非葉節點的關鍵字不大於或者不小於其左右孩子節點的關鍵字。堆分為大頂堆和小頂堆,滿足key i key 2i 1 ke...