排序方法总结(递归与非递归)
2016-03-20 19:43
260 查看
八大排序方法总结
<span style="font-size:18px;">#pragma once #ifndef _SORT_HEADER_ #define _SORT_HEADER_ #include<vector> using std::vector; //切记不要忘记 template<class T> void Swap(T& a, T& b) { T temp; temp = a; a = b; b = temp; } #define SAFE_DELETE(p) \ { \ if ((p) != NULL) \ { \ delete (p); \ (p) = NULL; \ } \ } #define ISEXIST(p) \ { \ if (nullptr == (p)) \ {return; } \ } typedef void(*Functype)(int* p, int len); //定义一个和排序函数相同类型的函数指针 void GetRandomVal(int* p, int len); void SortSelect(Functype pFunc, int* p, int len);//参数为一个函数指针类型 void PrintArray( const int* p, int len); void BulSort( int* p, int len); void InsertSort( int* p, int len); void SelectSort(int* p, int len); void InsertByStep(int* p, int len, int d); void ShellSort(int* p, int len, int* step, int count); int AdjustMiddle(int* p, int lest, int right); int Partation( int* p, int left, int right); void QuickSort( int* p, int left, int right); void UnCurQuickSort(int* p, int left, int right); void AdjustHeap(int *p, int len,int root); void HeapSort(int *p, int len); void MergeArray(int* p, int begin, int mid, int end); void MergeSort(int *p,int begin,int end); void UnCurMergeSort(int *p, int len); //一下为基数排序需要使用到的函数 void RadixSort(int *p,int len); void CollectBucket(int *p,vector<vector<int>>& Vec); int GetMaxCount(int *p,int len); int GetPosVal(int num, int nPos); #endif</span>
<span style="font-size:18px;"> </span>
<span style="font-size:18px;"> </span>
<span style="font-size:18px;">//以下为实现文件 </span>
<span style="font-size:18px;">#include"Sort.h" #include<ctime> #include<stdlib.h> #include<assert.h> #include<stack> #include<string> #include<iostream> using namespace std; void SortSelect(Functype pFunc, int* p, int len)//参数为一个函数指针类型 { pFunc(p,len); } void GetRandomVal(int* p, int len) { if (nullptr == p || len < 1) { return; } srand((unsigned int)time(0)); for (int i = 0; i < len; ++i) { p[i] = rand(); } } void PrintArray(const int* p, int len) { ISEXIST(p); if (len < 1) { return; } for (int i = 0; i < len; ++i) { cout << p[i]<<" "; } cout << endl; } //标准插入 可以改为没有 临时变量 有待思考 void InsertSort(int* p, int len) { ISEXIST(p); if (len < 1) { return; } int temp = p[0], j = 0; for (int i = 1; i < len; ++i) { temp = p[i]; for (j = i - 1; j >= 0 && p[j] > temp; --j) { p[j + 1] = p[j]; } p[j + 1] = temp; } } //标准冒泡 void BulSort(int* p, int len) { if (nullptr == p || len < 1) { return; } bool IsExchange = false; for (int i = 0; i < len; ++i) { IsExchange = false; for (int j = 0; j <len-i-1; --j) { if (p[j] > p[j + 1]) { Swap(p[j],p[j+1]); } IsExchange = true; } //PrintArray(p,len); if (!IsExchange) { break;//当前一趟 并未发生交换 } } } //标准选择排序 void SelectSort(int* p, int len) { if (nullptr == p || len < 1) { return; } int minIndex = 0; for (int i = 0; i < len-1; ++i)//只进行 len-1 趟 最后一个 为最大值 { minIndex = i; for (int j = i+1; j < len; ++j)//从i+1 开始 找比前边小的 { if (p[j] < p[minIndex]) { minIndex = j; } } if (i != minIndex) { Swap(p[i], p[minIndex]); } } } void InsertByStep(int* p, int len, int d) { if (nullptr == p || len < 1 || d >= len || d < 1) { return; } int temp=0,j=0; for (int i = d; i < len; ++i) { temp = p[i]; for (j = i - d; j >= 0 && p[j] > temp; j-=d) { p[j + d] = p[j]; } p[j + d] = temp; } } void ShellSort(int* p, int len, int* step, int count) { if (nullptr == p || nullptr == step || len < 0 || count < 0) { return; } for (int i = 0; i < count; ++i) { InsertByStep(p, len, step[i]); } } int Partation(int* p, int left, int right) { if (nullptr == p || left < 0 || right <= 0||left>right) { return -1; } AdjustMiddle(p,left,right); int i = left; int j = right; int key = p[left]; while (i < j) { while (i < j&&p[j] >= key)//寻找第一个 比key小的值 { --j; } p[i] = p[j]; while (i < j&&p[i] <= key)//寻找第一个 比key大的值 { ++i; } p[j] = p[i]; } //循环退出时 i==j 并且 被覆盖的值 应该在 i位置上 p[i] = key; return i; } int Partation1(int* p, int left, int right)//划分函数很重要 { int i = 0; int index = left; int temp = p[left]; int mid=AdjustMiddle(p, left, right); Swap(p[left],p[mid]);//将中间元素 作为轴值 Swap(p[index], p[right]);// index 与 right 调换 for (i = left; i<right; i++) { if (p[i]<temp) { Swap(p[index], p[i]);//遇到比基准值小就调换 index++;//基准位后移 } } Swap(p[index], p[right]);// index 与 right 调换 return index; } void QuickSort(int* p,int left,int right) { if (nullptr == p || left < 0 || right <= 0 || left >= right) { return; } int nIndex; if (left < right) { nIndex= Partation(p, left, right); QuickSort(p,left,nIndex-1); QuickSort(p,nIndex+1,right); } } void AdjustHeap(int *p, int len, int root) { if (nullptr == p || len < 0 || root < 0 || root >= len||2*root+1>=len) { return; } int temp = p[root];//保存更节点的值 int i = 2 * root + 1;//左孩子 while (i < len) { if (i + 1 < len&&p[i] < p[i + 1]) { ++i;//寻找两个孩子中 值较大的节点 } if (p[i] > temp) { p[(i - 1) / 2] = p[i];//将较大的节点 赋值给父节点 } else { break;//否则 已经是大根堆 退出 } i = 2 * i + 1;//向下移动 } p[(i - 1) / 2] = temp;//找到对应位置 放入 } //标准 堆排序 注意堆调整数组如果0位置空缺 则在排序时 会带来麻烦 void HeapSort(int* p, int len) { if (nullptr == p || len <= 1) { return; } int root = len/2-1;//可通过规律获得 for (int i = len/2; i>0; --i)//将无序堆 调整为有序堆 调整次数为 len/2 { AdjustHeap(p,len,root--); } for (int i = 0; i < len; ++i) { Swap(p[0],p[len-i-1]);//每次和最后一个元素交换 AdjustHeap(p,len-i-1,0);//每次堆调整 长度减1 } } void MergeArray(int* p, int begin, int mid, int end) { ISEXIST(p); if (begin < 0 || mid < 0 || end < 0 || begin > mid || mid > end) { return; } int i = begin, j = mid + 1;//mid位于 前半个数组 并且 end为下标 int k = 0; int* pTemp = new int[end-begin+1]; if (nullptr == pTemp) { throw "can not apply memory!";; } while (i <= mid&&j <= end) { if (p[i] < p[j]) { pTemp[k++] = p[i++]; } else { pTemp[k++] = p[j++]; } } while (i <= mid) { pTemp[k++] = p[i++]; } while (j <= end) { pTemp[k++] = p[j++]; } i = 0; while (i < k) { p[i+begin]=pTemp[i]; ++i; } delete[] pTemp; pTemp = nullptr; } void MergeSort(int *p, int begin, int end) { if (nullptr == p || begin < 0 || end<0)//等于号 很重要 { return; } if (begin < end) { int mid = (end + begin) / 2; MergeSort(p, begin, mid); MergeSort(p, mid + 1, end); MergeArray(p, begin, mid, end); } } void UnCurQuickSort(int* p,int left,int right) { assert(nullptr!=p); assert(left>=0&&right>=left); stack<int> SPos; int mid = Partation(p, left, right); if (left < mid - 1) { SPos.push(left); SPos.push(mid - 1); } if (mid + 1 < right) { SPos.push(mid + 1); SPos.push(right); } while (!SPos.empty()) { int high = SPos.top(); SPos.pop(); int low = SPos.top(); SPos.pop(); mid = Partation(p,low,high); if (low < mid - 1) { SPos.push(low); SPos.push(mid-1); } if (mid + 1 < high) { SPos.push(mid+1); SPos.push(high); } } } void UnCurMergeSort(int *p, int len) { assert(nullptr != p); assert(len>0); int start = 0; int step=1; while (step < len) { start = 0; while (start < len) { if (start + 2 * step -1 < len) { //需要注意mid是处于前半个区间的 并且都是闭区间 MergeArray(p,start,start+step-1,start+step*2-1); } //这个地方可能会出现两种情况 //1:最后只剩下一个step归并单元 这种情况不用再归并 //2:最后剩下一个step归并单元 和一个小于step归并单元 else if(start+step<len&&start+2*step>len) { //这个地方处理最后剩下一个半区间 MergeArray(p, start, start + step-1, len-1); } start += (step<<1); } step <<= 1; } } int AdjustMiddle(int* p, int left, int right) { //此函数调整快排过程中轴值得选择 避免恶化 assert(nullptr != 0); assert(left >= 0 && right >= 0 && left <= right); if (left == right) { return left; } int mid = (left + right) << 1; if (p[left] > p[mid]) { Swap<int>(p[left],p[mid]); } if (p[left] > p[right]) { Swap<int>(p[left], p[right]); } if (p[mid] > p[right]) { Swap<int>(p[mid], p[right]); } return mid; } //以下是基数排序使用的函数 void CollectBucket(int *p, vector<vector<int>>& Vec) { if (nullptr == p || Vec.empty()) { return; } int k = 0; for (size_t i = 0; i < Vec.size(); ++i)//表示从 0-9 { for (size_t j = 0; j < Vec[i].size(); ++j)//表示bucket中的元素个数 { p[k++] = Vec[i][j]; } Vec[i].clear(); } } void RadixSort(int *p, int len) { if (nullptr == p || len < 1) { return; } //vector <vector<int>> Vec(ncol, vector<int>(nrow,0)); ncol*nrow 二维数组 vector <vector<int>> Vec(10, vector<int>()); int count = GetMaxCount(p, len); for (int i = 0; i < count; ++i) { for (int j = 0; j < len; ++j) { Vec[GetPosVal(p[j], i)].push_back(p[j]); } CollectBucket(p, Vec); } } int GetMaxCount(int *p, int len) { if (nullptr == p || len < 1) { return -1; } //通过最大值 比较易懂 int count = 1, temp = 10; for (int i = 0; i < len; ++i) { while (abs(p[i]) >= temp)//注意可能有负数 { temp *= 10; ++count; } } return count; } int GetPosVal(int num, int nPos) { if (nPos < 0) { throw("parameter illegal!"); } int temp = _Pow_int(10, nPos); return (num / temp) % 10; }</span>
相关文章推荐
- python快速入门
- ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: YES)
- Phong和Blinn-Phong光照模型
- 《leetCode》:Contains Duplicate II
- hdu 4311 Meeting point-1 (快速求解曼哈顿距离和)
- iOS开发------实现图片下载缓存到本地
- Linux基础知识学习
- 两个解释动态规划问题非常直观形象的例子
- 广义后缀自动机与后缀树
- hud5040 InstrusiveBFS+优先队列
- JavaScript中的typeof和instanceof
- 不使用库函数实现字符串处理函数
- C语言-知识点及学习路线
- 构建之法前三章读后感
- 一元多项式及其运算
- Linux内核协议栈(2) 由简单的socket编程例子开始
- web前端的三个重要部分
- 【牛腩小试】——IIS配置
- 5-26单词长度
- 进程的概念