《啊哈!算法》学习笔记——简单桶排序,冒泡排序,快速排序

简单的桶排序

借助于一个一维数组,利用数组的下标存储需要排序的数字。刚开始的时候,将数组的值进行初始化为0,表示数组下标所代表的数字没有出现过,之后开始处理数字,出现过的数字,则修改数组下标相应数字的值。假如出现数字3,则修改a[3]的值,对应a[3]++。最后循环嵌套按照相应要求输出排序后数字即可。

例:对n个0-1000之间的整数进行从小到大排序。
代码:
#include <stdio.h>
int main(){
	int n,i,j,num;
	int count[1001]={0};	//将数组的值初始化为0
	scanf("%d",&n);
	for(i=0;i<n;i++){		//循环输入n个数 
		scanf("%d",&num);	
		count[num]++;		//将输入数字进行计数 
	}
	//遍历0-1000之间的数字
	for(i=0;i<1001;i++){	//从大到小则为for(i=1000;i>=0;i--) 
		for(j=1;j<=count[i];j++){
			printf("%d ",i);
		}
	} 
	return 0;
}
输入样例:

10
8 100 50 22 15 6 1 1000 999 0

输出样例:

0 1 6 8 15 22 50 100 999 1000

时间复杂度O(M+N),如果需要排序的数字范围特别大,则非常的浪费空间。如果出现小数,则不能使用了。

冒泡排序

冒泡排序的基本思想是:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。
每一趟排序只能将一个数字归位,如果有n个数进行排序,则要进行n-1趟操作。

代码:
#include <stdio.h>
int main(){
	int n,i,j,temp;
	int a[100];
	scanf("%d",&n);
	for(i=0;i<n;i++){	//循环输入n个数 
		scanf("%d",&a[i]);
	}
	//冒泡排序核心部分
	for(i=0;i<n-1;i++){		//进行n-1趟排序 
        for(j=0;j<n-i-1;j++){	// -1防止判断索引越界,-i不与每趟排序完成数字比较 
            if(a[j] > a[j+1]){    //从小到大排序         
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }
    for(i=0;i<n;i++){
    	printf("%d ",a[i]);
	} 
	return 0;
}
输入样例:

10
8 100 50 22 15 6 1 1000 999 0

输出样例:

0 1 6 8 15 22 50 100 999 1000

时间复杂度O(N2)

快速排序

假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数。为了方便,就让第一个数6作为基准数。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边。
初始序列“6 1 2 7 9 3 4 5 10 8”两端开始“探测”。先从右往左找一个小于6的数,再从左往右找一个大于6的数,然后交换他们。这里可以用两个变量 i 和 j ,分别指向序列最左边和最右边。我们为这两个变量起个好听的名字“哨兵i”和“哨兵j”。刚开始的时候让哨兵i指向序列的最左边(即i=1),指向数字6。让哨兵j指向序列的最右边(即j=10),指向数字8

《啊哈!算法》学习笔记——简单桶排序,冒泡排序,快速排序
《啊哈!算法》学习笔记——简单桶排序,冒泡排序,快速排序
《啊哈!算法》学习笔记——简单桶排序,冒泡排序,快速排序
《啊哈!算法》学习笔记——简单桶排序,冒泡排序,快速排序
此时探测结束,将基准数6与3进行交换
《啊哈!算法》学习笔记——简单桶排序,冒泡排序,快速排序

代码:
#include <stdio.h>
int a[1000];
//快速排序核心
void quickSort(int left,int right){
	int i,j,t,temp;
	if(left>right)
		return;
	temp=a[left];	//temp中存储基准数 
	i=left;
	j=right;
	while(i!=j){
		//顺序很重要,要先从右往左
		while(a[j]>=temp && i<j)
			j--;
		//再从左到右
		while(a[i]<=temp && i<j)
			i++;
		if(i<j){
			t=a[i];
			a[i]=a[j];
			a[j]=t;
		}
	} 
	a[left]=a[i];
	a[i]=temp;
	quickSort(left,i-1);//继续处理左边 
	quickSort(i+1,right);//继续处理右边 
	return;
}
int main(){
	int n,i;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
		
	quickSort(0,n-1);//调用快速排序
	
	for(i=0;i<n;i++)	//输出排序结果
		printf("%d ",a[i]);
	return 0;
}
输入样例:

10
6 1 2 7 9 3 4 5 10 8

输出样例:

1 2 3 4 5 6 7 8 9 10

平均时间复杂度O(NlogN),快速排序是基于“二分”思想的一种排序。