您的位置:首页 > 编程语言 > C语言/C++

排序算法之堆排序

2014-06-07 15:29 169 查看
堆排序

最差时间复杂度
最优时间复杂度
平均时间复杂度
最差空间复杂度
 total, 

auxiliary
堆排序(Heapsort)是指利用这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。——堆排序.维基百科



(图片引自维基百科)

个人理解的堆排序:欲对data[0,size)进行堆排序,1)对数组建大根堆(或小根堆),使之符合堆序性(父节点恒大于子节点)与结构性(完全二叉树);2)将根节点(最大元素)与未有序的最后一个节点i交换,交换后data[i,size)已有序;3)将根节点下滤以恢复大根堆的堆序性;4)回到步骤2),直至未有序部分只剩一个节点。

在建大根堆时,有两种方法:1)为满足堆序性从最后一个内部节点开始将全部内部节点下滤;2)从第一个节点开始将全部节点上滤以满足堆序性。其中,方法1)时间复杂度为∑height(i),方法二的时间复杂度为∑depth(i)。在二叉树结构中高度小(深度大)的节点更多,复杂度为高度和的方法1)在效率上更好一些。

算法代码:

inline int parent(int i) {return ((i) - 1) >> 1;}
inline int leftChild(int i) {return ((i) << 1) + 1;}
inline int rightChild(int i) {return ((i) << 1) + 2;}

void heapSort(int data[], int size)
{ /* 对data[]进行堆排序 */
void buildMaxHeap(int[], int);
void percolateDown(int[], int, int);

/* 建大根堆 */
buildMaxHeap(data, size);

while (size)
{
/* 将第一个元素与未排序的最后一个元素交换 */
int max = data[0];
data[0] = data[size - 1];
data[size - 1] = max;

/* 将交换后的第一个元素下滤以恢复大堆堆序性 */
percolateDown(data, --size, 0);
}
}

void buildMaxHeap(int data[], int size)
{ /* 建大根堆 */
void percolateDown(int[], int, int);

/* 从最后一个内部节点开始,将所有内部节点下滤 */
for (int i = parent(size - 1); i >= 0; i--)
{
percolateDown(data, size, i);
}
}

void percolateDown(int data[], int size, int index)
{ /* 将序号为index的元素下滤以恢复大根堆堆序性 */
int maxChild;
int tmp = data[index];
while (leftChild(index) < size)
{
maxChild = (rightChild(index) < size && data[leftChild(index)] < data[rightChild(index)]) ? rightChild(index) : leftChild(index);
if (tmp >= data[maxChild])
{
break;
}
data[index] = data[maxChild];
index = maxChild;
}
data[index] = tmp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序算法 c++ 堆排序