vlambda博客
学习文章列表

数据结构——简易版桶排序,冒泡排序,快速排序(C实现)

问题:用户输入10个数字(范围0~10),从小到大排序。


一.简单的桶排序 —— O(M+N) 

M:桶的个数 N:待排序的个数

步骤:

  1. 数组建桶book[i],初始化book[i]均为0,数组角标即为该数字。(book[1]存1出现的次数,初始为0)

  2. 用户输入,for循环,从0到10,进行计数。(输入t,book[t]++)

  3. 遍历所有桶,出现几次就打印几次。

#include<stdio.h> int main(){  // 创建11个桶,每个桶初始存0  int book[11], i, j,t;  for( i = 0; i<11; i++)     book[i] = 0 ;   // 让用户输入5个数字,每次读入的存进去 计数++ for( i = 0; i < 5 ; i++){ scanf("%d",&t); book[t]++ ;  }  // 全部存到了桶中,打印出来每个桶  for ( i = 0 ; i<=11;i++)    for(j = 0; j<book[i];j++)      printf("%d ",i); return 0;}

上述弊端:

非常浪费空间。且若排小数无法实现。除此之外,我们假设存的是分数,但排名的是人名,也无法实现。



二.冒泡排序 —— O(N²)

基本思想:每次比较相邻元素,若顺序错误,相邻元素交换。

步骤:

  1. 若排n个数,n-1次循环,进行归位(自己不跟自己比)

  2. 每一趟:从第一位开始进行相邻两数比较,每一趟就找到了最大的那位往后面放,因此一趟就排好了一个。已经归位的就不用再进行比较。

核心:双重嵌套循环。


下面实例用冒泡排序解决分数比较,最后排列的是人名。

#include<stdio.h>int main(){ //先申请一个长度为100的作为备用 struct student a[100],k; int i,j,n; // 让用户输入究竟有几个数字 printf("请输入您需要排序的用户的个数:"); scanf("%d",&n);
for(i=1;i<=n;i++){ scanf("%s %d",&a[i].name,&a[i].score); printf("%d %d\n",a[i].name,a[i].score);    printf("%d %d\n",&a[i].name,&a[i].score);  }  //得到数字,开始比较 for(i=1;i<=n-1;i++){ for(j=1;j<=n-i;j++){ if(a[j].score<a[j+1].score){ k = a[j]; a[j] = a[j+1];        a[j+1] = k;        }  } }   for(i=1;i<=n;i++)    printf("%s\n",a[i].name); return 0;}

弊端:虽然解决了桶排序的弊端,但是时间复杂度高。



三.快速排序 ——O(NlogN)

基本思想:首位数为基准,左右两个各一个哨兵,右边为j,j先出发左移,找到比基准小的停下,左边为i,i找到比基准大的停下。

交换继续移动,重复过程,直到i和j碰头,基准数置于了中间。

两边无序数据继续采用上述步骤。

如下图:


#include<stdio.h>int a[101],n;
void quickSort(int left,int right){ // 左右端,开始定位 int i,j,temp; if(left>right) return; // 定基准,左i 右j int jz = a[left]; i = left; j = right;
//开始交换 ij while(i!=j)  { //先跑j,后跑i,用j找到小于基准的, 没有用等于号,总有一下i=j 这样我就跳出了 while(a[j]>=jz && j>i) j--;    while(a[i]<=jz && i<j) i++; //当i比j小的时候,且i和j没有相遇的时候 ,交换。 if(i<j){ temp = a[i]; a[i]=a[j]; a[j]=temp; } }
// 换完之后把基准给i a[left] = a[i];  a[i] = jz;  quickSort(left,i-1); quickSort(i+1,right); return; }
int main(){ int i,j; scanf("%d",&n);  for(i=1;i<=n;i++)    scanf("%d",&a[i]);  quickSort(1,n);  for(i=1;i<=n;i++)    printf("%d",a[i]);  return 0;}