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

时间:2024-10-28 07:12:36

????个人主页:我们的五年

????系列专栏:排序算法

????欢迎大家点赞????评论????收藏⭐文章

 

一.冒泡排序:

时间复杂度: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;
}

几百倍!