首页 > 编程语言 > 详细

关于冒泡排序的一些改进

时间:2017-04-04 16:08:45      阅读:190      评论:0      收藏:0      [点我收藏+]

---恢复内容开始---

 冒泡排序:

一般冒泡排序我们都很容易想到以下的方法,但事实上冒泡排序还有一些地方可以改进。最主要的方法是引入标志位。

void print(int *p, int length) {
    for (int i = 0; i < length; i++) {
        cout << p[i] << ",";
    }
}

void BubbleSort(int *p, int length) {
  for (int i = 0; i < length; i++) {
    for (int j = 0 ; j < length-i-1; j++) {
      if (p[j]>p[j+1]) {
        swap(p[j], p[j+1]);
      }			
    }
  }
    print(p,length)
}
	
int main()
{
  int arr[7] = {2,4,5,1,7,3,6};
  int length = sizeof(arr) / sizeof(int);
  BubbleSort(arr,length);
  return 0;
}    

  

 技术分享

 (最后一行是输出的结果)

  

改进方案一

看到上面运行结果,第4,5,6,7趟都是没有发生逆序对的互换,但算法还是依旧进行了比较。

为此,引入一个排序标志。

void BubbleSort(int *p, int length) {
  for (int i = 0; i < length; i++) {
    bool sorted = true;
    for (int j = 0 ; j < length-i-1; j++) {
      if (p[j]>p[j+1]) {
        swap(p[j], p[j+1]);
        sorted = false;          //如果有逆序对,说明还没有排好序
      }	
    }

    if (sorted) {    //没有逆序对,说明已经排好序了,可以直接输出。
      break;
    }
  }
  print(p,length);
}

技术分享

 (最后一行是输出的结果)

由此可见,到第4趟发现没有逆序对了,就会停止。

假设这段有序的区间是[0,n1/2),那么按照这个算法算出来的复杂度就是 O(n2/3) ,即 n*n1/2

 

改进方案二(比方案一更优化)

由方案一我们得到启发,如果我们能够对已经排好序的部分不再去比较的话,那么性能会更好。例如

假设int arr[12] = {2,4,5,1,7,3,6,8,9,10,11,12};

如果我们得到6的位置的话,那么6之后的我们就不去比较了。

那6这个位置怎么得到呢?

我们可以设置一个变量,记录最后一次逆序对发生变化的位置。得到的就是排好序的部分里面排在最前的位置,也就是6的位置。

 

void BubbleSort(int *p, int length) {
  int pos_temp = length - 1;
  for (int i = 0; i < length; i++) {
    int pos = pos_temp;
    for (int j = 0 ; j < pos; j++) {
      if (p[j]>p[j+1]) {
        swap(p[j], p[j+1]);
        pos_temp = j;//记录最后一次逆序对发生变化的位置
      }	
    }

    if (pos== pos_temp) {//如果没变过,说明没有逆序对了,可以直接输出
      break;
    }
  }
  print(p,length);
}

  

 技术分享

如上图,进行过一趟比较之后,我们就记录好了6的位置,也就是第6位。那么此后我们就不管6之后的数据了。

 

关于冒泡排序的一些改进

原文:http://www.cnblogs.com/yuqinweb/p/6665046.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!