冒泡排序及其改进算法

来源:互联网 发布:淘宝儿童折叠床 编辑:程序博客网 时间:2024/05/22 04:43
1. 冒泡排序的思想
冒泡排序是一种交换排序算法,他的思想原理是自下向上进行扫描,扫描过程中相邻关键词两两对比,若为逆序则进行记录交换,一次扫描结束后可以确定一个元素的位置。重复扫描直至没有记录需要交换为止。
2. 复杂度分析
最好的情况:正序,此时需要进行1次扫描,其中n-1次比较,0次交换,所以时间复杂度为O(n),空间复杂度为O(1);
最坏的情况:逆序,此时需要进行(n-1)次扫描,其中(n-1)+(n-2)+…+1=n(n-1)/2次扫描,其中n(n-1)/2次比较,3n(n-1)/2次交换,所以时间复杂度为O(n^2),空间复杂度为O(1);
平均情况:时间复杂度为O(n^2),空间复杂度为O(1)。
3. 改进方法
(1) 设置交换标志位swap。若一次扫描中没有记录发生交换,说明有序,无需下次扫描(上述算法中已使用)。
(2) 保存最后一次记录交换的位置,下次扫描进行到此位置开始即可。因为没有记录交换的部分已经有序。
算法实现如下:
(3) 双向扫描。对于两头大中间有序的序列,双向扫描可以降低扫描次数,提高效率。
(4) 快速排序。
4.算法实现
/*
*作者:辣汤胡
*日期:2017-11-22
*代码功能:通过C语言实现冒泡排序算法
*包含两个冒泡排序:设置有交换标志位的冒泡和有保存交换位置的冒泡的改进
*集成开发环境:Microsoft Visual Studio 2015
*/
#include <stdio.h>
#include <assert.h>
//include<stdlib.h.h>
void bubble1(int *R, int n)  
{
 int i, j, swap,temp;
 for (i = 0; i < n; i++)
 {
  swap = 0;
  for (j = n; j > i; j--)
  {
   if (R[j] < R[j - 1])
   {   temp = R[j - 1]; R[j - 1] = R[j]; R[j] = temp;
    swap = 1;
   }
  }
  if (!swap) break;     //设置交换标志位swap,若一次扫描中没有发生交换说明已经有序,无需下次扫描
 }
}
void bubble2(int *R, int n)
{
 int i=0, j, k,temp;
 while (i < n)
 {
  k = n;
  for (j = n; j>i; j--)
  {
   if (R[j] < R[j - 1])
   {
    temp = R[j-1]; R[j-1] = R[j]; R[j] = temp;
    k = j;
   }
  }
  i=k;     //保存最后一次交换的位置k,下次扫描到此位置即可,1到k-1已经有序
 }
}
//输出函数
void shuchu(int *R, int n)
{
 int i;
 for (i = 0; i < n; i++)
 {
  printf("%4d", R[i]);
 }
printf("\n");
}
//验证两种冒泡排序的有效性
void test(void (*bubble)(int *R, int n))
{
 int R[] = { 3,5,7,9,2,4,6,8,0,1 };
 int n = 9;
 bubble(R, n);
 int i;
 printf("冒泡排序的输出为:\n");
 for (i = 0; i <n; i++)
 {
  printf("%2d", R[i]);
 }
 printf("\n");
}
int main()
{
 test(bubble1);
 test(bubble2);
 return 0;
}