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

第六章 堆排序

 

总结:这章主要讲了堆、建堆、堆排序、优先级队列等。

 

1.   

堆可以被视为一颗完全二叉树,底层用数组实现。

length[A]: 数组中的元素个数

heap-size[A]: 存放在A中的堆的元素个数

树的根A[1]

给定某个结点的下标i:

父节点PARENT(i)=[i/2]

左节点LEFT(i)=2i

右节点RIGHT(i)=2i+1

最大堆:A[PARENT(i)] >= A[i]

最小堆A[PARENT(i)] <= A[i]

 

2.    保持堆的性质

MAX-HEAPIFY(A, i)

输入数组A,下标i,假设以LEFT(i)RIGHT(i)为根的两颗二叉树都是最大堆,要使以A[i]为根的二叉树也是最大堆。

分析:复杂度O(lgn)

 

伪代码

MAX-HEAPIFY(A, i)

l <- LEFT(i)

r <- RIGHT(i)

largest <- i

if l<=heap-size[A] and A[l]>A[largest]

      then largest <- l

if r<=heap-zise[A] and A[r]>A[largest]

      then largest <- r

if largest != i

      then exchange A[i] <-> A[largest]

           MAX-HEAPIFY(A, largest)

 

3.    建堆

BUILD-MAX-HEAP(A)

将数组A变为最大化堆

自底向上建堆,子数组A[(n/2)+1, …, n]中的元素都是树中的叶子

分析:复杂度O(n)

 

伪代码

BUILD-MAX-HEAP(A)

heap-size[A] <- length[A]

for i <- (length[A]/2) downto 1

       MAX-HEAPIFY(A, i)

 

4.    堆排序算法HEAPSORT(A)

A进行排序,从小到大输出

分析:O(nlgn)

 

伪代码

HEAPSORT(A)

BUILD-MAX-HEAP(A)

for i <- length[A] downto 2

do exchange A[1] <-> A[i]

heap-size[A] <- heap-size[A]-1

           MAX-HEAPIFY(A, 1)

 

5.    优先队列

可以用堆实现

 

1)       HEAP-MAXIMUM(A)

返回A中的最大值

分析:O(1)

 

伪代码

HEAP-MAXIMUM(A)

return A[1]

 

2)       HEAP-EXTRACT-MAX(A)

去掉A中的最大值

分析:O(lgn)

 

伪代码

HEAP-EXTRACT-MAX(A)

if heap-size[A] < 1

      then error “heap underflow”

max <- A[1]

A[1] <- A[heap-size[A]]

heap-size[A] <- heap-size[A]-1

MAX-HEAPIFY(A, 1)

return max

 

3)       HEAP-INCREASE-KEY(A, i, key)

A[i]的值增加为key,人要保持最大堆的特性

分析:O(lgn)

 

伪代码

HEAP-INCREASE-KEY(A, i, key)

if key < A[i]

      then error “new key is smaller than the current key”

A[i] <- key

while i>1 and key > A[PARENT(i)]

      do exchange A[i] <-> A[PARENT(i)]

           i <- PARENT(i)

 

4)       MAX-HEAP-INSERT(A, key)

key插入到A

分析:O(lgn)

 

伪代码

MAX-HEAP-INSERT(A, key)

heap-size[A] <- heap-size[A]+1

A[heap-size[A]] <- 负无穷大

HEAP-INCREASE-KEY(A,heap-size[A],key)

最大堆的C++实现

#include <iostream> using namespace std; void exchange(int &a, int &b) { int temp=a; a=b; b=temp; } template<class T> class maxHeap { private: T *heap; int heapSize; int maxSize; public: maxHeap(int sz=10):heapSize(0),maxSize(sz){heap=new T[sz+1];} //构造函数 maxHeap(T a[],int n,int sz); //带有堆的初始值的构造函数 ~maxHeap(){delete [] heap;} void buildHeap(int n);//建立最大化堆,对大小为n void heapify(int i);//建立以下标i为根的最大化根,且假设该节点的左右子树都是最大化根 void insert(const T x); void deleteMax(); int isEmpty(){return (heapSize==0);} int isFull(){return heapSize==maxSize;} void heapSort();//堆排序,破坏了堆的特性 }; template <class T> maxHeap<T>::maxHeap(T a[], int n, int sz) { maxSize=sz; heapSize=n; heap = new T[sz+1]; for(int i=0;i<n;i++) heap[i]=a[i]; buildHeap(heapSize); } template <class T> void maxHeap<T>::heapify(int i) { int left=2*i+1; int right=2*i+2; int largest=i; if(left<heapSize && heap[largest]<heap[left]) largest=left; if(right<heapSize && heap[largest]<heap[right]) largest=right; if(largest!=i) { exchange(heap[i],heap[largest]); heapify(largest); } } template <class T> void maxHeap<T>::buildHeap(int n) { heapSize=n; for(int i=(heapSize/2);i--;i>0) heapify(i); } template <class T> void maxHeap<T>::insert(const T x) { if(isFull()) return; heapSize++; int i=heapSize-1; heap[i]=x; int parent=((i-1)/2); while(i>0 && x>heap[parent]) { exchange(heap[i],heap[parent]); i=parent; parent=((i-1)/2); } } template <class T> void maxHeap<T>::deleteMax() { if(isEmpty()) return; heap[0]=heap[heapSize-1]; heapSize--; heapify(0); } template <class T> void maxHeap<T>::heapSort() { if(isEmpty()) return; int t=heapSize; while(heapSize>0) { exchange(heap[0],heap[heapSize-1]); heapSize--; heapify(0); } for(int i=0;i<t;i++) cout << heap[i] << " "; cout << endl; } int main() { int A[10]={3,6,4,8,9,12,34,13,2,10}; maxHeap<int> h(A,10,15); h.heapSort(); h.buildHeap(10); //重新建堆 h.insert(15); h.heapSort(); h.buildHeap(11); h.deleteMax(); h.heapSort(); while(1); }

你可能感兴趣的:(算法,delete,Class,ini,insert,Exchange)