堆排序的实现与分及测试

来源:互联网 发布:手机渲染视频软件 编辑:程序博客网 时间:2024/05/16 08:09

头文件如下:

//《对于任何算法的分析,首先要进行具体的分析,这样才能下手:// 比如,可以通过图形具象化,代码实现一下,体验一下,任何时候// 都要尽量避免作抽象思维。》/*堆排序 * 1、将一个无序的序列构建成最大堆(构造初始堆): *1.1、从最后一个非叶子节点i开始,以此节点作为堆顶,构造堆; *1.2、将i-1作为下一个堆顶,构造堆; *1.3、分别以2*i和2*i+1为参数,对左右子节点进行递归; *1.4、退出条件是:递归的两个子节点序列号大于序列大小。 * 2、第一步骤中已经构造出一个符合定义的堆,下面完成排序: *2.1、交换堆顶元素和最后一个元素,并将无序序列大小减一; *2.2、由于上一步破坏了堆结构,所以需要重复第一步,重新构造堆。 *2.3、退出条件是:无序序列元素个数为1。 *算法的核心就是第一步:堆的构造。 */// 总结:// 参考网页:http://blog.csdn.net/morewindows/article/details/6967409//http://www.cnblogs.com/luchen927/archive/2012/03/08/2381446.html//http://blog.csdn.net/xiaoxiaoxuewen/article/details/7570621//http://www.cnblogs.com/heyuquan/archive/2014/07/22/heap-sort.html  排序算法的优化//http://www.cnblogs.com/gaochundong/p/complexity_of_algorithms.html 算法复杂度分析// 为何相比第一个网址里面实现的堆排序算法,我的算法对1000个数据排序都要1000毫秒呢?// 以后凡是实现的排序算法都要用数以万记的数据进行排序,并查看运行时间,并作以优化和进一步学习。// 看来仅仅会写一个一般的排序算法是完完全全不够的,一定要注意效率问题,特别是面试的时候处理大数据的问题。/* 代码实现后记: *1、建立初始堆的时候,堆是下往上的。 *2、调整堆的时候,是从上往下的。 */#ifndef HEAPSORT_H#define HEAPSORT_H#include "Common.h" void HeapAdjust( int *a, int i, int size); void Adjust_heap( vector<int> &v, int length, int i ); void build_heap( vector<int> &v, int length ); void heap_sort( vector<int> &v); void HeapSortCppTest();template<typename T>class Heap{private:vector<T> v;public:Heap(vector<T> &v);void heapSortAlgorithm(  );void buildHeap( );void adjustHeap( int len, int I );// 序号要从0开始,长度要从1开始void printHeap();void heapSet(vector<T> &v);};#endif

CPP文件如下:

#include "HeapSort.h"void HeapAdjust( int *a, int i, int size) //调整堆{int lChild = 2*i; //i的左孩子节点int rChild = 2*i+1;//i的右孩子节点int max = i;if( i <= size/2 ){if( lChild <= size && a[lChild] > a[max] ){ max = lChild;}if( rChild <= size && a[rChild] > a[max] ){max = rChild;}if( max != i ){int tmpChg = a[i];a[i] = a[max];a[max] = tmpChg;HeapAdjust(a,i,size);}}}void Adjust_heap( vector<int> &v, int length, int i ){int left = 2*i;int right = 2*i+1;int largest = i;int temp;while( left < length || right < length ){if( left < length && v[largest] < v[left] ){largest = left;}if( i != largest ){temp = v[largest];v[largest] = v[i];v[i] = temp;i = largest;left = 2*i;right = 2*i+1;}else{ break; }}}void build_heap( vector<int> &v, int length ){int i;int begin = length/2-1;for( i = begin; i>=0; i-- ){Adjust_heap(v,length,i);}}void heap_sort( vector<int> &v){int length =v.size();int temp;cout<<"before sorted:"<<endl;cout<<"size="<<v.size()<<" capacity="<<v.capacity()<<endl;for( int i = 0 ; i < length; i ++ ){cout<<v[i]<<" ";}cout<<endl;build_heap(v,length);while( length > 1 ){temp = v[length -1 ];v[length-1] = v[0];v[0] = temp;length--;Adjust_heap(v,length,0);}length =v.size();cout<<"after sorted:"<<endl;cout<<"size="<<v.size()<<" capacity="<<v.capacity()<<" length="<<length<<endl;for( int i = 0 ; i < length; i++ ){cout<<v[i]<<" ";}cout<<endl;}// 堆的调整要从以I为堆顶的元素开始// 然后依次,对其左右子堆进行队规的调整// 注意:只需要对发生变动了的左右子堆进行调整即可template<typename T>void Heap<T>::adjustHeap( int len, int I )// 序号要从0开始,长度要从1开始{int Left = 2*I + 1;int Right = 2*I + 2;int Largest = I;int countA = 0;if( Left < len || Right < len )//构造出大堆{//cout<<countA++<<" ";//printHeap();if( Right < len )// 避免越界{if( (*this).v[Right] > (*this).v[Largest]  ) {Largest = Right; } //左右子节点分别处理}if( Left < len ){if( (*this).v[Left] > (*this).v[Largest]  ) {Largest = Left;}}if( Largest != I ) {::swap<T>( (*this).v[Largest], (*this).v[I] );if( Largest == Left ) { adjustHeap( len, Left );}if( Largest == Right ) { adjustHeap( len, Right );}} }return;}template<typename T>void Heap<T>::buildHeap( ){int len = (*this).v.size();int I = len/2 - 1;for( int count = I; count >= 0; count-- ){ adjustHeap( len, count );}return;}template<typename T>void Heap<T>::heapSortAlgorithm( ){int Count = (*this).v.size();buildHeap( );for( ; Count > 0; ){::swap<T>( (*this).v[0], (*this).v[Count-1]);Count--;adjustHeap( Count, 0 );}return;}template<typename T>void Heap<T>::printHeap(){cout<<"The current heap is: "<<endl;for( int i =0; i < (*this).v.size(); i++ ) { cout<< (*this).v[i]<<" "; }cout<<endl;return;}//注意:1、拷贝构造函数和赋值构造函数的区别;//2、何时调用了拷贝函数。//3、拷贝构造函数和拷贝函数的区别。template<typename T>void Heap<T>::heapSet(vector<T> &v)//在此调用vector的拷贝构造函数{(*this).v=v;return;}template<typename T>Heap<T>::Heap(vector<T> &v){heapSet(v);}//测试代码:/**/void HeapSortCppTest(){clock_t tBegin,tEnd;vector<int> test(1000,8);for( int i =0; i < test.size(); i++ )test[i] = rand()%19999;/*test.push_back(10);test.push_back(5);test.push_back(8);test.push_back(2);test.push_back(17);test.push_back(77);test.push_back(71);test.push_back(72);test.push_back(37);test.push_back(47);test.push_back(67);test.push_back(97);test.push_back(723);test.push_back(71);test.push_back(723);test.push_back(74);test.push_back(71);test.push_back(70);test.push_back(79);*/Heap<int> heap(test);//heap.printHeap();tBegin = clock();heap.heapSortAlgorithm( );tEnd = clock();cout<<"The run time of heapSort is : "<<tEnd-tBegin<<"  ms"<<endl;//heap.printHeap();return;}

代码已测试,复制粘贴即可运行。

0 0