Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2857316
  • 博文数量: 471
  • 博客积分: 7081
  • 博客等级: 少将
  • 技术积分: 5369
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-04 21:55
文章分类

全部博文(471)

文章存档

2014年(90)

2013年(69)

2012年(312)

分类: C/C++

2012-08-14 20:20:36

冒泡排序

冒泡排序(Bubble Sorting)的基本思想是:
设待排序n个元素存放在数组a[n]中,无序区范围初始为(a(0),a(1),a(2),...,a[n-1]),冒泡排序方法是在当前无序区内,从最上面的元素a[0]开始,对每两个相邻的元素a[i+1]和a[i](i=0,1,...,n-1)进行比较,且使值较小的元素换至值较大的元素之上(若a[i]>a[i+1],则a[i]和a[i+1]的值互换),这样经过一趟冒泡排序后,假设最后下移的元素为a[k],则无序区中值较大的几个元素到达下端并从小到大依次存放在a[k+1],a[k+2],...a[n-1]中,这样无序区范围变为(a[0],a[1],a[2],...,a[k])。在当前无序区内进行下一趟冒泡排序。这个过程一直到某一趟排序中不出现元素交换的动作,排序结束。整个排序过程最多执行n-1遍。这种排序方法是通过相邻元素之间的比较与交换,使值较小的元素逐渐从后部移向前部(从下标较大的单元移向下标较小的单元),就象水底下的气泡一样逐渐向上冒。故称为冒泡排序法。

冒泡排序的优化算法 
是减少了冒泡排序外面的循环的次数,如果在第K项后没有产生交换,则K项之后所有的项必定有序,如果flag=0则说明整个数组都有序,则退出… 

点击(此处)折叠或打开

  1. #include
  2. /*升序排序,
  3. 第一趟扫描完毕时,"最轻"的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置R[1]上。
  4. 第二趟扫描 扫描R[2..n]。扫描完毕时,"次轻"的气泡飘浮到R[2]的位置上……
  5. 最后,经过n-1 趟扫描可得到有序区R[1..n]
  6. */
  7. void bubbleSort(int a[],int length)
  8. {
  9.     int flag=1;//如果有交换过,则等于1,无交换过即本来已经有序,直接退出
  10.     for(int i=0;(flag==1)&&i
  11.     {
  12.          flag=0;//本趟排序开始前,交换标志应为假
  13.          for(int j=length-1;j>i;j--)
  14.          {
  15.             if(a[j]
  16.             {
  17.                 int temp=a[j];
  18.                 a[j]=a[j-1];
  19.                 a[j-1]=temp;
  20.                 flag=1;//如果有交换过,则等于1,无交换过即本来已经有序,直接退出
  21.             }
  22.          }
  23.      }
  24. }
  25. int main()
  26. {
  27.     //int a[10]={9,6,10,5,8,3,2,1,11,12};
  28.     //int a[10]={1,2,3,4,5,6,7,8,9,10};
  29.     int a[10]={10,9,8,7,6,5,4,3,2,1};
  30.     bubbleSort(a,10);
  31.     for(int i=0;i<10;i++)
  32.     printf("%d ",a[i]);
  33.     getchar();
  34.     return 0;
  35.     
  36. }

  37. //输出1 2 3 4 5 6 7 8 9 10

1、算法思想
     快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。

(1) 分治法的基本思想
     分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。

(2)快速排序的基本思想
     设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为:
①分解: 
    
 在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
  注意:
     划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]):
     R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys
                  其中low≤pivotpos≤high。
②求解: 
     
通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。 

快速排序具有最好的平均性能(average behavior),但最坏性能(worst case behavior)和插入排序

相同,也是O(n^2)。比如一个序列5,4,3,2,1,要排为1,2,3,4,5。按照快速排序方法,每次只会有一个数据进入正确顺序不能把数据分成大小相当的两份,很明显,排序的过程就成了一个歪脖子树,树的深度为n,那时间复杂度就成了O(n^2)。尽管如此,需要排序的情况几乎都是乱序的,自然性能就保证了。据书上的测试图来看,在数据量小于20的时候,插入排序具有最好的性能。当大于20时,快速排序具有最好的性能,归并(merge sort)和堆排序(heap sort)也望尘莫及,尽管复杂度都为nlog2(n)。



点击(此处)折叠或打开

  1. #include

  2. int partition(int a[],int left,int right)
  3. {
  4.     int i=left;
  5.     int j=right;
  6.     int temp=a[i];
  7.     while(i
  8.     {
  9.         while(i=temp)
  10.             j--;
  11.             if(i
  12.                 a[i]=a[j];
  13.         while(i
  14.             i++;
  15.             if(i
  16.                 a[j]=a[i];
  17.     }
  18.     a[i]=temp;
  19.     return i;
  20. }
  21. void quickSort(int a[],int left,int right)
  22. {
  23.     int dp;
  24.     if(left
  25.     {
  26.         dp=partition(a,left,right);
  27.         quickSort(a,left,dp-1);
  28.         quickSort(a,dp+1,right);
  29.     }
  30. }

  31. int main()
  32. {
  33.     int a[9]={5,4,9,1,7,6,2,3,8};
  34.     quickSort(a,0,8);
  35.     for(int i=0;i<9;i++)
  36.     {
  37.         printf("%d ",a[i]);
  38.     }
  39.     return 0;
  40. }



阅读(1721) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~