经典排序算法_冒泡算法

冒泡算法

原理

依次比较相邻的数字,如果前一个比后一个大(小)就把他们调换位置

思路

假设为升序排序
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 ( n 1 ) 2 \frac{n(n-1)}{2} ,复杂度为 O ( n 2 ) O(n^2) ,如果在代码中设置一个标志位来标志序列是否已经排好序,则可以达到 O ( n ) O(n)

如果序列是降序的,那么需要n-1趟排序,每一次比较都要换位,时间上的花销为 3 n ( n 1 ) 2 \frac{3n(n-1)}{2} ,主要将时间花在交换数据上,时间复杂度为 O ( n 2 ) O(n^2)

空间复杂度为 O ( 1 ) O(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]);
}
发布了23 篇原创文章 · 获赞 0 · 访问量 215

猜你喜欢

转载自blog.csdn.net/qq_37876050/article/details/104286460
今日推荐