关闭

堆排序

标签: 数据结构算法
159人阅读 评论(0) 收藏 举报
分类:
  • 堆数据结构是一个完全二叉树,父结点值都大于子结点值(都小于子结点值)。
  • 用数组表示堆(0,...,size-1),根节点的下标为0,对于任意一个结点i,其左子结点为2*i+1, 右子结点为2*i+2。
  • 堆中最后一个非叶子结点的下标为size/2-1。

//例程中是建一个大头堆
template<typename T>
void adjustHeap(T data[], int start, int end)
{
	//沿着子结点下顺
	//start的左子结点为2*start+1,右子结点为2*start+2.
	for (int i = 2 * start + 1; i < end; ++i)
	{
		if (i < end - 1 && data[i] < data[i + 1])//这里需要注意一下i+1会不会越界
		{
			++i;//让i指向子结点中的较大者
		}
		if (data[i] < data[start]) //满足堆性质,不用调整
		{
			break;
		}

		//最大子结点与父结点交换
		T temp = data[start];
		data[start] = data[i];
		data[i] = temp;
		
		start = i;//start下顺,接着调整
	}
}


//将一个数组初始化为堆,从最后一个非叶子开始从下往上进行adjustHeap
template<typename T>
void buildHeap(T data[], int size)
{
	for (int start = size / 2 - 1; start >= 0; --start)
	{
		adjustHeap(data, start, size);
	}
}

template<typename T>
void heapSort(T data[], int size)
{
	//对数组建堆
	buildHeap(data, size);

	//将堆的第一个元素与最后一个元素交换,然后adjustHeap
	for (int i = size - 1; i > 0; --i)
	{
		T temp = data[0];
		data[0] = data[i];
		data[i] = temp;

		adjustHeap(data, 0, i);
	}

}

下面补充一个递归版的adjust_heap:

template<class T>
void adjust_heap(T heap[], int start, int end) //[start, end)
{
    int left = 2 * start + 1, right = 2 * start + 2;
    if (left < end)
    {
        int max_idx = left;
        if (right < end)
        {
            if (heap[left] < heap[right])
            {
                max_idx = right;
            }
        }
        if (heap[max_idx] <= heap[start])
        {
            return; //不用调整了,父节点最大
        }
        std::swap(heap[start], heap[max_idx]);
        adjust_heap(heap, max_idx, end);
    }
}


1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:8435次
    • 积分:569
    • 等级:
    • 排名:千里之外
    • 原创:47篇
    • 转载:9篇
    • 译文:0篇
    • 评论:3条
    文章分类