文章作者:姜南(Slyar) 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作。
n个关键字序列Kl,K2,…,Kn称为堆(Heap),当且仅当该序列满足如下性质(简称为堆性质):
ki≤K2i且ki≤K2i+1 或 Ki≥K2i且ki≥K2i+1(1≤i≤ n)
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。 (即如果按照线性存储该树,可得到一个不下降序列或不上升序列)
SLYAR整理了一下算法,用C语言实现,带注释。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
/* i为根节点,n为节点总数 */ void sift(int a[], int i, int n) { int child, tmp; for (tmp = a[i]; n >= 2 * i; i = child) { /* i的左孩子为2*i,右孩子为2*i+1 */ child = 2 * i; /* 让child指向孩子中较大的一个 */ if (child != n && a[child + 1] > a[child]) { child++; } /* 如果孩子节点大 */ if (tmp < a[child]) { /* 交换孩子节点和根节点 */ a[i] = a[child]; } else break; } /* 将根放在合适位置 */ a[i] = tmp; } /* 对a[1...n]进行排序 */ void heapsort(int a[], int n) { int i, tmp; /* 将a[1...n]建成大根堆 */ for (i = n / 2; i >= 1; i--) { sift(a, i, n); } /* 进行n-1趟排序 */ for (i = n; i >= 2; i--) { /* 交换堆顶元素和最后一个元素 */ tmp = a[1]; a[1] = a[i]; a[i] = tmp; /* 将a[1...i-1]重建为堆 */ sift(a, 1, i-1); } } |
转载请注明:Slyar Home » 堆排序(Heap Sort) 算法实现 C语言版