冒泡排序和选择排序及其他们的优化

1.冒泡排序

 

冒泡排序(Bubble Sort),又被称为气泡排序或泡沫排序。

它是一种较简单的排序算法。它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,一次遍历之后,最大的元素就在数列的末尾!采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。重复此操作,直到整个数列都有序为止!

普通的冒泡排序

void Bubble_sort(int a[],int length){
  for(int i=0;i<length-1;i++){
    for(int j=0;j<length-i-1;j++){
      int temp=0;
      if(a[j]>a[j+1]){
        temp=a[j];
        a[j]=a[j+1];
        a[j+1]=temp;
      }
    }
  }
}

优化一:例如:{5,8,6,3,9,2,1,7}

利用冒泡进行到第六轮的时候有:

(1,2,3,4,5,6,7,8,9}

进行到第七轮的时候有:

{1,2,3,4,5,6,7,8,9}

很明显可以看出:在第六轮的时候已经呈现有序序列了,可算法依旧在执行

则可以判断出,我们利用一个bool类型当它数据不发生交换时 进行退出

优化代码有:

/冒泡排序算法优化1
//优化思想:如果不发生交换说明已经有序了,就可以退出了
void Bubble_sort1(int a[],int length){
  for(int i=0;i<length-1;i++){
    bool isSorted=true;
    for(int j=0;j<length-i-1;j++){
      if(a[j]>a[j+1]){
        int temp=a[j];
        a[j]=a[j+1];
        a[j+1]=temp;
        isSorted=false;
      }
    }
    if(isSorted)
      break;
  }
}

优化二:进行数列有序列的界定

设定一个数列{3,4,2,1,5,6,7,8}

可以发现有的数列中后面的一直是有序的,当在前面找出一个较大的时候对后面的顺序不产生影响,只是让后面的有序长度增加了1,利用这个思想,我们可以设定一个之用来记录每一轮循环完之后,交换的地点也就是第一个有序数的位置

代码如下

//冒泡算法优化2
//优化思想:对数列有序区的界定,在每次交换完之后更新有序区的边界
void Bubble_sort2(int a[],int length){
  int sortBorder=length-1;
  //记录数组的有序边界
  int lastIndex=0;
  //记录最后一次交换的位置
  for(int i=0;i<length-1;i++){
    bool isSorted=true;
    for(int j=0;j<sortBorder;j++){
      if(a[j]>a[j+1]){
        int temp=a[j];
        a[j]=a[j+1];
        a[j+1]=temp;
        isSorted=false;
        lastIndex=j;
      }
    }
    sortBorder=lastIndex;
    if(isSorted)
      break;
  }
}

2,选择排序

 

选择排序也是一种简单直观的排序算法。它的工作原理很容易理解:初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。算法平均时间复杂度O(n2)。
代码如下:

void xuanze_sort(int a[],int length){
  for(int i=0;i<length;i++){
    for(int j=i+1;j<length;j++){
      int temp=0;
      if(a[i]>a[j]){
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
      }
    }
  }
}


优化算法:设定两个值,每次从两边开始找,算法复杂度还跟以前一样

代码如下:

void xuanze_sort1(int a[],int length){
  int left=0;
  int right=length-1;
  while(left<=right){
     int min=left;
     int max=left;
    for(int i=left;i<=right;i++){
      if(a[i]<a[min]){
        min=i;
      }
      if(a[i]>a[max]){
        max=i;
      }
    }
    swap(a[left],a[min]);
    if(left==max){
      max=min;
    }
    swap(a[right],a[max]);
    left++;
    right--;
  }
}

完整代码展示:

//小博学习之路之排序
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
//简单冒泡排序算法
void Bubble_sort(int a[],int length){
  for(int i=0;i<length-1;i++){
    for(int j=0;j<length-i-1;j++){
      int temp=0;
      if(a[j]>a[j+1]){
        temp=a[j];
        a[j]=a[j+1];
        a[j+1]=temp;
      }
    }
  }
}
//冒泡排序算法优化1
//优化思想:如果不发生交换说明已经有序了,就可以退出了
void Bubble_sort1(int a[],int length){
  for(int i=0;i<length-1;i++){
    bool isSorted=true;
    for(int j=0;j<length-i-1;j++){
      if(a[j]>a[j+1]){
        int temp=a[j];
        a[j]=a[j+1];
        a[j+1]=temp;
        isSorted=false;
      }
    }
    if(isSorted)
      break;
  }
}
//冒泡算法优化2
//优化思想:对数列有序区的界定,在每次交换完之后更新有序区的边界
void Bubble_sort2(int a[],int length){
  int sortBorder=length-1;
  //记录数组的有序边界
  int lastIndex=0;
  //记录最后一次交换的位置
  for(int i=0;i<length-1;i++){
    bool isSorted=true;
    for(int j=0;j<sortBorder;j++){
      if(a[j]>a[j+1]){
        int temp=a[j];
        a[j]=a[j+1];
        a[j+1]=temp;
        isSorted=false;
        lastIndex=j;
      }
    }
    sortBorder=lastIndex;
    if(isSorted)
      break;
  }
}
//简单选择排序算法
void xuanze_sort(int a[],int length){
  for(int i=0;i<length;i++){
    for(int j=i+1;j<length;j++){
      int temp=0;
      if(a[i]>a[j]){
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
      }
    }
  }
}
void xuanze_sort1(int a[],int length){
  int left=0;
  int right=length-1;
  while(left<=right){
     int min=left;
     int max=left;
    for(int i=left;i<=right;i++){
      if(a[i]<a[min]){
        min=i;
      }
      if(a[i]>a[max]){
        max=i;
      }
    }
    swap(a[left],a[min]);
    if(left==max){
      max=min;
    }
    swap(a[right],a[max]);
    left++;
    right--;
  }
}
int main(int argc, char const *argv[]) {
  int a1[]={5,8,6,3,9,2,1,7};
  int a2[]={5,8,6,3,9,2,1,7};
  int a3[]={5,8,6,3,9,2,1,7};
  int a4[]={5,8,6,3,9,2,1,7};
  int a5[]={5,8,6,3,9,2,1,7};
  int length1=sizeof(a1)/sizeof(int);
  Bubble_sort(a1,length1);
  Bubble_sort1(a3,length1);
  Bubble_sort2(a4,length1);
  for(int i=0;i<length1;i++){
    cout<<a1[i]<<" ";
  }
  cout<<endl;
  for(int i=0;i<length1;i++){
    cout<<a3[i]<<" ";
  }
  cout<<endl;
  for(int i=0;i<length1;i++){
    cout<<a4[i]<<" ";
  }
  cout<<endl;
  int length2=sizeof(a2)/sizeof(int);
  xuanze_sort(a2,length2);
  for(int i=0;i<length2;i++){
    cout<<a2[i]<<" ";
  }
  cout<<endl;
  xuanze_sort1(a5,length2);
  for(int i=0;i<length1;i++){
    cout<<a5[i]<<" ";
  }
  cout<<endl;
  return 0;
}

 结果展示:


 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值