数据结构 || 八大排序

算法的评价从时间复杂度、空间复杂度、稳定性来分析
稳定性:如果排序之前A在A’的前面,排序后A还在A’的前面,则说明算法稳定,可以通过判断算法中有无跳跃交换,没有则稳定

4个稳定 直接插入 冒泡 归并 基数
4个不稳定 希尔 选择 快排 堆排序

在这里插入图片描述

1. 冒泡排序(沉石排序)Bubble Sort

  • 算法思想
    从第一个开始,两两比较,大的向后挪动,第一轮后,最后的元素就是最大的,继续进行下一轮,总共进行len-1轮,每次找待排序中的最大值(每次比较时都不与已排序好的数据进行比较)放到最后
时间复杂度 空间复杂度 稳定
O(n^2) O(1) 稳定
void BubbleSort(int *arr,int len)
{
   
   assert(arr != NULL);
   for(int i = 0;i < len-1;++i)  //循环次数
   {
     
      for(int j = 0;j+1 < len-i;++j)     //比较次数
      {
     
          if(arr[j] > arr[j+1])
          {
   
              int tmp = arr[j];
              arr[j] = arr[j+1];
              arr[j+1] = tmp;
          }
      } 
   }     
}                         
  • 优化:如果在其中某一轮时已经完全有序,如何停止,不用继续循环
    ~ 定义标记位,赋值为真,有交换时将其赋值为假,在每次一趟比较完毕时判断标记是true或false,true说明本趟比较中没有交换,后面的数据都大于之前的数据,说明该排序已经完全有序,则跳出整个循环
void BubbleSort(int* arr, int len)             //冒泡排序
{
   
	bool tag = true;   //优化标记  如果存在一次交换则tag为假  如果为真则没有交换数据 已经有序
	assert(arr != nullptr);
	for (int i = 0; i < len - 1; i++)
	{
          //比较趟数
		for (int j = 0; j + 1 < len - i; j++)
		{
          //每一次的比较   少一个
			tag = true;
			if (arr[j] > arr[j + 1])
			{
          //两两比较 前一个大于后一个 交换数据
				tag = false;   //有交换数据 还不是完全有序 将标记赋为假
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (tag)
		{
         //tag为真 说明不存在后面的数据比前面的大,数据已经有序,则跳出循环
			break;
		}
	}
}

2. 直接插入排序(InsertSort)

  • 算法思想
    从待排序队列中依次取出,放到已排序好的队列中,再次保持有序,重复直到完全有序
    默认第一个数据是有序的,每次从下标为1的数据进行插入,取出待插入的数据 tmp,将tmp与它之前的数据从右向左依次比较,当前面的数据大于tmp,则将前面的数据向后移动,直到找到前面的数据小于tmp,就将tmp插入到被比较的元素之后
  • 待排序队列越有序,直接插入排序越优解
时间复杂度 空间复杂度 稳定性
O(n^2) O(1) 稳定
void InsertSort(int *arr,int len)
{
   
    assert(arr != NULL);  //判空
    if(arr == NULL)
    {
   
        return ;
    }
    int tmp = 0;
    int j = 0;//j要定义在循环外面 方便tmp插入时找到插入位置
    for(int i = 1;i < len;++i)
    {
   //从待排序队列中取值 i从1开始 0号默认有序
        tmp = arr[i];   
        for(j = i-1;j >= 0;--j)
        {
    //j从右向左
            if(tmp < arr[j])
            {
     //大于tmp 向后移动一格
                arr[j+1] = arr[j];
            }
            else
            {
   
                break;//跳出本层循环
            }
        }
        arr[j+1] = tmp;//放到arr[j]的右边
    }
}

3. 希尔排序(shell sort)

由于直接插入排序的时间复杂度高,为了缩小时间复杂度,===>希尔排序
希尔排序 【特殊的直接插入排序】(ShellSort)
算法思想:
缩小增量排序 增量:互素,最后一个增量必须为1
对原始数据进行分组,按增量进行分组,对分出来的组调用直接插入排序
时间复杂度:O(n1.3)~O(n1.5) 空间复杂度:O(1) 稳定性:不稳定 【数据之间跳跃排序】
通过多次调用直接插入排序

gap[] ={5,3,1};

增量为5 gap = 5 调用直接插入排序

增量为3 gap= 3

增量为1 gap = 1 最后一个增量必须为1

static void Shell(int* arr, int len, int gap)
{
   
	assert(arr != nullptr);
	if (arr == NULL)
	{
   
		return;
	}
	int tmp ;
	int j ;
	for (int i = gap;</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构中的八大排序算法,是指常见的八种用于对数据进行排序的算法。这八种算法分别是冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序和基数排序。 冒泡排序是一种简单的排序算法,通过不断比较和交换相邻元素的位置,使得最大(或最小)的元素逐渐往后(或往前)移动。 选择排序是一种简单直观的排序算法,每次选择未排序序列中最小(或最大)的元素,放到已排序序列的末尾。 插入排序是一种简单直观的排序算法,将一个待排序的元素插入到已部分排序的数列中的合适位置。 希尔排序是一种改进的插入排序算法,通过将待排序数列分组,并对每个分组进行插入排序,然后逐渐减小分组规模,最后进行一次插入排序。 归并排序是一种分治思想的排序算法,将待排序数列不断分割成较小的数列,然后再将这些较小的数列按照顺序进行合并。 快速排序是一种分治思想的排序算法,通过选择一个中间的基准元素,将数列分割成两部分,然后分别对这两部分进行排序。 堆排序是一种利用堆这种数据结构排序算法,通过将待排序数列构建成一个大(或小)顶堆,然后逐步将堆顶元素与最后一个元素交换,并调整堆结构。 计数排序是一种非比较型的排序算法,通过统计待排序数列中每个元素出现的次数,然后依次输出即可。 基数排序是一种非比较型的排序算法,通过对待排序数列的每个位进行排序,依次从低位到高位进行。 这里简单介绍了八大排序算法的基本思想和实现方法。在实际应用中,不同的排序算法适用于不同的场景和要求,我们需要根据具体情况选择合适的算法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值