您的位置:首页 > 编程语言 > Java开发

排序趟[置顶] Java和C实现的冒泡排序(基本思想)

2013-05-23 20:47 267 查看
本篇文章朋友在北京喝咖啡的时候突然想到的...最近就有想写几篇关于排序趟的笔记,所以回家到之后就奋笔疾书的写出来发表了

交换排序的基本思想是:两两比拟待排序记录的关键字,发现两个记录的次序相反时即停止交换,直到没有反序的记录为止。
应用交换排序基本思想的重要排序方法有:冒泡排序和快速排序。

冒泡排序

1、排序方法

将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看做是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的准则,从下往上扫描数组R:凡扫描到违反本准则的轻气泡,就使其向上"飘浮"。如此重复停止,直到最后任何两个气泡都是轻者在上,重者在下为止。
(1)初始
R[1..n]为无序区。

(2)第一趟扫描
从无序区底部向上依次比拟相邻的两个气泡的重量,若发现轻者在下、重者在上,则交换二者的位置。即依次比拟(R
,R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);对于每对气泡(R[j+1],R[j]),若R[j+1].key<R[j].key,则交换R[j+1]和R[j]的内容。
第一趟扫描终了时,"最轻"的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置R[1]上。

(3)第二趟扫描
扫描R[2..n]。扫描终了时,"次轻"的气泡飘浮到R[2]的位置上……
最后,经过n-1趟扫描可得到有序区R[1..n]
注意:
第i趟扫描时,R[1..i-1]和R[i..n]分别为以后的有序区和无序区。扫描仍是从无序区底部向上直至该区顶部。扫描终了时,该区中最轻气泡飘浮到顶部位置R[i]上,结果是R[1..i]变成新的有序区。

2、冒泡排序过程示例
对关键字序列为4938659776132749的文件停止冒泡排序的过程【参见动画演示】

3、排序算法
(1)分析
因为每一趟排序都使有序区增加了一个气泡,在经过n-1趟排序之后,有序区中就有n-1个气泡,而无序区中气泡的重量总是大于即是有序区中气泡的重量,所以整个冒泡排序过程最多需要停止n-1趟排序。
若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满意轻者在上,重者在下的准则,因此,冒泡排序过程可在此趟排序后终止。为此,在下面给出的算法中,引入一个布尔量exchange,在每趟排序开始前,先将其置为FALSE。若排序过程中产生了交换,则将其置为TRUE。各趟排序结束时检查exchange,若未曾产生过交换则终止算法,不再停止下一趟排序。

(2)具体算法
voidBubbleSort(SeqListR)
{//R(l..n)是待排序的文件,采用自下向上扫描,对R做冒泡排序
inti,j;
Booleanexchange;//交换标记
for(i=1;i<n;i++){//最多做n-1趟排序
exchange=FALSE;//本趟排序开始前,交换标记应为假
for(j=n-1;j>=i;j--)//对以后无序区R[i..n]自下向上扫描
if(R[j+1].key<R[j].key){//交换记录
R[0]=R[j+1];//R[0]不是哨兵,仅做暂存单元
R[j+1]=R[j];
R[j]=R[0];
exchange=TRUE;//产生了交换,故将交换标记置为真
}
if(!exchange)//本趟排序未产生交换,提前终止算法
return;
}//endfor(外循环)
}//BubbleSort

****************************************************************************************************************************************************************************************

/*
冒泡排序基本思想
将n个记录看做按纵向排列,每趟排序时自下至上对每对相邻记录停止比拟,若次序不符合要求(逆序)就交换。每趟排序结束时都能使排序范围内关键字最小的记录象一个气泡一样升到表上端的对应位置,整个排序过程共停止n-1趟,依次将关键字最小、次小、第三小…的各个记录“冒到”表的第一个、第二个、第三个…位置上。


初态第1趟第2趟第3趟第4趟第5趟第6趟第7趟
12121212121212
38202020202020
20382525252525
46253838383838
38463838383838
74384646464646
91747474747474
25919191919191
*/
//打印数组
voidPrintArray(intarray[],intn)
{

inti;
for(i=0;i<n;i++)
printf("%d",array[i]);
printf("\n");

}
//冒泡排序
voidBubbleSort(intarray[],intn)
{

inti=0;
intj=0;
inttemp=0;
intflag=0;
for(i=0;i<n-1;i++)/*外循环控制排序的总趟数*/
{
flag=0;/*本趟排序开始前,交换标记应为假*/
for(j=n-1;j>i;j--)/*内循环控制一趟排序的停止*/
{
if(array[j]<array[j-1])/*相邻元素停止比拟,若逆序就交换*/
{
temp=array[j];
array[j]=array[j-1];
array[j-1]=temp;
flag=1;/*产生了交换,故将交换标记置为真*/
}

}
if(flag==0)/*本趟排序未产生交换,提前终止算法*/
break;
/*
printf("第%d趟排序结果:\n",i+1);
PrintArray(array,n);
*/

}
}

voidTestBubbleSort()
{
intarray[8]={38,20,46,38,74,91,12,25};
BubbleSort(array,8);
PrintArray(array,8);
}

****************************************************************************************************************************************************************************************

问题

有一数组a,长度为n,把数组中的元素从小到大重新排列

思绪

从0到n-1,两两比拟数组中的元素,如果前者大于后者,则交换之(如a[0]>a[1],则交换a[0]和a[1])。作一趟冒泡排序后,最大值就在最后一个位置a[n-1]上了。然后对余下的0到n-2个元素作第二趟冒泡排序,次最大值就去到倒数第二个位置a[n-2]上了,如此类推。

例如对10,-3,5,34,-34,5,0,9停止排序

第一趟:-3,5,10,-34,5,0,9,34

第二趟:-3,5,-34,5,0,9,10,34

第三趟:-3,-34,5,5,0,9,10,34

第四趟:-34,-3,5,0,5,9,10,34

第五趟:-34,-3,0,5,5,9,10,34

这时不再产生交换,排序结束。

核心代码:

每日一道理

生活中受伤难免,失败跌倒并不可怕,可怕的是因此而一蹶不振,失去了对人生的追求与远大的理想。没有一个人的前进道路是平平稳稳的,就算是河中穿梭航行的船只也难免颠簸,生活中所遇上的坎坷磨难不是偶尔给予的为难,而是必然所经受的磨练。

staticvoidsort(int[]array){
intlength=array.length;
inttemp;
booleanisSort;
for(inti=1;i<length;i++){
isSort=false;
for(intj=0;j<length-i;j++){
if(array[j]>array[j+1]){
//交换
temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
isSort=true;
}
}
if(!isSort)break;//如果没有产生交换,则退出循环
}
}
全体代码:

packagecom.icescut.classic.algorithm;
publicclassBubbleSort{
publicstaticvoidmain(String[]args){
int[]array={10,-3,5,34,-34,5,0,9};//testdata
sort(array);
for(intel:array){
System.out.print(el+"");
}
}
staticvoidsort(int[]array){
intlength=array.length;
inttemp;
booleanisSort;
for(inti=1;i<length;i++){
isSort=false;
for(intj=0;j<length-i;j++){
if(array[j]>array[j+1]){
//交换
temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
isSort=true;
}
}
if(!isSort)break;//如果没有产生交换,则退出循环
}
}
}
****************************************************************************************************************************************************************************************

冒泡排序(BubbleSort)是一种简略的排序算法。它重复地访问过要排序的数列,一次比拟两个元素,如果他们的顺序错误就把他们交换过去。访问数列的任务是重复地停止直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经过交换慢慢“浮”到数列的顶端。

冒泡排序算法的运作如下:

比拟相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作一样的任务,从开始第一对到结尾的最后一对。在这一点,最后的元素应当会是最大的数。

针对所有的元素重复以上的步调,除了最后一个。

持续每次对越来越少的元素重复下面的步调,直到没有任何一对数字需要比拟。

冒泡排序的过程图:



代码:

publicclassBubbleSort{
publicstaticvoidmain(String[]args){
intscore[]={67,69,75,87,89,90,99,100};
for(inti=0;i<score.length-1;i++){//最多做n-1趟排序for(intj=0;j<score.length-i-1;j++){//对以后无序区间score[0......length-i-1]停止排序(j的范围很关键,这个范围是在逐步缩小的)if(score[j]<score[j+1]){//把小的值交换到前面inttemp=score[j];
score[j]=score[j+1];
score[j+1]=temp;
}
}
System.out.print("第"+(i+1)+"次排序结果:");
for(inta=0;a<score.length;a++){
System.out.print(score[a]+"\t");
}
System.out.println("");
}
System.out.print("终究排序结果:");
for(inta=0;a<score.length;a++){
System.out.print(score[a]+"\t");
}
}
}




文章结束给大家分享下程序员的一些笑话语录:小沈阳版程序员~~~\n程序员其实可痛苦的了......需求一做一改,一个月就过去了;嚎~\n需求再一改一调,一季度就过去了;嚎~\n程序员最痛苦的事儿是啥,知道不?就是,程序没做完,需求又改了;\n程序员最最痛苦的事儿是啥,知道不?就是,系统好不容易做完了,方案全改了;\n程序员最最最痛苦的事儿是啥,知道不?就是,系统做完了,狗日的客户跑了;\n程序员最最最最最痛苦的事儿是啥,知道不?就是,狗日的客户又回来了,程序给删没了!

---------------------------------
原创文章By
排序和趟
---------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: