排序
2017-01-24 00:09
309 查看
排序
随机数获取
///////////////////////////////////////////// // // 获取随机数 // min 最小值 // max 最大值 ///////////////////////////////////////////// int GetRandom(int min, int max) { return (rand() % static_cast<int>(max + 1 - min)) + min; } |
冒泡排序(n2)
///////////////////////////////////////////// // // 冒泡排序 v1.0 // arr 整型数组指针 // n 数组长度 ///////////////////////////////////////////// template <class T> void BubbleSort(T* arr, int n) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n - 1 - i; ++j) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } |
///////////////////////////////////////////// // // 冒泡排序 v2.0 // arr 整型数组指针 // n 数组长度 ///////////////////////////////////////////// template <class T> void BubbleSort(T* arr, int n) { int bFlag = false; for (int i = 0; i < n; ++i) { for (int j = 0; j < n - 1 - i; ++j) { // 交换数据 if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; bFlag = true; } } if (bFlag == false) // 无交换直接跳出 { break; } } } |
插入排序(n2)
///////////////////////////////////////////// // // 直接插入排序 // 基本思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。 // a int* 整型数组指针 // N int 数组长度 ///////////////////////////////////////////// void InsertSort(int *a, int N) { int i = 0; int j = 0; for (int i = 1; i < N; i++) if (a[i] < a[i - 1]) { int temp = a[i]; for (j = i - 1; j >= 0 && a[j] > temp; j--) a[j + 1] = a[j]; // 把比temp大或相等的元素全部往后移动一个位置 a[j + 1] = temp; } } |
二分插入排序(nlog2n)
///////////////////////////////////////////// // // 二分插入排序 // 基本思想:基于插入排序,在查找插入位置时采用二分查找法。 // A int* 整型数组指针 // length int 数组长度 ///////////////////////////////////////////// void BinInsertSort(int* A, int length) { int middle = 0; int left = 0; int right = 0; for (int i = 1; i<length; i++) // 从第2个元素开始 { int insertNum = A[i]; // 将有序区作为查找范围 left = 0; right = i - 1; // 二分查找 while (left <= right) { // 依次取查找范围的中间位置 middle = (left + right) / 2; if (insertNum<A[middle]) right = middle - 1;// 在前半区查找 else left = middle + 1; // 在后半区查找 } // 移动元素, 空出要插入的位置 for (int j = i - 1; j >= left; j--) A[j + 1] = A[j]; // 将当前元素插入适当位置 A[left] = insertNum; } } |
希尔排序
///////////////////////////////////////////// // // 希尔排序 // a 整型数组指针 // n 数组长度 ///////////////////////////////////////////// void ShellSort(int* a, int n) { int i = 0; int j = 0; int x = 0; int gap = n / 2; while (gap >= 1) // 循环至增量为1时结束 { for (i = gap; i<n; i++) { x = a[i]; // 获取序列中的下一个数据 j = i - gap; // 序列中前一个数据的序号 while (j >= 0 && a[j]>x) // 下一个数大于前一个数 { a[j + gap] = a[j]; // 将后一个数向前移动 j = j - gap; // 修改序号,继续向前比较 } a[j + gap] = x; // 保存数据 } gap /= 2; // 缩小增量 } } |
直接选择排序(n2)
///////////////////////////////////////////// // // 直接选择排序 // a 整型数组指针 // n 数组长度 ///////////////////////////////////////////// void SelectSort(int* a, int n) { int i, j, t, k; for (i = 0; i<n - 1; i++) { k = i; for (j = i + 1; j<n; j++) if (a[k]>a[j]) k = j; t = a[i]; a[i] = a[k]; a[k] = t; } } |
不稳定,元素的位置可能会改变。
堆排序
void HeapAdjust(int a[],int s,int n)//构成堆 { int j,t; while(2*s+1<n) //第s个结点有右子树 { j=2*s+1 ; if((j+1)<n) { if(a[j]<a[j+1])//右左子树小于右子树,则需要比较右子树 j++; //序号增加1,指向右子树 } if(a[s]<a[j])//比较s与j为序号的数据 { t=a[s]; //交换数据 a[s]=a[j]; a[j]=t; s=j ;//堆被破坏,需要重新调整 } else //比较左右孩子均大则堆未破坏,不再需要调整 break; } } void HeapSort(int a[],int n)//堆排序 { int t,i; int j; for(i=n/2-1;i>=0;i--) //将a[0,n-1]建成大根堆 HeapAdjust(a, i, n); for(i=n-1;i>0;i--) { t=a[0];//与第i个记录交换 a[0] =a[i]; a[i] =t; HeapAdjust(a,0,i); //将a[0]至a[i]重新调整为堆 } } |
#include <ctime> #include <iostream> using namespace std; ///////////////////////////////////////////// // // 获取随机数 // min 最小值 // max 最大值 ///////////////////////////////////////////// int GetRandom(int min, int max) { return (rand() % static_cast<int>(max + 1 - min)) + min; } int _tmain(int argc, _TCHAR* argv[]) { const int nMax = 1000; int Data[nMax]; srand((unsigned)time(NULL)); // 设置种子 for (int n = 0; n < nMax; ++n) { Data = rand(); } //BubbleSort<int>(Data, nMax); InsertSort(Data, nMax); for (int n = 0; n < nMax; ++n) { cout << Data << " "; } system("pause"); return 0; } |
归并排序
void MergeStep(int a[],int r[],int s,int m,int n) //相邻有序段合并 { int i,j,k; k=s; i=s; j=m+1; while(i<=m && j<=n) //当两个有序表都未结束时,循环比较 { if(a[i]<=a[j]) //当较小的元素复制到R中 r[k++]=a[i++]; else r[k++]=a[j++]; } while(i<=m) //将未合并的部分复制到R中 r[k++]=a[i++]; while(j<=n) r[k++]=a[j++]; //将未合并的部分复制到R中 } void MergePass(int a[],int r[],int n,int len) //完成一遍合并的函数 { int s,e; s=0; while(s+len<n) //至少有两个有序段 { e=s+2*len-1; if(e>=n) //最后一段可能少于len个结点 e=n-1; MergeStep(a,r,s,s+len-1,e); //相邻有序段合并 s=e+1; //下一对有序段中左段的开始下标 } if(s<n) //还剩一个有序段,将其从A中复制到R中 for(;s<n;s++) r[s]=a[s]; } void MergeSort(int a[],int n) { int *p; int len=1; //有序序列的长度 int f=0; //变量f作标志 if(!(p=(int *)malloc(sizeof(int)*n))) //分配内存空间,保存临时数据 { printf("分配临时内存失败!\n"); exit(0); } while(len<n) { if(f) //交替地在A和P之间来回合并 MergePass(p,a,n,len); //调用MergePass,对p合并到a else MergePass(a,p,n,len); //调用MergePass,对a合并到p len*=2; //增加有序序列长度 f=1-f; //使f值在0和1之间切换 } if(f) //若进行了排序 for(f=0;f<n;f++) //将数组p中的数据复制到数组a a[f]=p[f]; free(p); //释放分配的内存 } |
快速排序
int Division(int a[],int left, int right) //分割 { int base=a[left]; //基准元素 while(left<right) { while(left<right && a[right]>base) --right; //从右向左找第一个比基准小的元素 a[left]=a[right]; while(left<right && a[left]<base ) ++left; //从左向右找第一个比基准大的元素 a[right]=a[left]; } a[left]=base; return left; } void QuickSort(int a[],int left,int right) { int i,j; if(left<right) { i=Division(a,left,right); //分割 QuickSort(a,left,i-1); //将两部分分别排序 QuickSort(a,i+1,right); } } |
相关文章推荐
- 2016书单总结--看透SpringMvc源代码分析与实践-概述
- c++思考题
- Windows DLL开发笔记
- C++ SQL 语句格式化
- 【PAT】1048. Find Coins
- 学习hibernate_02_双向onetoone注解
- 【机器学习】数据预处理
- jsoncpp 使用详解
- convert 3D matrix into diagonal block matrix
- DLL开发的问题
- Java+mysql用户注册登录
- 使用Visual调试库检测内存泄露
- hdu5862 Counting Intersections
- C++连接MySQL
- 2016年年终总结
- Linux内核重点精要
- 安装虚拟机及学习linux系统 20155222卢梓杰
- 这篇文章关于两阶段提交和Paxos讲的很好
- 高效质数判断算法及其JS实现
- ArchLabs Linux 2019.01.20 发布,基于Arch Linux的发行版