C++ for循环带多判断条件的冒泡排序失效原因咨询
两个冒泡排序实现问题分析
实现1(无法完成排序)
using namespace std; void bubble_sort(vector<int> &a, int n) { for (int i = n - 1; i > 0; i--) { for (int j = 1; (j <= i) and (a[j - 1] > a[j]); j++) { std::swap(a[j], a[j - 1]); } } }
实现2(排序效果符合预期)
using namespace std; void bubble_sort(vector<int> &a, int n) { for (int i = n - 1; i > 0; i--) { for (int j = 1; j <= i ; j++) { if(a[j - 1] > a[j]) std::swap(a[j], a[j - 1]); } } }
错误原因说明
二者的核心差异是相邻元素逆序判断的位置,实现1将判断放在了内层for循环的继续条件中,这直接导致了排序失效。
C++中for循环的执行逻辑为:先执行初始化语句,之后判断循环条件,只有所有条件全部为真时才会进入循环体,只要任意一个条件为假,就会直接终止整个循环。
实现1的内层循环条件(j <= i) and (a[j - 1] > a[j])意味着:只要遍历过程中碰到某一对相邻元素是升序的(a[j-1] <= a[j]),整个内层循环就会直接停止,不会继续比较后面的相邻元素。比如待排序数组为[2,3,1]时,第一轮外层循环i=2,j从1开始,此时a[0]=2 < a[1]=3,不满足逆序条件,内层循环直接终止,j不会走到2,3和1永远不会被比较交换,最终数组无法完成排序。
而实现2的内层循环条件只有j <= i,j会遍历从1到i的所有位置,每一对相邻元素都会被比较:逆序就交换,升序就跳过继续遍历下一对,完全符合冒泡排序每一轮将未排序区间的最大值移动到区间末尾的逻辑,所以排序结果正确。
内容的提问来源于stack exchange,提问作者Artaxerxes
相关产品推荐
相关产品推荐

