算法合集:四大经典排序(选择、插入、冒泡、希尔)算法原理及其C++代码实现

本文内容

本文主要对选择、插入、冒泡、希尔四个排序进行介绍以及C++代码实现,其中希尔排序稍难,其余三个原理较为简单。

什么是选择排序

选择排序就是每次从无序序列中选择无序序列的最大(小)的元素,与无序部分的最后一个(第一个)进行互换位置,这样使得每趟排序都能确定一个元素的绝对位置,执行n次后,得到一个完全有序的序列。图片演示如下:在这里插入图片描述
注意,图片中的思路是每次选择无序序列的最小元素,与无序部分的的一个互换位置,代码实现中是选择的最大元素的方法。

选择排序代码实现

#include <iostream>
#include <vector>
#include <random>
using namespace std;
/*
	思想:每次循环 找到最大的元素 然后把最后一个位置的元素和它的值交换 然后把要排序的数组缩短一个
*/
void SelectSort(vector<int>&datas) {
    
    
	int len = datas.size();
	for (int i = 0; i < len-1; i++)//只需排len-1个最大的元素 剩下的一个自然就是最小的
	{
    
    
		int max = 0;
		for (int j = 0; j < len-i; j++)
		{
    
    
			if (datas[max]<datas[j])
			{
    
    
				max = j;
			}
		}
		int tmp = 0;
		tmp = datas[ len - i - 1];
		datas[len - i - 1] = datas[ max];
		datas[max] = tmp;
	}
}

int main()
{
    
    
	// C++ 11 的random库 
	random_device rd;   
	mt19937 gen(rd());  
	uniform_int_distribution<> dist(1, 200); 

	vector<int>a(10);
	int len = a.size();
	for (int i = 0; i < len; i++)
	{
    
    
		a[i] = dist(gen);
	}
	cout << "before sort:" << endl;
	for (int i = 0; i < len; i++)
	{
    
    
		cout << a[i] << "\t";
	}
	cout << endl;
	SelectSort(a);
	cout << "after sort:" << endl;
	for (int i = 0; i < len; i++)
	{
    
    
		cout << a[i] << "\t";
	}
	cout << endl;
	system("pause");
	return 0;
}

什么是插入排序

从字面上理解,插入排序就是将一个数据插入到其本应存在的地方。具体思路如下:我们将数组分为两部分:前部分为完全有序的序列,后部分为无序的序列;每趟排序开始,选择无序序列中的第一个元素,从后往前插入到有序的序列中,n趟下来,数组就完全有序了。图片演示如下:

在这里插入图片描述

插入排序代码实现

#include <iostream>
#include <vector>
#include <random>
using namespace std;

void InsertSort(vector<int>&datas)
{
    
    
	int len = datas.size();
	//细节 由于只含有一个元素的序列是天然有序的 所以我们只需要进行 n-1 次排序就行了
	for (size_t i = 0; i < len -1; i++)
	{
    
    
		int current = datas[i + 1];
		int preIndex = i;
		//这部分对应动图中的元素后移操作
		while (preIndex>=0&&datas[preIndex]>current)
		{
    
    
			datas[preIndex + 1] = datas[preIndex];
			preIndex--;
		}
		//这里对应移动所有元素后的插入操作
		datas[preIndex + 1] = current;
	}
}

int main()
{
    
    
	// C++ 11 的random库 
	random_device rd;
	mt19937 gen(rd());
	uniform_int_distribution<> dist(1, 200);

	vector<int>a(10);
	int len = a.size();
	for (int i = 0; i < len; i++)
	{
    
    
		a[i] = dist(gen);
	}
	cout << "before sort:" << endl;
	for (int i = 0; i < len; i++)
	{
    
    
		cout << a[i] << "\t";
	}
	cout << endl;
	InsertSort(a);
	cout << "after sort:" << endl;
	for (int i = 0; i < len; i++)
	{
    
    
		cout << a[i] << "\t";
	}
	cout << endl;
	system("pause");
	return 0;
}

什么是希尔排序

希尔排序是插入排序的简化版,通过插入排序的算法我们可以发现,每次在找元素插入的位置时,会进行大量的数据交换以及判断,这是一个限制,希尔排序就能很好的减少这些交换次数,简单理解便是:通过增量序列对待排序序列分组,在分组之间进行交换,这样做的好处是,通过分组间的交换更快使得数组变得有序,即更小的元素能更快的被换到它实际的位置上去,同时减少了判断和交换。
在这里插入图片描述

希尔排序代码实现

#include <iostream>
#include <vector>
#include <random>
using namespace std;

void ShellSort(vector<int>& datas)
{
    
    
	int len = datas.size();
	int temp, gap = len / 2;
	while (gap > 0) 
	{
    
    
		for (int i = gap; i < len; i++) 
		{
    
    
			temp = datas[i];
			int preIndex = i - gap;
			while (preIndex >= 0 && datas[preIndex] > temp) 
			{
    
    
				    datas[preIndex + gap] = datas[preIndex];
				    preIndex -= gap;	
			}
			datas[preIndex + gap] = temp;
		}
		gap /= 2;
	}
}

int main()
{
    
    
	// C++ 11 的random库 
	random_device rd;
	mt19937 gen(rd());
	uniform_int_distribution<> dist(1, 200);

	vector<int>a(10);
	int len = a.size();
	for (int i = 0; i < len; i++)
	{
    
    
		a[i] = dist(gen);
	}
	cout << "before sort:" << endl;
	for (int i = 0; i < len; i++)
	{
    
    
		cout << a[i] << "\t";
	}
	cout << endl;
	ShellSort(a);
	cout << "after sort:" << endl;
	for (int i = 0; i < len; i++)
	{
    
    
		cout << a[i] << "\t";
	}
	cout << endl;
	system("pause");
	return 0;
}

什么是冒泡排序

冒泡排序的排序原理也是十分巧妙的,它的思想如下:两个相邻元素进行比较,较大(小)者放后面(前),那么可以确定的是,对整个序列进行一次这个操作,最大的元素必定移动到了数组最后一位。因此也需要将数组分成两个部分:前部分为无序的序列,后部分为有序的序列,每次操作使得无序序列长度-1,将其最大的元素放到有序序列中,同时有序序列长度+1,进行n-1次,数组就完全有序了。
思考:是否真的需要n-1次?当某一趟排序过程中,没有元素进行交换,就意味着无序序列中不存在逆序的情况(否则必定会换的),所以可以设置标志位来实现,若没交换排序就直接结束了。
在这里插入图片描述

冒泡排序代码实现

#include <iostream>
#include <vector>
#include <random>
using namespace std;

void BubbleSort(vector<int>& datas)
{
    
    
	int len = datas.size();
	for (int i = 0; i < len - 1; i++) 
	{
    
    
		bool flag = false;
		for (int j = 0; j < len - 1 - i; j++) 
		{
    
    
			if (datas[j + 1] < datas[j]) 
			{
    
    
				int temp = datas[j + 1];
				datas[j + 1] = datas[j];
				datas[j] = temp;
				flag = true;
			}
		}
		//没交换直接结束
		if (!flag) return;
	}
}

int main()
{
    
    
	// C++ 11 的random库 
	random_device rd;
	mt19937 gen(rd());
	uniform_int_distribution<> dist(1, 200);

	vector<int>a(10);
	int len = a.size();
	for (int i = 0; i < len; i++)
	{
    
    
		a[i] = dist(gen);
	}
	cout << "before sort:" << endl;
	for (int i = 0; i < len; i++)
	{
    
    
		cout << a[i] << "\t";
	}
	cout << endl;
	BubbleSort(a);
	cout << "after sort:" << endl;
	for (int i = 0; i < len; i++)
	{
    
    
		cout << a[i] << "\t";
	}
	cout << endl;
	system("pause");
	return 0;
}

下篇文章将介绍一些更为巧妙的排序,若本文对大家有用,就请关注点赞支持一下呗~

猜你喜欢

转载自blog.csdn.net/weixin_45416439/article/details/129742049