手撕七大排序(一)

一. 排序的概念及其运用

1. 排序的概念

所谓排序 就是给你一堆数据 让你按照一个或多个关键字 让这一堆数据递增或者递减

2. 排序的运用

这个就很常见了 就拿我们买东西举例

我们最近想要去买个手机

那么应该怎么选呢?

最多人买的应该没错吧

于是我们想看看 哪个手机买的人最多 这个时候我们只需要点一下按照销量排序 我们就可以拿到我们需要的数据了

3. 常见的排序算法

我这里使用xmind整理了一份思维导图给大家

我们这篇博客主要需要学习的是插入排序和选择排序

二. 直接插入排序

1. 基础概念

插入排序其实就像我们拿到一副扑克牌

我们肯定是习惯将整个一副牌按照从小到大的顺序排好是吧

这个就是插入排序在我们现实生活中的运用

2. 代码表示

(我们这里的所有数据以小序为例)

我们这里先假设插入一个数字

首先插入排序我们是默认前面的数据是有序的

所以说我们插入一个元素需要三个数据才可以完成

第一个当然是指向我们数组的指针

第二个是目前数组内元素的个数 我们用这个来确定最后面的元素是哪个

第三个是我们需要插入的值

我们用它来插入

 代码表示如下

    //我们用end表示下标
    
    int end;
    //tmp储存end后的数据
    int tmp;
        while (end >= 0)
		{
			if (tmp < a[end])
			{
                //end往后挪 腾位置
				a[end + 1] = a[end];
				--end;
			}
            这里有两种情况 一种是比a[end]大 一种是比前面的值都小
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;

我们可以发现 这段代码没有问题

之后我们开始写整体的数组排序

这个时候我们只需要进行两次循环
(第一次循环将最前面一个元素当成是一个有序数组
第二次循环将最前面两个元素当成是一个有序数组
… … …)

代码表示如下

void InsertSort(int* a, int n)
{
	for (int i = 0; i < n-1; i++)
	{
		int end=i;
		int tmp=a[end+1];
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				--end;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

 我们来看看最后结果是什么样子的

可以完美运行

三. 希尔排序(shellsort) 

1. 基础概念

 

在了解希尔排序之前我们先了解下直接插入排序的时间复杂度

在完全逆序时 直接插入排序的时间复杂度最高 此时为 O(N^2)

在完全有序时 直接插入排序的时间复杂度最低 此时为 O(N)

所以说 只要让我们要排序的数字尽量有序 就能很大程度上降低时间复杂度

我们将这一步称为 预排序

2. 预排序

这里我们要引入一个 gap变量 我们将之称为间隔

从零起始位置开始 我们利用它们之间的间隔作为依据

建立N个不同的数组

并且这个时候我们将这个数组进行插入排序

之后我们不断缩小间隔 继续进行预排序

最后当gap等于1的时候再进行一次插入排序

3. 希尔排序代码

//希尔排序
//1.预排序 -- 目标:数组接近有序  分组插排
//2.直接插入排序
void ShellSort(int* a, int n)
{
	//gap>1 预排序
	//gap==1 直接插入排序
	int gap = n;
	while (gap > 1)
	{
		//gap/2到最后只能等于一 直接插入排序
		gap /= 2;
		for (int j = 0; j < gap; j++)
		{
			for (int i = j; i < n - gap; i += gap)
			{
				int end = i;
				int tmp = a[end + gap];
				while (end >= 0)
				{
					if (tmp < a[end])
					{
						a[end + gap] = a[end];
						end -= gap;
					}
					else
					{
						break;
					}
				}
				a[end + gap] = tmp;
			}
		}
	}

}

 整体代码表示如上

 以上便是本文所有内容,如有错误请各位大佬不吝赐教,感谢留言 

 

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值