排序算法总结

一. 冒泡排序

原理:比较相邻的元素,若前一个元素比后一个元素大,交换两个元素的位置;对每对相邻元素做一样的操作,从第一对到最后一对,最终最后的元素就是最大值。

初始 4 5 6 3 2 1

1      4 5 3 2 1 6

2      4 3 2 1 5 6

3      3 2 1 4 5 6

4      2 1 3 4 5 6

5      1 2 3 4 5 6

vector<int> BubbleSort(vector<int> &a){
for(int i=a.size()-1;i>=0;i--){ 
   for(int j=0;j<i;j++){
    if(a[j]>a[j+1]){
    int tmp=a[j];
    a[j]=a[j+1];
    a[j+1]=tmp;
    }
   }
 }
return a;
}

 最坏情况下 比较次数eq?%5Cfrac%7Bn%28n-1%29%7D%7B2%7D ,交换次数eq?%5Cfrac%7Bn%28n-1%29%7D%7B2%7D

时间复杂度eq?o%282%5E%7Bn%7D%29  稳定排序

二. 选择排序

原理:每次遍历都假设第一个索引处的元素最小,和其他索引处的值进行比较,如果当前索引处的值大于其他某处索引的值,假定其他某处索引的值为最小值,最后可以找到最小值所在索引;交换第一个索引处和最小值所在索引处的值。

原始           4 6 8 7 9 2 10 1

1                 1 6 8 7 9 2 10 4 

2                 1 2 8 7 9 6 10 4

3                 1 2 4 7 9 6 10 8

4                 1 2 4 6 9 7 10 8

5                 1 2 4 6 7 9 10 8

6                 1 2 4 6 7 8 10 9

7                 1 2 4 6 7 8 9 10

vector<int> SelectSort(vector<int> &a){
for(int i=0;i<a.size()-1;i++){
int min=i;
for(int j=i+1;j<a.size();j++){
  if(a[j]<a[min]) min=j;
}
if(min!=i){
int tmp=a[i];
a[i]=a[min];
a[min]=tmp;
}
return a;
}

最坏情况下 比较次数eq?%5Cfrac%7Bn%28n-1%29%7D%7B2%7D ,交换次数eq?n-1 

 时间复杂度eq?o%282%5E%7Bn%7D%29  不稳定排序

 三.插入排序

原理:把所有元素分为已排序和未排序;找到未排序的第一个元素,向已排序的组中进行插入;倒叙遍历已排序元素,一次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么久把待插入元素放到这个位置,其他位置元素向后移动一位。

初始   4 3 2 10 12 1 5 6

 1       3 4 2 10 12 1 5 6      3

 2       2 3 4 10 12 1 5 6      2

 3      2 3 4 10 12 1 5 6      10

 4       2 3 4 10 12 1 5 6      12

 5      1 2 3 4 10 12 5 6       1

 6      1 2 3 4 5 10 12 6       5

 7       1 2 3 4 5 6 10 12       6

vector<int> InsertSort(vector<int> &a){
for(int i=1;i<a.size();i++){
    for(int j=i;j>=0;j--){
     if(a[j-1]>a[j]){
      int tmp=a[j-1];
      a[j-1]=a[j];
      a[j]=tmp;
     }
     else break;
   }
  }
}

 最坏情况下 比较次数eq?%5Cfrac%7Bn%28n-1%29%7D%7B2%7D ,交换次数eq?%5Cfrac%7Bn%28n-1%29%7D%7B2%7D

时间复杂度eq?o%282%5E%7Bn%7D%29  稳定排序

四. 希尔排序

原理:对插入排序进行改进

选定一个增长量h,按照h作为数据分组依据,对数据进行分组;对分好组的每组数据完成插入排序;减小增长量,最小减为1,重复第二步操作。

原始:   9 1 2 5 7 4 8 6 3 5

h=5        9 1 2 5 7 4 8 6 3 5

              4 1 2 3 5 9 8 6 5 7

h=2        4 1 2 3 5 9 8 6 5 7

              2 1 4 3 5 6 5 7 8 9

h=1        2 1 4 3 5 6 5 7 8 9

              1 2 3 4 5 5 6 7 8 9        

vector<int> ShellSort(vector<int>&a){
 int n=a.size();
 //确定增量
 int h=1;
 while(h<=n/2){
   h=h*2+1;
}
while(h>=1){
  for(int i=h;i<a.size();i++){
     for(int j=i;j>=h;j-=h){
        if(a[j]<a[j-h]){
          int tmp=a[j-h];
          a[j-h]=a[j];
          a[j]=tmp;
         }
        else break;
       }
     }
   h=h/2;
   }
 return a;
}

不稳定排序 

 五. 归并排序

原理:尽可能将一组数据拆分成两个元素数目相等的子组,并对每个子组继续拆分,直至拆分后的每个子组元素数目为1;将相邻的两个子组进行合并成一个有序的大组;不断重复合步骤并直至最终只有一个组为止。

                                            8 4 5 7 1 3 6 2

                              8 4 5 7                             1 3 6 2

                        8 4            5 7                   1 3            6 2

                      8      4       5     7               1     3        6      2

                        4 8            5 7                    1 3           2 6

                               4 5 7 8                             1 2 3 6

                                           1 2 3 4 5 6 7 8

void MergeSort(vector<int> &a){
 int r=a.size()-1;
 int l=0;
 Sort(a,l,r);
}
void Sort(vector<int> &a,int l,int r){
 if(r<=l){retun;}
 int m=l+(r-l)/2;
 Sort(a,l,m);
 Sort(a,m+1,r);
 Merge(a,l,m,r);
}
void Merge(vector<int> &a,int l,int m,int r){
  vector<int> a1(a.size());
  int p1=l,p2=m,i=l;
  while(p1<=m&&p2<=r){
     if(a[p1]<a[p2]{
        a1[i++]=a[p1++];
     }
     else{
        a1[i++]=a[p2++];
     }
   }
  while(p1<=m1){
    a1[i++]=a[p1++];
   }
  while(p2<=r){
     a1[i++]=a[p2++];
   }
   for(int j=l;j<=r;j++)
   { a[j]=a1[j];}
  }

稳定排序 

 六. 快速排序

原理:设置一个分界值,通过分界值将数组分为左右两部分;将大于或等于分界值的数据放到数组的右边,小于分界值的放在数组的左边。此时左边部分中各元素小于或等于分界值,而右边部分中各元素都大于或等于分界值;左边右边的数据可以独立排序。对于左侧的数据也可以取一个分界值,将该部分分成左右两部分,同样左边放置较小值,右边放置较大值,同样右侧的数据也可以做类似操作。通过递归完成左侧部分排序后,再递归右侧部分排序,当左右两部分数据均排好后,整个数组排序完成。

                                                    6 1 2 7 9 3 4 5 8

                                                     3 1 2 4 5 6 9 7 8

                                            3 1 2 4 5                9 7 8

                                            2 1 3 4 5                8 7 9

                                         1 2          4 5             7 8 

                                            1 2 3 4 5                7 8 9

                                                      1 2 3 4 5 6 7 8 9

void QuickSort(vector<int> &a){
   int l=0;
   int r=a.size()-1;
   sort(a,l,r);
}
void Sort(vector<int> &a,int l,int r){
   if(l>=r) return;
   //分组,左子组右子组均有序
   int pa=Partition(a,l,r);
   Sort(a,l,p-1);
   Sort(a,p+1,r);
}
int Partition(vector<int> &a,int l int r){
    int num=a[l]; // 分界值
    int pl=l,pr=r+1;
    while(true){
       while(a[pr]>num){
        if(pl==pr) break;
        else pr--;
        }
       while(a[pl]<num){
        if(pl==pr) break;
        else pl++;
        }
        if(pl>=pr) break;
        else{
        swap(a.begin()+pl,a.begin()+pr);
        }
    }
    swap(a.begin()+l,a.begin()+pr);
    return pr;
}

不稳定排序 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值