标签:
堆排序算法
一、基本思想:是一种属性排序选择方法,在排序过程中,将 R[1...n] 看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序区域中选择关键字最大(或最小)的记录。
二、C 语言代码:
1 /** 2 * 堆排序的关键是构造初始堆,这里采用筛选的算法建堆: 假若完全二叉树的某一个结点 i, 它的左子树、右子树已是堆, 接下来需要将 R[2i].key 3 *和 R[2i+i].key 之中的最大者与 R[i].key 作比较, 若 R[i].key 较小则将其与最大孩子的关键字交换, 这有可能破坏了下一级的堆, 于是继续采用 4 *上述方法构造下一级的堆, 直到完全二叉树中结点 i 构成堆为止. 对于任意一棵完全二叉树, 从 i = [n/2] ~ 1, 反复利用上述调整堆的方法构建堆, 5 *大者"上浮"小者被"筛选"下去, 筛选算法如下: 6 */ 7 8 //对 R[low...high] 进行筛选 9 void sift(RecType R[], int low, int high) 10 { 11 //R[j] 是 R[i] 的左孩子 12 int i = low; 13 int j = 2 * i; 14 RecType tmp = R[i]; 15 16 //若 j 在有效范围内 17 while (j <= high) { 18 //若右孩子较大, 则将 j 指向右孩子 19 if (j < high && R[j].key < R[j+1].key) { 20 j++; 21 //若 R[i].key 小于孩子中最大关键字 22 if (tmp.key < R[j].key) { 23 R[i] = R[j]; //将 R[j] 调整到双亲结点位置上 24 i = j; //修改 i 的值以便于继续向下筛选 25 j = 2 * i; //再次设置 R[j] 为 R[i] 的左孩子 26 } else { 27 break; 28 } 29 } 30 } 31 R[i] = tmp; //被筛选结点的值放入最终位置 32 } 33 34 /** 35 * 在初始堆(大根堆)构造完后, 根结点一定是最大关键字结点, 将其放到数序的最后, 也就是将堆中的根与最后一个叶子交换. 由于最大元素已归位, 36 *整个待排序的元素个数减少一个, 但由于根结点的改变, 这 n-1 个结点不一定为堆, 而其左子树和右子树均为堆, 调用一次 sift() 算法将这 37 *n-1 个结点调整成堆, 其根结点次大的元素, 将它放到数列的倒数第二个位置, 即将堆中根与最后一个叶子交换, 待排序的元素个数变为 n-2 个, 38 *再调整, 再将根结点归位, 如此这样直至完全二叉树只剩下一个根为止, 堆排序算法如下: 39 */ 40 41 void heapSort(RecType R[], int n) 42 { 43 int i; 44 RecType tmp; 45 46 //循环建立初始堆 47 for (i = n/2; i >= 1; i--) { 48 sift(R, i, n); 49 } 50 51 //进行 n-1 趟完成堆排序, 每一趟堆排序的元素个数减 1, 将最后一个元素同当前区间内的 R[1] 对换 52 for (i = n; i > 2; i--) { 53 tmp = R[1]; 54 R[1] = R[i]; 55 R[i] = tmp; 56 sift(R, 1, i-1); //筛选 R[i] 结点, 得到 i-1 个结点的堆 57 } 58 }
三、算法分析
时间复杂度:由算法代码可知,堆排序是由两个函数组成,第一个是 sift() 函数构建大根堆,第二个是 heapSort() 排序函数,对于 n 个排序记录而言,完全二叉树的高度为 log2(n+1),即 sift() 函数对于每个函数结点调整的时间复杂度是 O(log2n),而在 heapSort() 函数中两次循环的叠加为 (n/2 + n-1),故对于堆排序而言:
关键字比较和记录移动的最少次数是 (n/2 + n-1)log2n,算法的时间复杂度为 O(nlog2n)。
关键字比较和记录移动的最多次数为 (n/2 + n-1)log2n,算法的时间复杂度为 O(nlog2n)。
关键字平均比较和记录移动次数为 (n/2 + n-1)log2n,算法的时间复杂度为 O(nlog2n)。
空间复杂度:由算法代码可知,所需的额外空间只有一个 tmp 变量,故堆排序算法空间复杂度为 O(1)。
四、思考
堆排序的重点在于构造初始堆,那么,为什么一般要构造大根堆而不是小根堆?同时,当记录数较少时,为什么堆排序不合适?
标签:
原文地址:http://www.cnblogs.com/lishiyun19/p/4319622.html