常见的排序算法

来源:互联网 发布:js监听离开当前页面 编辑:程序博客网 时间:2024/06/05 02:35
//直接插入排序void InsertSort(int *a, size_t n)//将一个数插入到一个有序区间中{assert(a);for (size_t i = 0; i < n - 1; i++){int end = i;int tmp = a[end + 1];for (end; end >= 0; end--){if (a[end] > tmp){a[end + 1] = a[end];}else{break;}}a[end + 1] = tmp;}}//shell排序void ShellSort(int *a, size_t n){int gap = n;while (gap > 1){gap = gap / 3 + 1;//预排序,将整体变得大概有序,最后当gap=1时就是直接插入排序,前面所做的预排序是为直接插入排序做铺垫。for (size_t i = 0; i < n - gap; i++){int end = i;int tmp = a[end + gap];for (end; end >= 0; end--){if (a[end] > tmp){a[end + gap] = a[end];}else{break;}}a[end + gap] = tmp;}}}//选择排序void SelectSort(int* a, size_t n){size_t begin = 0, end = n - 1;while (begin < end){size_t min=begin ,max = begin;for (size_t i = begin; i <= end; i++){if (a[i] < a[min])min = i;if (a[i]>a[max])max = i;}swap(a[begin], a[min]);if (begin == max)//max在头被交换至min处,将min处赋值给max,保证max为最大数的下标{max = min;}swap(a[end], a[max]);begin++;end++;}}//堆排序void Adjustdown(int* a, size_t n, size_t root)//向下调整算法{size_t parent = root;size_t child = parent * 2 + 1;while (child<n){//找大孩if (child + 1 < n&&a[child + 1] > a[child]){child++;}if (a[child] > a[parent]){parent = child;child = parent * 2 + 1;swap(a[child], a[parent]);}else{break;}}}void HeapSort(int* a, size_t n){//建大堆for (size_t i = 0; i < (n - 2) / 2; i--){Adjustdown(a, n, i);}size_t end = n - 1;while (end>0){swap(a[0], a[end]);Adjustdown(a, end, 0);end--;}}//冒泡排序void BubbleSort(int* a, int n){int j = 0;for (int i = 0; i < n - 1 ; i++){int flag = 0;for (j; j < n - i-1; j++){if (a[j]>a[j + 1]){swap(a[j], a[j + 1]);flag = 1;}}if (flag==0){break;}}}//快速排序//左右指针int PartSortLF(int*a, int begin, int end){int key = end;while (begin < end){while (begin < end && a[begin] <= a[key]){++begin;}while (begin < end && a[end] >= a[key]){end--;}if (begin < end){swap(a[begin], a[end]);}}swap(a[begin], a[key]);return begin;}//挖坑int PartSortK(int*a, int begin, int end){int key = a[end];while (begin < end){while (begin < end && a[begin] <= key){++begin;}a[end] = a[begin];while (begin < end && a[end] >= key){end--;}a[begin] = a[end];}a[begin] = key;return begin;}//前后指针int PartSortFB(int*a, int begin, int end){int cur = begin;int prev = cur - 1;while (cur < end){if (a[cur] < a[end] && ++prev != cur)//如果a[cur]<key prev++紧跟cur 如果prev!=cur 就交换;swap(a[cur], a[prev]);cur++;                                 //a[cur]>key,因为是&&前面错不判断后面条件,只有cur++往后走;}swap(a[++prev], a[end]);return prev;}void QuickSort(int* a, int left, int right){                                             //快排可以利用三数取中,和小区间优化进行优化。if (left >= right)                        //三数取中是取一组数头尾中间三数的中位数作为key,return;                               //小区间优化是当区间数的个数小于一定值时,利用直接插入排序,减少递归开销。while (left < right){int div = PartSortLF(a, left, right);QuickSort( a, left, div-1);QuickSort( a, div+1,right);}}//非递归实现快速排序void QuickSortNonR(int* a, int begin, int end)//这里使用栈来模拟递归,如果不知道栈中存什么可以看一看函数的参数{stack<int> s;if (begin < end){s.push(end);                         //s.push(begin);}while (!s.empty()){int begin = s.top();s.pop();int end = s.top();s.pop();int div = PartSortLF(a, begin, end);if (begin < div - 1)//至少还有两个数继续排,这里也可以用小区间优化{s.push(div - 1);s.push(begin);}if (div + 1 < end){s.push(end);s.push(div + 1);}}}//归并排序void Merge(int* a, int* tmp, int begin1, int end1, int begin2, int end2)//将两个空间begin1~end1与begin2~end2归并,这里1区间在2区间左边{int index = begin1;int start = begin1;int finish = end2;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2])tmp[index++] = a[begin1++];else{tmp[index++] = a[begin1++];}}//走到这里1,2两个区间里有一个区间可能没cp完所以要接着cpwhile (begin1 <= end1){tmp[index++] = a[begin1++];}while (begin2 <= end2){tmp[index++] = a[begin2++];}//最后要把tmp中的数据考回a中供上一层递归归并memcpy(a + start, tmp + start, (finish - start + 1)*sizeof(int));//一定要注意这里memcpy是按字节考的一定要乘上sizeoftype否则就会少cp数据}void _MergeSort(int* a, int* tmp, int begin, int end)//将一组数不断地分成小区间,然后将小区间归并起来{if (begin >= end)return;int mid = begin + (end - begin) / 2;//每次分成[begin,mid],[mid+1,end]两个区间_MergeSort(a, tmp, begin, mid);_MergeSort(a, tmp, mid+1,end);//归并区间Merge(a, tmp, begin, mid, mid + 1, end);}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 忘记Wi-Fi密码了怎么办 魅蓝手机null锁住了怎么办 红米手机锁屏了怎么办 不记得锁屏密码怎么办 小米手机音量键坏了怎么办 小米6音量键坏了怎么办 小米2s开不开机怎么办 小米4不充电了怎么办 小米2开不开机怎么办 手机开机键开不了机怎么办 三星s4反复重启怎么办 小米5反复重启怎么办 电脑系统奔溃了怎么办 电脑开机后屏幕出现英文怎么办 小米4开不开机了怎么办 小米4一直显示mi怎么办 小米手机开关键失灵怎么办 小米手机开机键失灵怎么办 小米6不断重启怎么办 小米6一直重启怎么办 小米6自动重启怎么办 手机的开机键坏了怎么办 小米6频繁重启怎么办 小米6安装xp卡米怎么办 刷机失败反复重启怎么办 红米手机很卡怎么办啊 红米2a显示图标怎么办 手机一直处于开机状态怎么办 vivo手机进水开不了机怎么办 魅蓝s6锁了怎么办 pos机刷卡刷多了怎么办 红米5a开不机怎么办 魅族双亲要密码怎么办? 苹果wi-fi网速慢怎么办 腾达宽带用户名密码忘了怎么办 无线网秘密忘了怎么办 wan口设置已断开怎么办 中兴手机忘记解锁图案怎么办 u盘显示参数错误怎么办 硬盘vc加密密码忘了怎么办 软件文件移动到其他盘打不开怎么办