数组-堆排序

一、思路

数组可以抽象成一个堆结构。堆的深度为log,由一个乱序数组变成一个堆数组时间复杂度为O(nlogn),堆顶元素是最值,每次从堆顶弹出一个元素,重复进行n-1次后,数组有序。

下面定义一些堆排序的相关操作:

  • HEAPIFY 建堆:把一个乱序的数组变成堆结构的数组,时间复杂度为 O(nlogn)。
  • HEAPPOP:从最大堆中取出最大值或从最小堆中取出最小值,并将剩余的数组保持堆结构,时间复杂度为 O(logn)。
  • HEAPSORT:借由 HEAPFY 建堆和 HEAPPOP 堆数组进行排序,时间复杂度为O(nlog n),空间复杂度为 O(1)。

堆结构的一个常见应用是建立优先队列(Priority Queue)。

void adjust(int arr[], int start, int n) { //将arr[start]做一次堆调整
	int temp = arr[start]; //暂存待调整的元素
	int i = 2 * start + 1; //start的左孩子
	while (i < n) { //存在左孩子时
		i = ((i + 1 < n) && arr[i + 1] > arr[i]) ? i + 1 : i; //右孩子存在并且更大
		if (arr[i] > temp) {
			arr[start] = arr[i];
			start = i; //start标记空洞元素位置
			i = 2 * i + 1;
		}
		else {
			break;
		}
	}
	arr[start] = temp;
}
void heapify(int arr[], int n) { //将一个乱序数组变成堆结构的数组
	int last = (n - 2) / 2; //最后一个非叶子结点
	while (last >= 0) {
		adjust(arr, last, n);
		last--;
	}
}
void heapPop(int arr[], int n) { //从堆中取出堆顶元素(置于末尾),并将剩余部分保持为堆结构,n为留在堆内元素个数。
	swap(arr[0], arr[n - 1]); //将堆顶元素从堆内移出
	adjust(arr, 0, n - 1);
}
void heapSort(int arr[], int n) { //升序 - 大根堆
	heapify(arr, n);
	for (int i = 0; i < n - 1; ++i) {
		heapPop(arr, n - i);
	}
}

 

你可能感兴趣的:(数据结构与算法,#,排序算法,#,数组)