最小堆及堆排序
2016-05-18 01:01
369 查看
头文件.h:
源文件.cpp:
return ;}
主函数main.h:
#ifndef MINHEAP_H_INCLUDED #define MINHEAP_H_INCLUDED #define DefaultSize 20 //默认堆大小 class MinHeap { private: int *heap; //指向存放最小堆元素的数组 int currentSize; //最小堆中当前元素个数 int MaxHeapSize; //最小堆最多允许元素 void siftDown(int start,int over); //下浮函数,从start到数组中最后一个元素 下滑调整成为最小堆 void siftUp(int start); //上浮函数,从start到0逐步调整成为最小堆 public: MinHeap(int A[],int n); //构造函数,通过一个数组建堆 ~MinHeap(){delete []heap;} //析构函数 // new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[] bool Insert(const int &x); //将x插入到堆的合适位置 bool RemoveMin(int &x); //删除堆顶最小的元素,并保存到x值 bool IsEmpty()const //判断堆是否为空 {return (currentSize==0)?true:false;} bool IsFull()const //判断堆是否已满 {return (currentSize==MaxHeapSize)?true:false;} void MakeEmpty(){currentSize=0;} //置空堆 void Traverse(); //遍历堆 void HeapSort(int A[],int &n); //最小堆排序,按照从小到大的顺序排序 }; #endif // MINHEAP_H_INCLUDED
源文件.cpp:
#include "MinHeap.h" #include <iostream> using namespace std; //构造函数,通过传入的数组创建堆 MinHeap::MinHeap(int A[],int n) { currentSize=n; MaxHeapSize=(n>DefaultSize)?n:DefaultSize; heap=new int[currentSize]; //创建堆存储空间,并返回数组指针给堆指针 for(int i=0;i<n;i++) heap[i]=A[i]; //复制堆数组 int position=(currentSize-2)/2; //寻找最后一个非叶子节点 while(position>=0) //自底向上逐步扩大形成堆 { siftDown(position,currentSize-1); //局部从上到下下滑调整 position--; //向前移一位继续调整 } } //siftDown: 从结点start开始到数组最后一个元素(包括)为止,自上向下比较,如果子女的值小于父结点的值, // 则小的值上浮,继续向下层比较,这样将一个集合局部调整为最小堆 void MinHeap::siftDown(int start,int over) { int i=start,j=2*i+1,t; //j为i的左子女下标 while(j<=over) //j超过over则跳出循环 { if(j<over&&heap[j+1]<heap[j]) j++; //如果j没到over即说明i有右子女,若右子女较小,j指向右子女位置,最终j指向两子女中较小的位置 if(heap[i]<=heap[j]) break; //如果父结点比左右子树最小的值还小,则不做调整,循环终止 else { t=heap[i];heap[i]=heap[j];heap[j]=t; //否则交换两个结点的值 i=j;j=2*i+1; //i到j位置,j到j的左子女处 } } } //插入结点到已有的堆中,利用siftUp函数 bool MinHeap::Insert(const int& x) { if(currentSize==MaxHeapSize) return false; //堆满 heap[currentSize]=x; //将堆数组末尾插入x siftUp(currentSize); //传入当前要调整的结点位置 currentSize++; //堆的长度+1 return true; } //siftUp: 从start到数组下标为0 的元素位置,自下向上比较,子女的值小于父结点的值 // 父结点下沉,将集合调整为最小堆(将原先创建好的最小堆 与新的结点调整为新的最小堆) void MinHeap::siftUp(int start) { int j=start,i=(j-1)/2,t; //j=2*i+1;无论j为左/右子女位置,i=(j-1)/2 得到的始终是父结点下标 while(i>=0) { if(heap[i]<=heap[j]) break; //父结点值小,不调整,跳出循环 else { t=heap[i];heap[i]=heap[j];heap[j]=t; //插入结点小,与父结点交换 j=i;i=(j-1)/2; //j移到父结点i的位置,i到i的父结点 } } } //Remove删除堆顶最小的元素,将堆中最后一个元素移到堆顶,调用siftDown函数重新调整成最小堆 bool MinHeap::RemoveMin(int &x) { if(currentSize==0) return false; //堆空 x=heap[0]; //保存堆顶元素 heap[0]=heap[currentSize-1]; //将堆中最后一个元素移到栈顶 currentSize--; //堆的长度-1 siftDown(0,currentSize-1); //只要从0位置调整即可 return true; } void MinHeap::Traverse() { cout<<"遍历堆的结果:"; int i; for(i=0;i<currentSize;i++) cout<<heap[i]<<" "; cout<<endl; } <pre name="code" class="cpp">//最小堆,堆内部排序后得到的是从大到小的顺序 //最大堆,堆内部排序后得到的是从小到大的顺序//堆排序,用数组A保存从小到大的排序结果,n保存数组长度void MinHeap::HeapSort(int A[],int &n){ int t,i,j; for(i=currentSize-1;i>=0;i--) //堆里面最终得到的是从大到小的顺序 { t=heap[0];heap[0]=heap[i];heap[i]=t; siftDown(0,i-1); } for(i=currentSize-1,j=0;i>=0;j++,i--) A[j]=heap[i]; n=currentSize;
return ;}
主函数main.h:
#include <iostream> #include "MinHeap.h" using namespace std; #define Max 20 int main() { int A[Max],i=0,n,m,k; cout<<"请输入初始化堆的长度:"; cin>>n; cout<<"请输入要创建的堆的数据,以f6/ctrl+Z结束:"; for(i=0;i<n;i++) cin>>A[i]; MinHeap h(A,n); //初始化构造一个堆 h.Traverse(); cout<<"请输入要插入的结点:"; cin>>m; h.Insert(m); cout<<"插入结点后:"; h.Traverse(); h.RemoveMin(k); cout<<endl<<"删除的元素为: "<<k<<endl; cout<<"删除结点后:"<<endl; h.Traverse(); h.HeapSort(A,n); cout<<endl<<"排序后堆中元素(从大到小): "; h.Traverse(); cout<<endl<<"按从小到大顺序:"; for(i=0;i<n;i++) cout<<A[i]<<" "; cout<<endl; return 0; }
相关文章推荐
- 手把手教你使用startuml画用例图
- Bower : ENOGIT git is not installed or not in the PATH解决方法
- KVO、BLOCK、代理、通知
- webserver
- 软件开发——软技能(四、日志)
- 网络传输层的基本知识
- CSAPP lab2 bomb
- Java中的匿名内部类总结
- js中typeof和constructor
- Spring-android源码初探
- 练习26:if语句
- python 类型转换及一些内容编辑
- 各种图(流程图,思维导图,UML,拓扑图,ER图)简介
- 无法升级数据库,因为此版本的SQLServer不支持该数据库的非发布版本(539)“解决方案
- Autolayout第三方库Masonry的入门与实践
- Java中的抽象类
- U-Boot移植——设置SDRAM
- 【手游】梦幻西游手游 美术资源加密分析
- 面试经典题Handler机制回答
- 主机无法访问虚拟机Linux的apache