几种C语言经典排序算法笔记

几种C语言经典排序算法笔记

本人在复习也还在学习C语言,这里自己重新写了几个简单的经典排序算法,在这里做个小笔记以便查阅。网上关于相关算法的描述已经很多了,这里就简单描述一下,把代码实现放上。这是第一次尝试发博文,有意后面再多写一些,代码、文章还有不足的地方,还请各位大神不吝赐教,感谢!

1. 冒泡排序(Bubble Sort)

冒泡排序是交换排序的一种,非常经典的C语言算法。轻气泡上升,重气泡下沉,每一趟交换结束都会使本趟最轻的气泡上升到正确的位置。

void BubbleSort(int *list, int size)
{
 int i, j, tmp;
 for (i = 0; i < size - 1; i++)       //最多(size-1)趟排序
 {
  for (j = 0; j < size - i - 1; j++)  //最多一趟比较(size-1)次,比较次数逐趟递减
  {
   if (list[j] > list[j + 1])
   {
    tmp = list[j];
    list[j] = list[j + 1];
    list[j + 1] = tmp;
   }
  }
 }
}

最优时间复杂度O(n),最差时间复杂度O(n^2)。稳定排序。

2. 快速排序(Quick Sort)

快速排序也是交换排序的一种,由Hoare提出,思想基于分治法(Divide and Conquer)。选取某个记录的关键字设为基准,每一趟排序将待排序记录序列分为两部分,一部分记录的关键字小于基准,另一部分关键字大于基准,两部分序列分别位于基准两边。再对两边的子序列进行快速排序(递归)。

int partition(int *list, int low, int high)
{
 int tmp;
 int key = list[low];                 //基准
 int i = low;
 int j = low + 1;
 for (;j < high;j++)                  //high = size;(需扫描到最后一个记录)
 {
  if (list[j] < key)
  {
   tmp = list[j];
   list[j] = list[++i];
   list[i] = tmp;
  }
 }
 list[low] = list[i];
 list[i] = key;
 return i;
}
void QuickSort(int *list, int low, int high)
{
 if (low >= high)                     //这里的条件不要忘记
  return;
 int m = partition(list, low, high);  //返回中间基准的位置
 QuickSort(list, low, m);             //对应分治法中“j < high”,high = m
 QuickSort(list, m + 1, high);        //但是第m个记录本身不需再排序,右半部分从第m+1个开始排序
}

最优时间复杂度O(nlog2n),最差时间复杂度O(n^2)。非稳定排序。

3.插入排序(Insert Sort)

先把第一个记录看作为只含有一个记录的有序子序列,从第二个记录开始逐个将待排序记录按关键字插入当前的有序子序列。

void InsertSort(int *list, int size)
{
 int i, j, tmp;
 for (i = 1;i < size;i++)             //默认第一个记录为有序序列,从第二个记录开始待插入
 {
   tmp = list[i];
   j = i - 1;
   while ((j >= 0) & (list[j] > tmp)) //一开始用的list[i]来比较,失败,因为list[i]会被下一句更新,要用tmp
   {
    list[j + 1] = list[j];            //记录顺序后移
    j--;
   }
   list[j + 1] = tmp;
 }
}

最优时间复杂度O(n),最差时间复杂度O(n^2)。稳定排序。除了直接插入排序,还有折半插入排序。

4.希尔排序(Shell Sort)

希尔排序又称缩小增量排序,由D. L. Shell提出。选定一个增量d,整个待排序序列从首个记录开始按增量d分为若干子序列,对这些子序列进行插入排序。减小d,重复上述步骤。直到最后d=1,继续完成排序。

void ShellSort(int* list, int size)
{
 int i, j, tmp;
 int d = size / 2;
 while (d >= 1)
 {
  for (i = d;i < size;i++)
  {
   tmp = list[i];
   j = i - d;
   while ((j >= 0) & (list[j] > tmp))
   {
    list[j + d] = list[j];            //记录按增量d进行移动
    j = j - d;                        //保证每一组增量序列的每个记录的关键字都被比较到
   }
   list[j + d] = tmp;
  }
  d = d / 2;
 }
}

一般认为平均时间复杂度为O(n^1.3)。非稳定排序。

5.选择排序(Selection Sort)

选择排序是最符合人们思维习惯的一种排序方法。每趟排序从待排序序列中挑选出一个关键字最小(或最大)的记录放到相应的位置。

void SelectionSort(int* list, int size)
{
 int i, j, mi, tmp;
 for (i = 0;i < size - 1;i++)  //最多(size-1)趟
 {
  mi = i;
  for (j = i + 1;j < size;j++) //未排序序列的记录逐趟减少
  {
   if (list[j] < list[mi])
    mi = j;
  }
  tmp = list[mi];
  list[mi] = list[i];
  list[i] = tmp;
 }
}

最优、最差时间复杂度均为O(n^2)。非稳定排序。

最后是以上五个算法对随机生成的数组(20个0~100的整数)进行排序的结果(图上看不出什么区别),可以看到都成功了,目前没发现代码有什么逻辑上的错误。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值