堆排序,建立在堆这种结构上。一般的堆可以建立在数组上,但也可以用链表结构来表示。有序堆满足,每个节点的键值要比它所有孩子的键值都大。 #include <iostream> using namespace std; typedef double Elem; /* 自顶向下堆化(大根堆) fixDown(Elem* eArray, int k, int N) 问题功能描述: 假设原来的堆是有序的,只是位置k上的键值下降了,将位置k上的元素放到一个适当的位置上,使其满足堆的条件。 procedure (eArray, k , N) while (2 * k <= N) // 存在孩子节点,"="的时候只有一个孩子节点 { 找到键值较大的孩子节点的位置j(注意只有一个孩子节点的情况) if eArray[k] < eArray[j] { 交换位置k和位置j上的元素; 将k设置为j; //因为交换位置k和位置j上的元素之后,以位置j上的元素为根的堆变得无序了,所以继续堆化 } else { 当前位置k就是eArray[k]的最终位置; 跳出循环; } } */ inline bool Less(Elem& e1, Elem& e2) {return e1 < e2;} inline void Exch(Elem& e1, Elem& e2) { Elem e = e1; e1 = e2; e2 = e;} void FixDown(Elem* eArray, int k, int N) { int j = 2 * k; // 键值最大的孩子节点的位置 while (j <= N) { // 找到键值最大的孩子节点 if (j < N && Less(eArray[j], eArray[j+1])) { j++; } if (!Less(eArray[k], eArray[j])) { break; } Exch(eArray[k], eArray[j]); k = j; j = 2 * k; } } /* 堆排序 1、自底向上,自左向右构建堆 2、将第一个元素(键值最大)与最后一个元素交换,堆的元素数目减1,调整堆。 3、循环执行第2步,直到堆为空。 */ /*eArray 为元素数组(下标从1开始),totalNum为元数目*/ void HeapSort(Elem* eArray, int totalNum) { int const N = totalNum; // 构建堆 int k; for (k = totalNum / 2; k >= 1; k--) { FixDown(eArray, k, totalNum); } while (totalNum > 1) { Exch(eArray[1], eArray[totalNum]); FixDown(eArray, 1, --totalNum); } } int main() { Elem a[10] = {0, 1, 2, 9, 4, 8, 6, 7, 5, 3}; int totalNum = 9; cout << "未排序前的序列:" << endl; int i; for (i = 1; i < totalNum; i++) { cout << a[i] << ", "; } cout << a[totalNum] << endl; HeapSort(a, totalNum); cout << "排序之后的序列:" << endl; for (i = 1; i < totalNum; i++) { cout << a[i] << ", "; } cout << a[totalNum] << endl; return 0; }