关于C语言的三种基本排序(冒泡排序、简单的桶排序、快速排序)

关于C语言的三种基本排序(冒泡排序、简单的桶排序、快速排序):

1.冒泡排序:

   冒泡排序是:“邻居好说话”。每个数都与它自己右边的邻居相比较,满足条件就交换自己与邻居的位置,这样一个个比较下去,直到比较到最后一位数。这个过程类似气泡冒上水面的过程,我们称为“冒泡排序”;
   若有五个数需要按从小到大作比较,先拿第一个数出来,与余下4个数依次比较,比较n-1次。这轮比较完后,第五个数就成为了最小的数放在第五位。现在比较第2个数,第二个数现在处于第一位,依次与后面的3个数作比较(不需要与最后一位数比较,因为在上一轮循环中已经确定了最后一个数是最小的数),这轮比较n-2次,其余数以此类推,每轮比较(n-i)次。
   因为冒泡排序是双重循环嵌套,冒泡排序的时间复杂度非常高,达到O(n*n), 若遇到限制编译时间的题目,冒泡排序就很危险了。
//n个数经过冒泡排序由大到小输出 
#include<stdio.h>
int main()
{
 int i, j, n, t, a[101];   //n代表总共输入了n个数
 printf("共有n个数需要进行大小比较: ");
 scanf("%d", &n); 
 for(i = 0; i < n; i++)
 {
  scanf("%d", &a[i]);
 }
 for(i = 0; i < n - 1; i++)  //5个数只需要比较4次,n个数需比较n-1次
 {
  for(j = 0; j < n - i; j++) //第i个数只需比较n-i次
  {
   if(a[j] < a[j + 1])  //前面数字小于后面数字,就交换这两个数字 
   {
    t = a[j];
    a[j] = a[j + 1];
    a[j + 1] = t;
   } 
  } 
 } 
 for(i = 0; i < n; i++)
 {
  printf("%d ", a[i]);
 }
 getchar(); getchar();
 return 0;
}

2.简单的桶排序:

   桶排序的时间复杂度非常小,只有O(n),但是桶排序会占用很多空间,时间复杂度低但空间复杂度高。
   桶排序就像往小桶里插旗子,对应的桶中插入对应的旗子。
//n个数字从小到大排序
#include<stdio.h>
int main()
{
 int n, i = 0, t, j, a[1001]; //输入需要排序数字的个数,不超过1000个数 ,一个足够大的数组来储存输入的数
 printf("请输入共有多少个需要排序的数: "); 
 scanf("%d", &n);
 for(i = 0; i < 1000; i++) //初始化数组 
 {
  a[i] = 0;
 } 
 for(i = 0; i < n; i++)
 {
  scanf("%d", &t);
  a[t]++;     //记录输入数字个数,相应桶中旗子加一 
 }
 for(i = 0; i < 1000; i++) //遍历所有位数,打印相应数字 
 {
  for(j = 0; j < a[i]; j++)
  {
   printf("%d ", i);
  }
 }
 getchar(); getchar();
 return 0;
} 

3.快速排序:

   快速排序是种跳跃排序,平均时间复杂度是O(n*logn),但最坏的情况快排就变成了冒泡排序,两两比较,最坏的时间复杂度是O(n*n)。
   对一组数据进行快速排序首先要选定一个基准数,就是选出一个数作为参考,再用i和j两个指标来分别从左往右和从右往左扫描,以左边的数为基准数,那么右边的指标 j 先从右往左扫描(j--),之后从左往右扫描的指标 i 开始扫描(i++);j 和i 找到各自的对应数之后让相应的数进行交换,重复此过程直到指标i=j,此时让基准数和i跟j对应的数交换,此轮循环结束。
   此时基准数将这组数分成了左右两组,在左边组中选一个基准数,重复上述操作,直到最后左边只剩下基准数,再对右边进行同样操作。
   快速排序基于二分思想,每次基准数归位后都会把这组数分成左右两个部分,在这其中在进行排序。

注意:
当进行从小到大排序时,每次必须是右边指标 j 先走(找出比基准值小的数),因为当 i==j时,就会跟基准数进行交换,交换后需要保证基准数左边的数比基准数小,所以每次需要先找出比基准数小的数,也就是右指标 j 每次都得先走。
那当进行从大到小排序时,每次都得是大于基准数的指标先走。
快速排序的条件里一定要加入’=’,如果没有等号,会有一边的指标不能移动使一边的数值固定,进行交换时会使所有数字成为同一个数。

 while(i != j)       /*对应数的寻找及交换*/ 
 {
  while(a[j] >= temp && j > i)  /*右指标大于基准数并且右指标大于左指标时继续找,直到找到小于基准数或右指标小于等于左指标*/ 
  {
   j--; 
  }
  while(a[i] <= temp && i < j) 
  {
   i++;
  }
  if(i < j)       /*当左指标小于右指标时,交换两指标对应数的位置*/ 
  {
   t = a[i];
   a[i] = a[j];
   a[j] = t;
  }  
 } 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值