[算法导论] 快速排序以及最大堆的C++实现
2013-02-16 14:49
656 查看
前言
重读了经典的<<算法导论>>时,我把书上的部分代码用C++实现,然后与自己之前写的代码对比一下,不禁为<<导论>>中算法实现的精简和优美所折服。今天把代码堆出来,以备不时之需。快速排序
/* * 2013-02-02 22:20 mingspy 算法导论 */ #pragma once #include <iostream> #include <time.h> #include <stdlib.h> using std::cout; using std::endl; namespace alg_intro{ /************************************************************************** *快速排序 - 递归方法 *对数组A[r, q]进行快速排序 *QuickSort(A, r, q) *{ * if (r >= q) return; * t <- Patition(A, r, q); //对数据分区 * QuickSort(A, r, t - 1); //排序左半边 * QuickSort(A, t + 1, q); //排序右半边 *} * *int Patition(A, r, q) *{ * i = r - 1; * FOR j <- r to q - 1 { //选择最后一个作为中值 * IF A[j] < A[q] THEN * i <- i + 1 * A[i]<->A[j] //交换 * } * * i <- i + 1 * A[i]<->A[q] * return i; *} */ long recall_times = 0; template<class T> void InsertSort(T * data,long r, long q) { for(int i = r+1; i <= q ; i++){ T t = data[i]; int j = i; for(; j > 0 && t < data[j - 1]; j --) data[j] = data[j - 1]; data[j] = t; } } template<typename T> long Patition(T * data, long r, long q) { long i = r - 1; for(long j = r; j < q ; j++){ if (data[j] < data[q]){ i++; Swap(data, i, j); } } i++; Swap(data, i, q); return i; } template<typename T> long RandomPatition(T *data, long r, long q) { long len = q - r + 1; long p = r + (Random() % len); Swap(data, q, p); return Patition(data, r, q); } template<typename T> void QuickSort(T * data, long r, long q) { //recall_times ++; if (r >= q) return; if(q - r < 16){ InsertSort(data, r, q); return; } long t = RandomPatition(data, r, q); QuickSort(data, r, t - 1); QuickSort(data, t + 1, q); } template<typename T> void Print(T * data, long len) { for (long i = 0; i < len; i ++ ) cout<<data[i]<<" "; cout << endl; } } int main(void) { int len = 20000000; int * data = new int[len]; for(int i = 0; i < len; i ++){ data[i] = alg_intro::Random(); } //alg_intro::Print(data, 100); time_t start = time(0); alg_intro::QuickSort(data, 0, len - 1); time_t end = time(0); cout << "sort "<<len <<" data used " << (end - start)<<"s" <<" call quick "<<alg_intro::recall_times<<endl; //alg_intro::Print(data, 100); delete []data; puts("Press Enter to quit!"); getchar(); return 0; }
最大堆及堆排序
/* * 2013-02-04 23:15 mingspy 算法导论 */ #pragma once #include <iostream> #include <assert.h> #include "alg_utilies.h" namespace alg_intro{ /* * 获取堆数组左孩子节点下标, 下标0处也存放数据 */ inline int Left(int i) { return (i<<2) + 1;} /* * 获取堆数组右孩子节点下标, 下标0处也存放数据 */ inline int Right(int i) {return (i<<2) + 2;} /* * 获取堆数组父节点下标, 下标0处也存放数据 */ inline int Parent(int i) { return (i+1)>>2;} /* *最大堆,A[Parent(i)]>=A[i] */ template<typename T> class MaxHeap{ public: MaxHeap(int cap):size(0), capability(cap){ A = new T[cap]; } MaxHeap(const T * A, int len):size(len), capability(len){ A = new T[len]; memcpy(A, arr, len * sizeof(T)); } ~MaxHeap(){ delete [] A; A = 0; } /* * Max-Heapify(A, i) 保持i节点最大堆的性质, 注意书上A[1...n] * l <- LEFT(i) * r <- RIGHT(i) * if l<= heap-size[A] and A[l] > A[i] * then largest <- l * else largest <- i * if r <= heapsize(A) and A[r] > A[largest] * then largest <- r * if largest != i * then exchange A[i]<->A[largest] * Max-Heapify(A, largest) */ void Heapify(int i){ int l = Left(i); int r = Right(i); int largest = i; if ( l < size && A[l] > A[largest]){ largest = l; } if ( r < size && A[r] > A[largest]){ largest = r; } if ( i != largest){ Swap(A, i, largest); Heapify(largest); } } void HeapifyUp(int i){ int parent; while (i > 0 && A[(parent=Parent(i))] < A[i]){ Swap(A, i, parent); i = parent; } } /* * Build-Max-Heap(A) 构建最大堆 A[1...n] * heap-size[A] <- length[A] * for i <- foot[length[A]/2] downto 1 * do Max-Heapify(A,i); */ void Build(){ if ( size == 0) return; for (int i = (size - 1) / 2; i >= 0; i--){ Heapify(i); } } /* *HeapSort(A) 堆排序 A[1...n] * Build-Max-Heap(A) * for i <- length[A] down to 2 //从最后一个元素开始 * do exchange A[1] <->A[i] //把最大元素交换到i * heap-size[A] <- heap-size[A] - 1 // * Max-Heapify(A, i) //重建堆 */ void Sort() { if(size == 0) return; size_t tmpSize = size; Build(); for (int i = --size; i > 0; i--) { Swap(A, i, 0); --size; Heapify(0); } size = tmpSize; } bool Empty() { return size == 0;} /* * Heap-Maximum(A) 返回最大值 A[1...n] * return A[1] */ T GetMax(){ assert (size > 0); //or不做判断,由外部进行Empty()判断 return A[0]; } /* *Heap-Extract-Max(A) 删除最大值 A[1...n] * 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; */ T ExtractMax(){ assert (size > 0); T max = A[0]; A[0] = A[--size]; Heapify(0); return max; } /* *Heap-Increase-Key(A, i, key) 变化A[i]处的值为更大的值 * if key < A[i] * then error "new key is smaller" * A[i] <- Key * while i > 1 and A[Parent(i)] < A[i] * do exchange A[i] <-> A[Parent(i)] * i <- Parent(i) */ void IncreaseKey(int i, T key){ assert(i>=0 && i < size); assert(A[i] < key); A[i] = key; HeapifyUp(i); } /* *Max-Heap-Insert(A,key) * heap-size[A] <- heap-size[A] + 1 * A[heap-size[A]] <- -INFINITY * Heap-Increase-Key(A, heap-size[A], key) */ void Insert(T key){ assert(size + 1 < capability); A[size] = key; HeapifyUp(size); size ++; } private: size_t size; // 当前大小 size_t capability; // 最大大小 T * A; }; } void Test_MaxHeap() { alg_intro::MaxHeap<int> heap(10); heap.Insert(0); heap.Insert(9); heap.Insert(5); heap.IncreaseKey(1, 10); heap.Insert(20); std::cout<<"20 20 10 9 5 =>if next line is same as these number, correct!"<<std::endl; std::cout<<heap.GetMax(); while(!heap.Empty()){ std::cout<<" "<<heap.ExtractMax(); } std::cout<<std::endl; }
最小堆
template<typename T> class MinHeap{ public: MinHeap(int cap = 10):_size(0), _capability(cap){ A = new T[cap]; } MinHeap(const T * A, int len):_size(len), _capability(len){ A = new T[len]; memcpy(A, arr, len * sizeof(T)); } MinHeap(const MinHeap & r):_size(r._size), _capability(r._capability){ A = new T[r._capability]; memcpy(A, r.A, r._capability * sizeof(T)); } ~MinHeap(){ delete [] A; A = 0; } /* * Max-Heapify(A, i) A[1...n] * l <- LEFT(i) * r <- RIGHT(i) * if l<= heap-size[A] and A[l] > A[i] * then largest <- l * else largest <- i * if r <= heapsize(A) and A[r] > A[largest] * then largest <- r * if largest != i * then exchange A[i]<->A[largest] * Max-Heapify(A, largest) */ void Heapify(int i){ int l = Left(i); int r = Right(i); int smallest = i; if ( l < _size && A[l] < A[smallest]){ smallest = l; } if ( r < _size && A[r] < A[smallest]){ smallest = r; } if ( i != smallest){ Swap(i, smallest); Heapify(smallest); } } void HeapifyUp(int i){ int parent; while (i > 0 && A[i] < A[(parent=Parent(i))]){ Swap(i, parent); i = parent; } } /* * Build-Max-Heap(A) A[1...n] * heap-size[A] <- length[A] * for i <- foot[length[A]/2] downto 1 * do Max-Heapify(A,i); */ void Build(){ if ( _size == 0) return; for (int i = (_size - 1) / 2; i >= 0; i--){ Heapify(i); } } /* *HeapSort(A) A[1...n] * Build-Max-Heap(A) * for i <- length[A] down to 2 // * do exchange A[1] <->A[i] // * heap-size[A] <- heap-size[A] - 1 // * Max-Heapify(A, i) // */ void Sort() { if(_size == 0) return; size_t tmpSize = _size; Build(); for (int i = --_size; i > 0; i--) { Swap(i, 0); --_size; Heapify(0); } _size = tmpSize; // reverse int mid = _size / 2; for(int i = 0; i < mid ; i++){ Swap(i, _size - 1 - i); } } bool Empty() { return _size == 0;} /* * Heap-Maximum(A) * return A[1] */ T & GetMin(){ assert (_size > 0); // return A[0]; } T & Get(int idx){ assert (_size > 0); // return A[idx]; } /* *Heap-Extract-Max(A) A[1...n] * 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; */ T RemoveMin(){ assert (_size > 0); T min = A[0]; A[0] = A[--_size]; Heapify(0); return min; } /* *Heap-Increase-Key(A, i, key) * if key < A[i] * then error "new key is smaller" * A[i] <- Key * while i > 1 and A[Parent(i)] < A[i] * do exchange A[i] <-> A[Parent(i)] * i <- Parent(i) */ void IncreaseKey(int i, const T & key){ assert(i>=0 && i < _size); A[i] = key; HeapifyUp(i); } /* *Max-Heap-Insert(A,key) * heap-size[A] <- heap-size[A] + 1 * A[heap-size[A]] <- -INFINITY * Heap-Increase-Key(A, heap-size[A], key) */ void Insert(const T & key){ assert(_size < _capability); A[_size] = key; HeapifyUp(_size); _size ++; } size_t size() const{ return _size; } /* * add key only if key is letter than * A[_size] when the heap is full. * useful when do NPath. */ void ConditionAdd(const T & key){ if(_size < _capability){ A[_size] = key; HeapifyUp(_size); _size ++; }else if(key < A[_size - 1]){ A[_size - 1] = key; HeapifyUp(_size - 1); } } private: inline void Swap(int i, int j) { T t = A[i]; A[i] = A[j]; A[j] = t; } size_t _size; // size_t _capability; // T * A; };
相关文章推荐
- 完整的C++实现算法导论十三章红黑树以及十四章中的顺序统计树
- 基于算法导论6.5用最大堆实现的优先队列(C++)
- C++快速排序实现(quicksort) (算法导论)
- C++最大堆实现priority_queue优先级队列(算法导论)
- 算法导论 4.1-5 最大子数组问题 线性时间算法 C++简单实现
- 【算法导论】用C++实现快速排序
- C++ 快速排序实现(算法导论)
- 【算法导论】c++实现的随机化的快速排序
- [算法导论-分治策略]求最大子数组之各种解法及源代码实现
- 快速排序(算法导论实现)
- 为算法考试做准备--快速排序以及找第K大数的实现
- GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现
- 快速排序(快排)算法的C++两种实现
- 算法导论-第23章-最小生成树:Prime算法(基于vector)的C++实现
- 【算法导论】c++实现计数排序
- Java实现算法导论中求解模线性方程解(基于最大公约数欧几里得扩展算法)
- 算法设计之,堆,堆排序,基于最大堆的最大优先队列的实现(C++实现)
- 【算法导论】22.3 图的深度优先搜索-C++实现
- 快速排序的C#实现以及,算法导论上之后一个习题的思考
- Java实现算法导论中最大公约数欧几里得算法