六种排序算法总结
来源:互联网 发布:日语网络课程360网盘 编辑:程序博客网 时间:2024/05/18 03:39
参考资料:
1.《MoreWindows 白话经典算法之七大排序(第2 版)》
2. http://blog.csdn.net/jnu_simba/article/details/9705111
一、冒泡排序(BubbleSort)
注意:用gcc编译c++程序要加-lstdc++.
eg. gcc -lstdc++ -o sort sort.cpp
这样,可以再循环语句中对循环变量赋值。
void swap1(int *left, int *right){ //形参为指针类型 //交换left和right所指向变量的值int temp=*left;*left=*right;*right=*temp;}
void swap2(int &left,int &right){ //函数的参数为引用类型。引用类型的形参与相应的实参占用相同的内存空间,也就是说,改变形参值,实参会随着变化<span style="white-space:pre"></span>//交换两个int型变量的值 <span style="white-space:pre"></span>int temp=left;<span style="white-space:pre"></span>left=right;<span style="white-space:pre"></span>right=temp;}
//swap3和swap2一样,形参都是引用类型
void swap3(int &left,int &right){if (left !=right){ //注意:若left和right引用的是同一个变量,那么会将这个变量置为0。所以排除这种情况left ^=right;right ^=left;left ^=right;}}
swap1, swap2, swap3 都是交换两个变量的值。
对数组而言,swap1实参为 &a[1], swap2, swap3实参为a[1].
基本的冒泡排序算法:
void BubbleSort1(int a[],int n){for (int i=1;i<n;i++){ //执行n-1趟,i从1取到n-1,每次执行完将arr[i-1]的值就位for (int j=n-1;j>=i;j--){ 反向检测,第i趟对arr[n-1]~arr[i]起泡if (a[j-1]>a[j]) swap1(&a[j-1],&a[j]);}}}
其中swap1的作用可以用下面的交换代替:
int temp=arr[j-1];arr[j-1]=arr[j];arr[j]=temp;改进的冒泡排序算法:
//思路:在算法中增设一个标志exchange,用以标记本趟起泡排序是否发生了逆序和交换,没有则exchange=false,表示已经全部排好序,因而可以终止处理,结束算法。
void BubbleSort2(int a[],int n){for (int i=1;i<n;i++){bool change=false;for (int j=n-1;j>=i;j--){if (a[j-1]>a[j]){change=true; swap1(&a[j-1],&a[j]);}}if (change==false) return;}}
二、直接插入排序(Insert Sort)
直接插入排序的算法:
void InsertSort1(int a[],int n){for (int i=1;i<n;i++){ //为a[i]在前面的a[0,……,i-1]区域找到合适的位置int j;for (j=i-1;j>=0;j--)if (a[j]<=a[i]) break; //找到了合适的位置,a[i]应在j+1位置if (j!=i-1){ //将原来的j+1~i-1依次向后移动一个int temp=a[i];for (int k=i-1;k>j;k--) a[k+1]=a[k];a[j+1]=temp;} }}
改进的直接插入排序算法:
//思路:一边将a[j]向后移动一边搜索a[i]的插入位置
void InsertSort2(int a[],int n){for (int i=1;i<n;i++){if (a[i-1]>a[i]){ int temp=a[i]; int j; for (j=i-1;j>=0&&a[j]>a[i];j--) //检查a[0,……,n-1] a[j+1]=a[j]; a[j+1]=temp; } } }
三、希尔排序(Shell Sort / Diminishing-increment sort)
按定义严格来写的希尔排序
void ShellSort1(int a[],int n){
<span style="white-space:pre"></span>for (int gap=n/2;gap>0;gap /=2) //步长设定for (int i=0;i<gap;i++) //按组排序for (int j=i+gap;j<n;j+=gap) //组内采用直接插入排序if(a[j]<a[j-gap]){ int temp=a[j]; int k; for(k=j-gap;k>=i&&a[k]>temp;k-=gap) a[k+gap]=a[k]; [k+gap]=temp; }}
四、直接选择排序(Select Sort)
直接选择排序和直接插入排序都是将数据分为有序区和无序区;
其区别是——
直接插入排序:将无无序区的第一个元素插入到有序区形成一个更大的有序区;
直接选择排序:在无序区选择一个最小的元素放在有序区的最后面;
void SelectSort(int a[],int n){for (int i=0;i<=n-2;i++){int MinIndex=i; //找最小元素的位置for (int j=i+1;j<n;j++) if (a[j] <a[MinIndex]) MinIndex=j; swap1(&a[i],&a[MinIndex]); //将找到的最小元素放到无序区的开头 }}
五、快速排序(Quick Sort)
快速排序采用了分治(divide-and-conquer)的策略。
该方法的基本思想是:
1.先从数组找出一个数作为基准数;
2.AdjustArray——将大于等于这个数的全都放到它右边,小于它的数全都放到它左边;
3.再对左右左右区间重复第2步,直到各区间只剩下一个数。
(具体解说参见《大话数据结构》)
快速排序的代码:
int AdjustArray(int s[],int l,int r){ int i=l,j=r; int x=s[l]; while(i<j){ while(i<j&&s[j]>=x) j--; //从右向左找小于x的数填坑if (i<j){ s[i]=s[j]; i++;}while(i<j&&s[i]<x) i++; //从左向右找大于等于x的数填坑if (i<j){ s[j]=s[i];j--;} } s[i]=x; return i; //返回调整后基准数的位置}//分治法的代码void QuickSort(int s[],int l,int r){if (l<r){int i=AdjustArray(s,l,r);QuickSort(s,l,i-1);QuickSort(s,i+1,r);}}
六、归并排序(Merge Sort)
void merge(int a[],int tmp_array[],int lpos,int rpos,int rightn){int leftn=rpos-1;int tmpos=lpos;int num_elements =rightn-lpos+1;while(lpos<=leftn && rpos <=rightn) if (a[lpos]<=a[rpos]) tmp_array[tmpos++]=a[lpos++]; else tmp_array[tmpos++]=a[rpos++];while(lpos <=leftn) tmp_array[tmpos++]=a[lpos++]; //copy the rest of the left partwhile(rpos <=rightn) tmp_array[tmpos++]=a[rpos++]; //copu the rest of the right partfor (int i=0;i<num_elements;i++,rightn--) a[rightn]=tmp_array[rightn]; //copy array back}void msort(int a[],int tmp_array[],int left,int right){int center;if(left<right){center=(left+right)/2;msort(a,tmp_array,left,center);msort(a,tmp_array,center+1,right);merge(a,tmp_array,left,center+1,right);}}void MergeSort(int a[],int n){ int *tmp_array =(int *)malloc(n*sizeof(int)); //创建一个由n个int 型元素所构成的一维动态数组变量 if (tmp_array !=NULL){ msort(a,tmp_array,0,n-1); free(tmp_array); } else printf("No space for tmp_array!\n");}函数malloc在stdlib.h 中声明:
eg:
int *p;
p=(int *)malloc(sizeof(int)); //创建一个int 型动态变量
int *q=(int *)malloc(sizeof(int)*n); //创建一个有n个int型元素所构成的一维动态数组变量
用malloc生成的动态变量,用free使之消除。
free(p); //撤销p所指向的动态变量
free(q); //撤销q所指向的动态数组
0 0
- 六种排序算法总结
- 排序算法(六) - 总结篇
- 排序算法总结(六)归并排序
- 漫谈经典排序算法:六、各种排序算法总结
- 漫谈经典排序算法:六、各种排序算法总结
- 漫谈经典排序算法:六、各种排序算法总结 .
- 漫谈经典排序算法:六、各种排序算法总结
- Java六种排序算法
- 常用算法总结之排序(六)----堆排序
- Java排序算法总结(六):堆排序
- Java排序算法总结(六):堆排序
- Java排序算法总结(六):堆排序
- 算法总结系列之六: 桶排序(Bucket Sort)
- 数据结构简单的六种排序算法
- 六种常见排序算法Java实现
- C语言实现六种排序算法
- Java语言实现六种排序算法
- c++实现六种排序算法
- 用Scala语言轻松开发多线程、分布式以及集群式程序
- 网页程序开机启动并自动全屏
- JAVA常用字符串工具类
- 配置WCF
- 友盟统计
- 六种排序算法总结
- 直接赋值与从键盘输入两种方式进行hello与word两个字符串的连接
- lombok 1.16.0
- meta标签控制IE渲染标准模式和兼容模式
- 回到PHP,美化了后台界面
- MyEclipse2013工具与破解工具
- 怎样通过转换器将pdf转换成ppt
- HDU2047 阿牛的EOF牛肉串
- javascript DES加密解密算法