冒泡排序:
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
原理:
重复扫描待排序序列,并比较每一对相邻的元素,当该对元素顺序不正确时进行交换。一直重复这个过程,直到没有任何两个相邻元素可以交换,就表明完成了排序。
1·嵌套循环,遍历数组:
将一乱序数组排列为升序:
3 | 4 | 2 | 1 | 6 | 9 | 7 | 8 | 5 | 0 |
第一次排序:
3 | 2 | 1 | 4 | 6 | 7 | 8 | 5 | 0 | 9 |
......
每一次遍历数组完成时,数组末位会置成该数组内部最大的元素,故在下一次遍历数组时,不需要再对其进行比较;每次遍历时控制为 sz - 1 - i 次。
到最后一次排序时,第一位元素已经是最小的元素,故不需要在排序,总共需要进行 size - 1 次排序。
代码如下:
void bubble_sort(int arr[], int sz)
{
for (int i = 0; i < sz - 1; i++)//控制排序次数
{
for (int j = 0; j < sz - 1 - i; j++)//遍历数组,进行交换
{
if (arr[j] > arr[j + 1])//若该元素大于后一位,则进行交换
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
2·优化_嵌套循环,遍历数组:
思路:
可能在第n次排序完成后,数组已经有序,就不再需要进行排序,故设置一个标志 flag 。
当遍历数组时发生交换,将 flag 置为 0 ;当发现在遍历数组时未发生交换, flag 则不会发生改变,则证明数组已经有序,跳出排序循环。
void bubble_sort(int arr[], int sz)
{
for (int i = 0; i < sz - 1; i++)
{
int flag = 1;//检验是否发生交换,若无交换,则证明数组已经有序
for (int j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
flag = 0;//只要数组发生交换,就把flag置为0
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
if (flag)
break;
}
3·双端冒泡:
思路:
第一次排序完成后,最大的元素已经在最后一位;此时,若由倒数第二位向前再次遍历,将剩余元素里最小的以为放到第一位,则完成双端冒泡。
void bubble_sort(int arr[], int sz)
{
int low, high, flag, i;
low = 0;
high = sz - 1;
while (low < high)
{
flag = 1;//检验是否发生交换,若无交换,则证明数组已经有序
//把元素中最大的排到最后一位
for (i = low; i < high; i++)
{
if (arr[i] > arr[i + 1])
{
flag = 0;
int tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
}
}
//若已经有序,则跳出排序循环
if (flag)
{
break;
}
//把剩余元素里最小的排到第一位
high--;
for (i = high; i > low; i--)
{
if (arr[i] < arr[i - 1])
{
int tmp = arr[i];
arr[i] = arr[i - 1];
arr[i - 1] = tmp;
}
}
low++;
}
}