排序算法(冒泡,插入),希尔排序(插入升级),希尔排序和插入排序时间比较!

🎁个人主页:我们的五年

🔍系列专栏:排序算法

🎉欢迎大家点赞👍评论📝收藏⭐文章

一.冒泡排序:

时间复杂度:O(N^2)。

🏄‍♂️思路分析:

冒泡排序是交换排序。

第一次找出最大的放在数组的最后面num[n-1]。

第二次找出第二大的数放在数组的num[n-2]。

......

两两相比,然后交换位置就可以找到最大的,第二大的......

如果某趟中,没有进行数据交换,证明此时序列已经有序。就可以直接跳出循环。

🏄‍♂️代码分析:

//冒泡排序
void Bubble_Sort(int* num, int n)
{
	//n-1趟
	for (int i = 0;i <n -1; i++)
	{
		bool flag = 0;
		//第一趟[0,n-2]
		for (int j = 1;j <n-i; j++)
		{
			if (num[j - 1] > num[j])
			{
				swap(num[j-1], num[j]);
				flag = 1;
			}
		}
		if (flag == 0)
			break;
	}
}

二.插入排序:

时间复杂度:O(N^2)。

最坏情况:逆序,N*(N-1)/2=O(N^2)。

最好情况:顺序,O(N)。

🏄‍♂️思路分析:

插入排序有点像我们打扑克牌,打扑克牌的时候,我们每拿一张牌,我们就会去和每一个进行比对,然后放在正确位置,让新拿到的牌和原来有序的序列变成新的有序的序列。

⛳️单趟理解:

如果[0,end]这段区间已经有序,我们想要将下num[end+1]插入到[0,end]这段区间中,使得[0,end+1]这段区间有序。

1.我们首先将num[end]与num[end+1]进行比较,如果num[end+1]的值小于num[end],那么我们就把num[end]移动到num[end+1]。这个一步的时候,num[end+1]就会被覆盖,所以我们可以考虑使用临时变量tmp存num[end+1],最后如果找到正确的位置,我们只需要将tmp的值给它就OK。

2.第一次完了以后,将end-1,然后用tmp和num[end]进行比较。

3.重复上面的步骤,当end减到某个值时,此时num[end]>=tmp就停止,此时[0,end]这个有序区间都<=tmp,end+2以后有序的区间都>tmp,最后我们只需要将tmp给num[end]就完成了单趟。

⛳️多趟理解:

只需要从[0,0]开始,插入n-1个元素就完成了排序。

🏄‍♂️代码解析:

//插入排序
void Insert_Sort(int* num, int n)
{
	for (int i = 0; i <= n - 2; i++)
	{
		//end表示有序区间的最后一个下标
        //[0,end],end+1
		int end = i;
		int tmp = num[end + 1];
		while (end >= 0)
		{
			if (tmp < num[end])
			{
				num[end + 1] = num[end];
				--end;
			}
			else
				break;
		}
		num[end + 1] = tmp;
	}
}

🏄‍♂️冒泡排序和插入排序的比较:

1.冒泡排序如果要提前结束,就是整体有序,其他的都要只要有一次交换,那么就要把整体都交换。(每趟基本都是最坏)

2.但是插入排序,可以移动几个数,然后插入进去,插入位置前面的数就不要移动,这样就比冒泡排序的适应性更强。(每趟基本不是最坏)

三.希尔排序:

因为希尔排序太吊了,会单独用一篇文章讲。在专栏中能找到。

//希尔排序
void Shell_Sort(int* num, int n)
{
	int gap = n;
	while(gap>1)
	{
        //加一的目的让最后一次gap为1
		gap /= 3+1;
		//end的最后位置:end+gap<n
		for (int j = 0; j+gap<n; j++)
		{
			int end = j;
			int tmp =num[j+ gap];
			while (end >=0)
			{
				if (tmp < num[end])
				{
					num[end + gap] = num[end];
					end -= gap;
				}
				else
					break;
			}
			num[end + gap] = tmp;
		}
	}
}

四.验证插入排序和希尔排序的实际实际比较:

🏄‍♂️头文件:

#pragma once
#include<iostream>
using namespace std;

//打印数组
void Print(int* num, int n);

//冒泡排序
void Bubble_Sort(int* num, int n);

//希尔排序
void Shell_Sort(int* num, int n);

//插入排序
void Insert_Sort(int* num, int n);

🏄‍♂️sort.cpp文件,函数实现文件:

#include<iostream>
#include<algorithm>

using namespace std;

//打印数组
void Print(int* num, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", num[i]);
	}
	printf("\n");
}


//冒泡排序
void Bubble_Sort(int* num, int n)
{
	//n-1趟
	for (int i = 0;i <n -1; i++)
	{
		bool flag = 0;
		//第一趟[0,n-2]
		for (int j = 1;j <n-i; j++)
		{
			if (num[j - 1] > num[j])
			{
				swap(num[j-1], num[j]);
				flag = 1;
			}
		}
		if (flag == 0)
			break;
	}
}

void Shell_Sort(int* num, int n)
{
	int gap = n;
	while(gap>1)
	{
		gap /= 3+1;
		//end的最后位置:end+gap<n
		for (int j = 0; j+gap<n; j++)
		{
			int end = j;
			int tmp =num[j+ gap];
			while (end >=0)
			{
				if (tmp < num[end])
				{
					num[end + gap] = num[end];
					end -= gap;
				}
				else
					break;
			}
			num[end + gap] = tmp;
		}
	}
}


void Insert_Sort(int* num, int n)
{
	for (int i = 0; i <= n - 2; i++)
	{
		//end表示有序区间的最后一个下标
		int end = i;
		int tmp = num[end + 1];
		while (end >= 0)
		{
			if (tmp < num[end])
			{
				num[end + 1] = num[end];
				--end;
			}
			else
				break;
		}
		num[end + 1] = tmp;
	}
}

🏄‍♂️测试文件:

#define  _CRT_SECURE_NO_WARNINGS 1
#include"Sort.h"
#include<stdlib.h>
#include<time.h>


void Bubble_Sort_Test()
{
	int	n;
	cin >> n;
	int* num = new int[n];
	for (int i = 0; i < n; i++)
		scanf("%d", &num[i]);
	Print(num, n);
	Bubble_Sort(num, n);
	Print(num, n);
	delete[] num;
}

void Shell_Sort_Test()
{
	int	n;
	cin >> n;
	int* num = new int[n];
	for (int i = 0; i < n; i++)
		scanf("%d", &num[i]);
	Print(num, n);
	Shell_Sort(num, n);
	Print(num, n);
	delete[] num;
}

void test()
{
	srand(time(0));
	const int N = 100000;
	int* a1 = new int[N];
	int* a2 = new int[N];
	for (int i = 0; i < N; i++)
	{
		a1[i] = rand();
		a2[i] = a1[i];
	}

	int begin1 = clock();
	Insert_Sort(a1, N);
	int end1 = clock();


	int begin2 = clock();
	Shell_Sort(a2, N);
	int end2 = clock();


	//Print(a1, N);
	//Print(a2, N);
	printf("Inert_Sort:%d\n", end1 - begin1);
	printf("Shell_Sort:%d\n", end2 - begin2);
	delete[] a1;
	delete[] a2;

}


int main()
{
	//Bubble_Sort_Test();
	//Shell_Sort_Test();
	test();
	return 0;
}

几百倍!

相关推荐
不会写代码的ys1 分钟前
【类与对象】--对象之舞,类之华章,共绘C++之美
c++
兵哥工控3 分钟前
MFC工控项目实例三十二模拟量校正值添加修改删除
c++·mfc
EterNity_TiMe_12 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
长弓聊编程13 分钟前
Linux系统使用valgrind分析C++程序内存资源使用情况
linux·c++
陌小呆^O^17 分钟前
Cmakelist.txt之win-c-udp-client
c语言·开发语言·udp
cherub.21 分钟前
深入解析信号量:定义与环形队列生产消费模型剖析
linux·c++
机器学习之心23 分钟前
一区北方苍鹰算法优化+创新改进Transformer!NGO-Transformer-LSTM多变量回归预测
算法·lstm·transformer·北方苍鹰算法优化·多变量回归预测·ngo-transformer
yyt_cdeyyds33 分钟前
FIFO和LRU算法实现操作系统中主存管理
算法
暮色_年华35 分钟前
Modern Effective C++item 9:优先考虑别名声明而非typedef
c++
重生之我是数学王子43 分钟前
QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现
开发语言·c++·qt