C语言冒泡排序原理

#include <stdio.h>
#define N 5
//冒泡排序
void main()
{
int i,j,temp;
int a[N];

printf("\n input %d number: \n",N);
for(i=0;i<N;i++)//
{
scanf("%d",&a[i]);
}

for(i=0;i<N;i++)//起什么作用
{
for(j=0;j<N-i-1;j++)// 不明白N-i-1的原理
if(a[j]<a[j+1])//起什么作用
{
//是怎么交换2个值的?
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}

}
printf("\n output the number:\n");

for(i=0;i<N;i++)//输出数组a
{
printf("%d ",a[i]);
}
printf("\n");
}

经典排序算法 - 冒泡排序Bubble sort
原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,
这样一趟过去后,最大或最小的数字被交换到了最后一位,
然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子
例子为从小到大排序,
原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 |

第一趟排序(外循环)
第一次两两比较6 > 2交换(内循环)
交换前状态| 6 | 2 | 4 | 1 | 5 | 9 |
交换后状态| 2 | 6 | 4 | 1 | 5 | 9 |

第二次两两比较,6 > 4交换
交换前状态| 2 | 6 | 4 | 1 | 5 | 9 |
交换后状态| 2 | 4 | 6 | 1 | 5 | 9 |

第三次两两比较,6 > 1交换
交换前状态| 2 | 4 | 6 | 1 | 5 | 9 |
交换后状态| 2 | 4 | 1 | 6 | 5 | 9 |

第四次两两比较,6 > 5交换
交换前状态| 2 | 4 | 1 | 6 | 5 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

第五次两两比较,6 < 9不交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

第二趟排序(外循环)
第一次两两比较2 < 4不交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

第二次两两比较,4 > 1交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

第三次两两比较,4 < 5不交换
交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

第四次两两比较,5 < 6不交换
交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

第三趟排序(外循环)
第一次两两比较2 > 1交换
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

第二次两两比较,2 < 4不交换
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

第三次两两比较,4 < 5不交换
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

第四趟排序(外循环)无交换
第五趟排序(外循环)无交换

排序完毕,输出最终结果1 2 4 5 6 9

#include <stdio.h>
int main()
{
int i,j,temp;
int a[6]={6,2,4,1,5,9}; //6个元素
for(j=0;j<5;j++) //共进行5轮外循环
{ for (i=0;i<5-j;i++) //每轮内循环结束时,第(j+1)大的数排到正确的位置上(沉底)
if (a[i]>a[i+1]) //每次比较相信的二个数,若大小顺序不对,就交换它们相互位置
{ temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;}
}
for(i=1;i<6;i++) //输出排序后的所有元素
printf("%3d,",a[i] );
printf("\n");
return 0;
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-11-17
冒泡是第一次把最大的那个数或者最小的那个数搞到最后,第二次把第二大的或第二小的那个数搞到第二后,如此类推!第一个循环是控制循环次数。然后第二个循环就是拿来比较两个数的大小,从第一个数开始,第一个数跟第二个比较,如果你想把这个数组从小到大排序,那么如果第一个大过第二个,就把第一个跟第二个交换。然后就继续比较第二个和第三个,如此类推。因为每做完一次循环,大的那个数就跑到前面去了,因为后面的就不用比较了,所以就有J<N-I-1,如果写J<N,虽然是对的,但这样会加大了运算量,程序的时间就长了。减一是因为如果不减的话最后一次数组就会越界。交换那里,交换一定要用中间变量,不然是交换不了的。最后会变成两个相同的值!
不懂的话继续问吧,我会答的~!!
第2个回答  2013-11-17
你只要明白循环就OK了
第一个循环 外循环
第二个循环 内循环 
他执行的时候 虽然复杂 也是一步一步来的
for(i=0;i<N;i++)//起什么作用
这里是i从0到N一个一个来 i=0后  执行下面一句 for(j=0;j<N-i-1;j++)
当执行到for(j=0;j<N-i-1;j++)的时候又是一个循环啊 j=0到N-I-1 每等于一个数都要执行这一步if(a[j]<a[j+1])//起什么作用
{
//是怎么交换2个值的?
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
也就是说外循环里每走一步 内循环都必须执行完全以后再能跳转到外循环第二步  
这就要求了每一个数都与其他每个数都比较一次了
至于j<N-i-1 N-I是因为前面比较过了的不需要再比较了  N-1是因为不需要跟自己比较了
第3个回答  推荐于2018-05-28
for(i=0;i<N;i++)//起什么作用
{
for(j=0;j<N-i-1;j++)// 不明白N-i-1的原理
if(a[j]<a[j+1])//起什么作用
{
//是怎么交换2个值的?
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
这是冒泡的核心,感觉写法跟java差不多,不过这样写不太直观。

首先第一句是从第一个数起比较

N-i-1指的是每循环一轮,最大的数自然在最后。所以每次都要减i
而减1是因为它后面有一个当前数和后面的数对比。

if(a[j]<a[j+1])
指的是如果后面的数比前面的数大。则返回真,执行下面的语句。
否则不执行。

temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
如果后面的数大,那么就执行。具体的逻辑。
想将A和B的值互换,那么。
temp = A
A=B
B=temp
如果直接A=B,A原来的值就会不见了。本回答被网友采纳