算法导论笔记-第六章-堆排序

xiaoxiao2021-02-28  56

6.1 堆 堆是一个数组,也可以被看作近似的完全二叉树。树上的每一个结点都对应数组中的一个元素。除了最底层,该树是完全充满的。 可以用某一数组代表堆,其中包含两个属性: A.length 代表给出的数组元素的数目 A.heap-size 代表又多少个堆元素存储在该数组中 (树性质: 前提:近似完全二叉树,从左到右排序,i为某结点编号 其父结点为:i/2 左孩子:2i 右孩子:2i+1 ) 高度:该结点到叶结点最长简单路径上边的数目 (n个元的的堆,高度为[lg2](向下取整)) 叶结点下标:n表示数组存储的n个元素时,叶节点下标分别为[n/2]+1,[n/2]+2,[n/2]+3..... 最大堆:某个结点的值最大与其父结点相同。 //A[PARENT(i)] >=A[i] 最小堆:某个结点的值最小与其父结点相同。 //A[PARENT(i)] <=A[i] 6.2 维护堆的性质 MAX-HEAPIFY过程:时间复杂度为 O(lg n) 维护堆的关键。 伪代码 MAX-HEAPIFY(A,i) l=LEFT(i) r=RIGHT(i) if l<=A.heap-size and A[l]>A[i] largest = l else if r<=A.heap-size and A[r]>A[i] largest = r if largest != i exchange A[i] with A[largest] MAX-HEAPIFY(A,largest) C实现: int RIGHT(int i) { return 2 * i + 1; } int LEFT(int i){ return 2* i; } void MAX_HEAPIFY(int A[], int i) { int A_heap_size = 10; int l = LEFT(i); int r = RIGHT(i); int largest = i; if (l<=A_heap_size && A[l]>A[i]) { largest = l; } if (r<=A_heap_size && A[r]>A[largest] ){ largest = r; } if (largest != i) { int temp=A[i]; A[i] = A[largest]; A[largest] = temp; MAX_HEAPIFY(A,largest); } } BUILD-MAX-HEAP过程: 线性时间复杂度,功能时从无序的输入数据数组中构造一个最大堆。 伪代码: BUILD-MAX-HEAP(A) A.heap-size = A.length for i = [A.length/2] downto 1 MAX-HEAPIFY(A,i)dd C实现: void BUILD_MAX_HEAP(int A[],int length) { int A_heap_size = length; int i = length; for (i; i > 0; i--) { MAX_HEAPIFY(A, i, A_heap_size); } } HEAPSORT过程:时间复杂度为 O(lg n),功能时堆一个数组进行原址排序。 伪代码: HEAPSORT(A) BUILD-MAX-HEAP(A) for i=A.length downto 2 exchangeA[1] with A[i] A_heap-size-- MAX-HEAPIFY(A,1) C语言实现:void HEAPSORT(int A[],int length) { int A_heap_size = length; int i = length; BUILD_MAX_HEAP(A, A_heap_size); for (; i > 1; i--){ int temp = A[1]; A[1] = A[i]; A[i] = temp; A_heap_size--; MAX_HEAPIFY(A, 1, A_heap_size); } } MAX-HEAP-INSERT,HEAP-EXTRACT-MAX,HEAP-INCREASE-KEY,HEAP-MAXIMUM过程: 时间复杂度 O(lg n),功能时利用堆实现一个优先队列。
转载请注明原文地址: https://www.6miu.com/read-2621868.html

最新回复(0)