排序算法(C++)
来源:互联网 发布:lofter绑定独立域名 编辑:程序博客网 时间:2024/06/02 05:51
一、插入排序
工作原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。设立第一个元素为哨兵,从第二个元素开始,插入到前面大于它的数的前面。直到第n个元素结束。
时间复杂度:O(n^2)
void insert_sort(int *num,int len){ for (int i = 1;i < len;i++) { int tmp = num[i]; int j = i; while(j>0 && num[j-1]>tmp) { num[j] = num[j-1]; j--; } num[j] = tmp; }}
二、选择排序
工作原理:找出数组中最小元素和第一个元素交换,然后找出数组中次最小元素,与第二个元素进行交换。对数组中前n-1个元素按该方式继续。
时间复杂度:O(n^2)
void selection_sort(int num[], int len){ for (int i = 0; i < len - 1; i ++) { int j = i; for (int k = i + 1; k < len; k++) { if (num[k] < num[j]) { j = k; } } if (j != i) { int temp = num[j]; num[j] = num[i]; num[i] = temp; } }}
三、冒泡排序
工作原理:每次比较相邻的元素,如果顺序错误就把它们交换过来。冒泡排序每一次循环确定一个数归位,n个数排序,要进行n-1次循环。每一次循环需要从第一位进行相邻两个数的比较,将较大的数放到后面。
时间复杂度:O(n^2)
void Bubble_sort(int num[], int len){ for (i=0;i<n;i++) //开始冒泡排序 { for(j=i;j<n;j++) { if (a[i]>a[j]) { t = a[i]; a[i]=a[j]; a[j]=t; } } }}
四、快速排序
工作原理:每次排序设置一个基准点,将小于等于基准点的数全部放在基准点的左边,大于等于基准点的数放在基准点的右边,每一次循环就是将这个基准点进行归位。快速排序是基于一种二分思想。
快速排序过程
时间复杂度:最差:O(n^2) 平均:O(nlgn)
void Quick_sort(int left,int right){ int i,j,k,tmp; if(left>right) return; tmp = a[left]; i = left; j = right; while (i!=j) { while(a[j]>=tmp && i<j) j--; while(a[i]<=tmp && i<j) i++; if (i<j) { k = a[i]; a[i] = a[j]; a[j] = k; } }a[left] = a[i];a[i] = tmp;Quick_sort(left,i-1);Quick_sort(i+1,n);}
五、归并排序
工作原理:归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)。
分解待排序的n个元素的序列成各具n/2个元素的两个子序列,使用归并并排序递归地排序两个子序列,合并两个已排序好的子序列。
时间复杂度: 最佳:O(n) 最差:O(nlgn) 平均:O(nlgn)
void Merge_sort(int num[],int first,int end){ if (first < end) { int mid = (first + end) / 2; Merge_sort(num, first, mid); Merge_sort(num, mid+1, end); Merge(num, first, mid, end); }}void Merge(int num[],int first,int mid,int end){ int n1= mid-first+1; int n2 = end-mid; int *L = new int[n1]; int *R = new int[n2]; for (int i=0;i<n1;i++) { L[i]=num[first+i]; } for (int j=0;j<n2;j++) { R[j]=num[mid+j+1]; } int i = 0; int j = 0; int k = first; while(i < n1 && j < n2) { if (L[i] < R[j]) { num[k++] = L[i++]; } else { num[k++] = R[j++]; } } while (i < n1) { num[k++] = L[i++]; } while (j < n2) { num[k++] = R[j++]; } delete [] L; delete [] R;}
六、堆排序
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
在Max-heapify程序的每一步中,从num[i]和它的左边和右边值中选出最大的,并将其下标存储到largest中,用自底向上的方法利用过程Max-heapify把一个大小为n的数组转换成最大堆。因为数组中的最大元素总在根节点num[0]中,通过把它和num[n-1]进行互换,让元素放到正确的位置。这时候,去掉最大的节点(即len–),剩余的节点可能会违背最大堆的性质,将剩余的节点再次调用Max-heapify(num,1)构造新的最大堆,找到第二大的元素,从而实现堆排序。
时间复杂度:O(nlgn)
void Max_heapify(int num[], int i, int len){ int left = i * 2 + 1; if (left < len) { int largest = left; int right = left + 1; if (right < len) { if (num[right] > num[largest]) { largest = right; } } if (num[i] < num[largest]) { swap(num[i], num[largest]); Max_heapify(num, largest, len); } }}void Heap_sort(int num[], int len){ for (int i = len / 2; i >= 0; i--) { Max_heapify(num, i, len); } for (int j = len - 1; j >= 1; j--) { swap(num[0], num[j]); Max_heapify(num, 0, --len); }}
七、桶排序、计数排序
基数排序的基本思想:对每一个输入元素x,确定小于x的元素的个数,利用这一信息,可以直接把x放到输入数组中的位置。
桶排序假设输入数据服从均匀分布,平均情况下它的时间代价为O(n),具体地说,计数排序假设输入数据都属于一个区间内的整数,而桶排序则假设输入是由一个随机过程产生,该过程将元素均匀、独立地分布在[0 ,1)区间上。桶排序将[0,1)区间划分为n个相同大小的子区间,称为桶。先对每个桶中的数进行排序,然后遍历每一个桶,按照次序把各个桶中的元素列出来即可。
void Count_Sort(int ArrIn[],int ArrOut[],int len,int limit){ int* count = new int[limit+1]; for(int i=0;i<=limit;i++)//初始化count[] count[i] = 0; for(int i=0;i<len;i++)//count[i]记录ArrIn[]中等于i的元素个数 count[ArrIn[i]] += 1; for(int i=1;i<=limit;i++)//count[i]记录ArrIn[]中小于等于i的元素个数 count[i] += count[i-1]; for(int i=len-1;i>=0;i--) { ArrOut[count[ArrIn[i]]-1] = ArrIn[i]; count[ArrIn[i]] -= 1; } delete []count;}
八、基数排序
基数排序(Radix sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
时间复杂度:平均:O(n) 最坏:O(nlgn)
int maxbit(int data[], int n) //辅助函数,求数据的最大位数{ int d = 1; //保存最大的位数 int p = 10; for(int i = 0; i < n; ++i) { while(data[i] >= p) { p *= 10; ++d; } } return d;}void radixsort(int data[], int n) //基数排序{ int d = maxbit(data, n); int *tmp = newint[n]; int *count = newint[10]; //计数器 int i, j, k; int radix = 1; for(i = 1; i <= d; i++) //进行d次排序 { for(j = 0; j < 10; j++) count[j] = 0; //每次分配前清空计数器 for(j = 0; j < n; j++) { k = (data[j] / radix) % 10; //统计每个桶中的记录数 count[k]++; } for(j = 1; j < 10; j++) count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶 for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中 { k = (data[j] / radix) % 10; tmp[count[k] - 1] = data[j]; count[k]--; } for(j = 0; j < n; j++) //将临时数组的内容复制到data中 data[j] = tmp[j]; radix = radix * 10; } delete[]tmp; delete[]count;}
九、希尔排序
希尔排序属于插入排序的一种。希尔排序的基本思想就是把数进行分组,按照一定的规律分组,最先可以按照d1这个增量分组,d1=n/2(n为数组中数的长度)来分成d1个分组,然后对分组内部的数进行直接插入排序再设置第二个增量d2来分组,如d2 = d1/2这样来分组直到增量为1停止。希尔排序方法是一个不稳定的排序方法。
时间复杂度:最佳:O(n^s)(1
void shell_sort(int *num,int len){ int d = 0; for (d=len/2;d>0;d=d/2) { for (int i = d;i < len;i++) { int tmp = num[i]; int j = i; while(j>=d && num[j-d]>tmp) { num[j] = num[j-d]; j= j-d; } num[j] = tmp; } }}
- 排序算法 - 堆排序 (C++)
- 排序算法 - 快速排序(C++)
- 排序算法 - 计数排序(C++)
- C 排序算法小结
- c排序算法大全
- 排序算法小结(C++)
- C 语言排序算法
- C/C++排序算法
- 排序算法(C)
- C++快速排序算法
- 排序算法 C语言版
- C语言排序算法
- C语言排序算法
- 快速排序算法 C
- c排序算法总结
- 排序算法(c语言)
- C/C++排序算法
- 【C#】[算法]冒泡排序
- MFC如何在有界面的应用程序中开启控制台窗口
- Spring Data JPA @Query
- android 开发 命名规范
- 设计模式基本原则
- SDL_播放声音_Mix
- 排序算法(C++)
- 23种设计模式(1):单例模式
- iOS JSON序列化/反序列化哪家强?
- 番茄工作法 计划表格式
- Error:Some file crunching failed, see logs for details
- http接口RSA加密实例
- QMutex使用时遇到的错误
- Android逆向之旅---Android中锁屏密码算法解析以及破解方案
- Git删除远程仓库的文件或目录