六种排序算法总结

来源:互联网 发布:日语网络课程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