冒泡算法
原理
依次比较相邻的数字,如果前一个比后一个大(小)就把他们调换位置
思路
假设为升序排序
1.比较第1个数和第2个数,将较大的数放在右边
2.比较第2个数和第3个数,将较大的数放在右边
…
3.比较第n-1个数和第n个数,将较大的数放在右边,此时,最右边的数为该序列最大的数,已排好序,不再参加后续的比较
4.第二趟依次比较第1个数到n-1个数后,最后一个数为第2大的数
5.第三趟依次比较第1个数到n-2个数后,最后一个数为第3大的数
6.以此类推,每次比较的数越来越少,知道将所有的数排完序
分析
序列有n个数,需要经行n-1趟排序
每完成一趟比较,将一个数放置在它的位置,下一趟比较的数据数少一
复杂度
如果序列本来就是升序的,那么一趟就可以完成排序,不需要数据之间交换位置,时间上的花销为 ,复杂度为 ,如果在代码中设置一个标志位来标志序列是否已经排好序,则可以达到
如果序列是降序的,那么需要n-1趟排序,每一次比较都要换位,时间上的花销为 ,主要将时间花在交换数据上,时间复杂度为
空间复杂度为
鸡尾酒排序
冒泡排序改进
冒泡排序时一个方向的从头到尾相互比较,鸡尾酒排序是从头到尾将最大的数放在后面,再从尾到头将最小的数放前面
代码
# include<stdio.h>
void swap(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
//冒泡排序
void bubble(int A[], int n){
int i, j;
for (i = 0; i < n - 1; i++)
for (j = 0; j < n - 1 - i; j++)
if (A[j] > A[j + 1])
swap(&A[j], &A[j + 1]);
}
//冒泡排序最优O(n)的情况
void bubble_2(int A[], int n){
int i, j;
int flag;
for (i = 0; i < n - 1; i++){
flag = 0;
for (j = 0; j < n - 1 - i; j++)
if (A[j] > A[j + 1]){
swap(&A[j], &A[j + 1]);
flag = 1;
}
if (flag == 0) // 即没有进行数字的交换,已经排好序
break;
}
}
//排序,双向,从左至右,从右至左冒泡
void cocktail(int A[], int n){
int left = 0, right = n - 1, i;
while (left<right){
for (i = left; i<right; i++)
if (A[i]>A[i + 1])
swap(&A[i], &A[i + 1]);
right--;
for (i = right; i>left; i--)
if (A[i - 1]>A[i])
swap(&A[i - 1], &A[i]);
left++;
}
}
int main() {
int A[] = {2, 5, 7, 3, 4, 1, 9, 6, 8};
int n = sizeof(A) / sizeof(int);
bubble(A, n);
for (int i = 0; i < n; i++)
printf("%d ", A[i]);
}