数据结构排序(一)

༺ 个人主页 · 纪念229 ༻

🏠我的博客主页🏠

༒专栏目录:《数据结构》༒

༒专栏目录:《算法》༒

༒专栏目录:《MySQL数据库》༒

༒专栏目录:《前端开发》༒

༒其它有趣的计算机知识༒

༺世上本没有路,走的人多了自然就有了༻


这篇文章讲述的是数据结构中的一些常见的排序方式,希望对你有所帮助


文章目录


1.直接插入排序

代码展示

c 复制代码
void InsertSort(int* arr, int n);
c 复制代码
//直接插入排序
void InsertSort(int* arr, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;
		int tmp = arr[end + 1];
		while (end >= 0)
		{
			if (arr[end] > tmp)
			{
				arr[end + 1] = arr[end];
				end--;
			}
			else {
				break;
			}
		}
		arr[end + 1] = tmp;
	}
}

直接插入排序就是

设下标end刚开始是0,tmp是数组在下标end + 1上的值然后根据条件如果end上的值大于tmp那么end上的值赋值到tmp所在的下标上然后end--,接着让end上的值与tmp上的值继续比较如果与上述相同那么继续end--如果等于或小于则结束直接将tmp值赋值在下标为end + 1的值上

之后接着end每次都加一直到end到n - 2为止

代码讲解

for (int i = 0; i < n - 1; i++)

循环直到end到n - 2为止为啥

下标最后为n - 1如果到了n - 1该下标的值会与数组外的值比较(越界)

c 复制代码
while (end >= 0)
{
		if (arr[end] > tmp)
		{
			arr[end + 1] = arr[end];
			end--;
		}
		else {
			break;
		}
}

如果end上的值大于tmp那么end上的值赋值到tmp所在的下标上然后end--,接着让end上的值与tmp上的值继续比较如果与上述相同那么继续end--如果等于或小于则结束

arr[end + 1] = tmp;

循环结束直接将tmp值赋值在下标为end + 1的值上

2.希尔排序

希尔排序与直接插入排序差不多,多了一个增量

其实就是利用增量将数组进行分组将每组都进行直接选择排序

比如给个数组9,3,5,7,2,1,4,6,8

gap为9 它会变成 gap = gap / 3 + 1的值(增量)

此时gap为4

分为9,2,8 3,1 5,4 7,6

然后每组都进行直接插入排序

2,8,9\] \[1,3\] \[4,5\] \[6,7

然后接着gap = gap / 3 + 1

此时gap为2

分为2,9,3,5,7 8,1,4,6

进行直接插入排序

2,3,5,7,9\] \[1,4,6,8

最后gap = gap / 3 + 1

gap为1

分为2,3,5,7,9,1,4,6,8

进行直接插入排序

1,2,3,4,5,6,7,8,9

就是先将gap 变为 gap = gap / 3 + 1

然后从第一个开始后(不包括第一个)数gap个与第一个组队然后再从这个数开始后(不包括这个数)数gap个如果到了第gap个没越界就继续组队越界了就将该组进行直接插入排序然后从第二个开始以此类推(组好队的人不能再组)

然后继续将gap = gap / 3 +1

继续分组给每组直接插入排序

直到gap 不大于 1为止

或许有人会问希尔排序还不如直接用直接插入排序

希尔排序这样排比直接选着排序快它是直接插入排序的改良版

我们看到之前的排序过程直接用代码暴力写的话会很复杂其实有改良版代码

代码展示

c 复制代码
//希尔排序
void ShellSort(int* arr, int n);
c 复制代码
//希尔排序
void ShellSort(int* arr, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;//3 2 1 
		//对每组进行直接插入排序
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (arr[end] > tmp)
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				else {
					break;
				}
			}
			arr[end + gap] = tmp;
		}
	}
}

代码讲解

c 复制代码
int gap = n;
 while (gap > 1)
 {
 gap = gap / 3 + 1;//3 2 1 
 ......
 }

给gap一个值

然后它刚进while循环然后gap = gap / 3 + 1;//3 2 1 (这里的3 2 1 指的是 / 3 的那个 3 建议用3)

此后每分完组排完序都

gap = gap / 3 + 1

直到gap不再大于1为止

gap为几就分几组

c 复制代码
for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (arr[end] > tmp)
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				else {
					break;
				}
			}
			arr[end + gap] = tmp;
		}
	}

进行分组并将每组进行直接插入排序

复制代码
for (int i = 0; i < n - gap; i++)
{
......
}

当gap为确定值的时候我们遍历到n - gap - 1时就结束了

再比较就越界所以

i < n - gap

为啥从i = 0 开始每次加一

这样就可以看到gap组每个数据的遍历过程

c 复制代码
while (end >= 0)
			{
				if (arr[end] > tmp)
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				else {
					break;
				}
			}
			arr[end + gap] = tmp;
		}

前面因为gap大每组数据太小

当分到只剩几组的时候,遍历到每组的数据中的最后几位时就可以清楚的看到直接插入排序的样子(前面也在进行直接插入排序只是步骤少)(并且每组数据到了后面前面的数据也已经根据从小到大的顺序排好了)

这样就实现了希尔排序


文章写到这里就告一段落,希望对你有所帮助,感谢观看!

相关推荐
薛定e的猫咪16 分钟前
(NeurIPS 2021)MatNet:面向矩阵型关系数据的神经组合优化编码器
人工智能·深度学习·线性代数·算法·矩阵
高亦真31 分钟前
今天是学习嵌入式的第32天
linux·学习·算法
鹿角片ljp9 小时前
LeetCode 236. 二叉树的最近公共祖先|递归后序
算法
luj_17689 小时前
大律师考核应重能力与科技素养
c语言·开发语言·c++·经验分享·算法
无定义_9 小时前
Floyd——Warshall
算法
带多刺的玫瑰10 小时前
Leecode#9刷题之回文数
数据结构·算法
泯泷10 小时前
手搓JSVM第 5 篇:写第一个编译器:从 AST 生成 IR
前端·javascript·算法
泯泷10 小时前
手搓JSVM第 7 篇:控制流:if、while 与 jump
前端·javascript·算法
泯泷10 小时前
手搓JSVM第 6 篇:把 IR 编成字节码:emit 与 label fixup
前端·javascript·算法