算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)
2017-12-04 16:50
495 查看
程序如下:
// heap_sort.cpp : 定义控制台应用程序的入口点。 // #include<iostream> #include<algorithm> using namespace std; #define N 1000 #define PARENT(i) (i)>>1 #define LEFT(i) (i)<<1; #define RIGHT(i) ((i)<<1)+1 class Heap { public: //成员变量 int A[N + 1]; int length; int heap_size; //构造与析构 Heap() {} Heap(int size) :length(size), heap_size(size) {} ~Heap() {} //功能函数 void Max_Heapify(int i); void Build_Max_Heap(); void HeapSort(int A[]); //优先队列函数 void Heap_Increase_Key(int i,int key); void Max_Heap_Insert(int key); int Heap_Maximum(); int Heap_Extract_Max(); void Heap_Delete(int i); //辅助函数 void Print(); void Print1(); }; //使以i结点为根结点的子树成为堆,调用条件是确定i的左右子树已经是堆,时间是O(lgn) //递归方法 void Heap::Max_Heapify(int i) { int l = LEFT(i); int r = RIGHT(i); int largest; //选择i、i的左、i的右三个结点中值最大的结点 if (l<heap_size&&A[l]>A[i]) largest = l; else largest = i; if (r<heap_size&&A[r]>A[largest]) largest = r; //如果根结点值最大,已经满足堆的条件,函数停止 //否则 if (largest != i) { //根结点与值最大的结点交换 swap(A[i],A[largest]); //交换可能破坏子树的堆,重新调整子树 Max_Heapify(largest); } } //建堆,时间复杂度O(nlgn) void Heap::Build_Max_Heap() { heap_size = length; //从中间开始依次向前调整每个结点,使得符合堆的性质 for (int i = length / 2; i >= 0; i--) Max_Heapify(i); } //堆排序,时间复杂度O(nlgn) void Heap::HeapSort(int A[]) { //建立一个最大堆 Build_Max_Heap(); //每次将前i个元素构成最大堆 for (int i = length - 1; i >= 1; i--) { //将前i个元素中的最大值存入到A[i]中 swap(A[0],A[i]); //堆的大小减一 heap_size--; //只有堆顶的性质可能会被破坏 Max_Heapify(0); } } //将元素i的关键字增加到key,要求key>=A[i] void Heap::Heap_Increase_Key(int i, int key) { if (key < A[i]) { cout << "new key is smaller than current key" << endl; exit(0); } A[i] = key; //跟父结点比较,若A[PARENT(i)]<A[i],则交换 //若运行到某个结点时A[PARENT(i)]>A[i],就跳出循环 while (A[PARENT(i)]>0 && A[PARENT(i)] < A[i]) { swap(A[PARENT(i)],A[i]); i = PARENT(i); } } //将key插入到集合A中 void Heap::Max_Heap_Insert(int key) { if (heap_size == N) { cout << "heap is full" << endl; exit(0); } heap_size++; length++; A[heap_size - 1] = -0x7fffffff; Heap_Increase_Key(heap_size - 1, key); } //返回A中最大关键字,时间O(1) int Heap::Heap_Maximum() { return A[0]; } //去掉并返回A中最大关键字,时间复杂度O(lgn) int Heap::Heap_Extract_Max() { if (heap_size < 0) { cout << "heap underflow" << endl; exit(0); } //取出最大值 int max = A[0]; //将最后一个元素补到最大值的位置 A[0] = A[heap_size - 1]; heap_size--; //重新调整根结点 Max_Heapify(0); //返回最大值 return max; } //删除堆中第i个元素 void Heap::Heap_Delete(int i) { if (i > heap_size) { cout << "there is no node i" << endl; exit(0); } //把最后一个元素补到第i个元素的位置 int key = A[heap_size - 1]; heap_size--; //如果新值比原来A[i]大,则向上调整 if (key > A[i]) Heap_Increase_Key(i,key); else//否则,向下调整 { A[i] = key; Max_Heapify(i); A[heap_size] = 0; } } void Heap::Print() { int i; for (i = 0; i < heap_size; i++) { if (i > 0)cout << ','; else cout << "==>A={"; cout << A[i]; } cout << '}' << endl; } void Heap::Print1() { int i; cout << "==>A={"; for (i = 0; i < length; i++) { if (A[i] > 0) { cout << A[i] << " "; } } cout << '}' << endl; } void main() { Heap a(13); a.A[0] = 1; a.A[1] = 9; a.A[2] = 10; a.A[3] = 2; a.A[4] = 7; a.A[5] = 5; a.A[6] = 6; a.A[7] = 4; a.A[8] = 13; a.A[9] = 3; a.A[10] = 18; a.A[11] = 11; a.A[12] = 100; a.Build_Max_Heap(); cout << "建立最大堆结果:" << endl; a.Print(); a.Heap_Delete(2); cout << "删除堆中A[2]结果:" << endl; a.Print(); a.Heap_Extract_Max(); cout << "取出堆中最大值后结果:" << endl; a.Print(); a.Heap_Increase_Key(8, 15); cout << "将A[8]值增加到15后结果:" << endl; a.Print(); a.Max_Heap_Insert(56); cout << "将值56插入最大堆后的结果:" << endl; a.Print(); a.HeapSort(a.A); cout << "堆排序结果:" << endl; a.Print1(); system("pause"); }执行结果:
相关文章推荐
- 算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)
- 算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)
- 算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)
- 算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)
- 算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)
- 算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)
- 算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)
- 程序员面试宝典(第三版)——单链表的基本操作:建立,求长度,输出,排序,插入,删除,逆置(转)
- 闭散列表的查找、插入和删除操作的完整C代码
- 程序员面试宝典(第三版)——单链表的基本操作:建立,求长度,输出,排序,插入,删除,逆置
- 自己写的顺序表的基本操作,插入、删除、修改,给出完整代码,其中运用到goto语句
- 单链表的基本操作,正序/逆序建表(尾插法/头插法)、计算单链表长度、输出单链表内容、插入、删除,给出完整代码
- 开散列表的查找、插入、删除操作的完整C代码
- 单链表的创建删除排序插入逆向打印各种操作
- 算法导论第三版--插入排序和归并排序
- java语言编写链表的基本操作(链表的创建,插入,删除,打印,排序)
- c#操作xml的代码(插入节点、修改节点、删除节点等)
- C++ 单链表的建立,插入数值,删除数值,排序,遍历,和分割操作
- 算法导论学习--红黑树详解之删除(含完整红黑树代码)
- Android的SQlite先天不足:删除 插入后主键不能自动排序 解决(附:SQlite开发的完整demo)