數組-堆排序

一、思路

數組可以抽象成一個堆結構。堆的深度爲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);
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章