排序算法---之交换排序(冒泡排序&快速排序-左右指针法,挖坑法,前后指针法)

来源:互联网 发布:过滤器相关java面试题 编辑:程序博客网 时间:2024/06/01 09:24

                                                      排序算法----交换排序(冒泡排序&快速排序)

一、排序算法分为:

     1.插入排序(直接插入排序&希尔排序)

     2.选择排序(直接选择排序&堆排序)

     3.交换排序(冒泡排序&快速排序)

     4.归并排序

----快速排序总共有三种方法:(1).左右指针法(2).挖坑法(3).前后指针法

二、几种排序的性能比较

排序方法的比较

类别

排序方法

时间复杂度

空间复杂度

稳定性

平均情况

最好情况

最坏情况

辅助存储

插入排序

直接插入

O(n2)

O(n)

O(n2)

O(1)

稳定

希尔排序

O(n1.3)

O(n)

O(n2)

O(1)

不稳定

选择排序

直接选择

O(n2)

O(n2)

O(n2)

O(1)

不稳定

堆排序

O(nlog2n)

O(nlog2n)

O(nlog2n)

O(1)

不稳定

交换排序

冒泡排序

O(n2)

O(n)

O(n2)

O(1)

稳定

快速排序

O(nlog2n)

O(nlog2n)

O(n2)

O(nlog2n)

不稳定

归并排序

O(nlog2n)

O(nlog2n)

O(nlog2n)

O(n)

稳定

基数排序

O(d(r+n))

O(d(rd+n))

O(d(r+n))

O(rd+n)

稳定

注:基数排序中,n代表关键字的个数,d代表长度,r代表关键字的基数

 

三、冒泡排序

    1.代码

//冒泡排序void BubbleSort(int* a,size_t n){assert(a);int end = n;while(end>0){for(int i=0;i<end;++i){if(a[i-1]>a[i]){swap(a[i-1],a[i]);}}--end;}}//打印函数void PrintArray(int* a,size_t n){for(size_t i=0;i<n;++i){cout<<a[i]<<" ";}cout<<endl;}//测试代码void  BubbleSortTest(){int a[]={2,5,4,0,9,3,6,8,7,1};PrintArray(a,sizeof(a)/sizeof(a[0]));BubbleSort(a,sizeof(a)/sizeof(a[0]));PrintArray(a,sizeof(a)/sizeof(a[0]));}
2.时间复杂度:

    最好情况:O(n)

    最坏情况:O(n^2)

    平均情况:O(n^2)

    空间复杂度:O(1)

3.稳定性:稳定

四、快速排序

   方法一左右指针法

   算法代码:

//方法一:左右指针法int PartSort1(int* a,int left,int right){int key = a[right];int begin = left;//左右指针,下标int end = right;while(begin<end){while(begin<end && a[begin]<=key)//从左边找比key大的值{++begin;}while(begin<end && a[end]>=key)//从右边找比key小的值{--end;}if(begin<end){swap(a[begin],a[end]);}swap(a[begin],a[right]);}return a[begin];}void QuickSort1(int* a,int left,int right){assert(a);if(left<right){int div = PartSort1(a,left,right);QuickSort1(a,left,div-1);QuickSort1(a,div+1,right);}}//打印函数void PrintArray(int* a,size_t n){for(size_t i=0;i<n;++i){cout<<a[i]<<" ";}cout<<endl;}//测试代码void QuickSortTest(){    int a[]={2,5,4,0,9,3,6,8,7,1};PrintArray(a,sizeof(a)/sizeof(a[0]));QuickSort1(a,0,(sizeof(a)/sizeof(a[0]))-1);PrintArray(a,sizeof(a)/sizeof(a[0]));}
    方法二:挖坑法

    算法代码:

//方法二:挖坑int PartSort2(int* a,int left,int right){int key = a[right];while(left<right){while(left<right && a[left]<=key){++left;}a[right] = a[left];//左坑while(left<right && a[right]>=key){--right;}a[left] = a[right];}a[left] = key;return a[left];}void QuickSort2(int* a,int left,int right){assert(a);if(left<right){int div = PartSort2(a,left,right);QuickSort2(a,left,div-1);QuickSort2(a,div+1,right);}}//打印函数void PrintArray(int* a,size_t n){for(size_t i=0;i<n;++i){cout<<a[i]<<" ";}cout<<endl;}//测试代码void QuickSortTest(){    int a[]={2,5,4,0,9,3,6,8,7,1};PrintArray(a,sizeof(a)/sizeof(a[0]));QuickSort2(a,0,(sizeof(a)/sizeof(a[0]))-1);PrintArray(a,sizeof(a)/sizeof(a[0]));}
      方法三:前后指针法

     算法代码:

//方法三:前后指针法??若有问题,请指出int PartSort3(int* a,int left,int right){int cur = left;int prev = left-1;int key = a[right];while(cur<right);{if(a[cur]<key && ++prev!=cur){swap(a[cur],a[prev]);}++cur;}swap(a[++prev],a[right]);return prev;}void QuickSort3(int* a,int left,int right){assert(a);if(left<right){int div = PartSort3(a,left,right);QuickSort3(a,left,div-1);QuickSort3(a,div+1,right);}}//打印函数void PrintArray(int* a,size_t n){for(size_t i=0;i<n;++i){cout<<a[i]<<" ";}cout<<endl;}//测试代码void QuickSortTest(){    int a[]={2,5,4,0,9,3,6,8,7,1};PrintArray(a,sizeof(a)/sizeof(a[0]));QuickSort3(a,0,(sizeof(a)/sizeof(a[0]))-1);PrintArray(a,sizeof(a)/sizeof(a[0]));}
2.时间复杂度:

   最好情况:O(nlogn)

   最坏情况:O(n^2)

   平均情况:O(nlogn)

   空间复杂度:O(nlogn)

3.稳定性:不稳定









阅读全文
0 0
原创粉丝点击