Algorithm第四版算法 C++实现(二)——初级排序算法(选择排序、插入排序、希尔排序)

排序是将一组对象按照某种逻辑顺序重新排列的过程。排序算法常常是解决其他问题的第一步。

选择排序

找到最小的元素与第几个元素交换位置
main.cpp

#include <iostream>
#include "head.h"
using namespace std;
int main()
{
	vector<char> s;
	s.resize(11);
	for (int i = 0; i < 11; i++)
	{
		cin >> s[i];
	}
	sort<char> so;
	so.select_sort(s);
	for (int i = 0; i < 11; i++)
	{
		cout << s[i];
	}
	return 0;
}

/*
test data
sortexample
*/

head.h

template<typename T>
class sort
{
	std::vector<T> a;
public:
	sort()
	{

	};
	 void select_sort(std::vector<T> &item)
	{
		//std::cout << "test\n";
		a = item;
		int n = a.size();
		for (int i = 0; i < n; i++)
		{
			int min = i;
			for (int j = i + 1; j < n; j++)
			{
				if (less(a[j], a[min]))
				{
					min = j;
				}
			}
			swap(i, min);
		}
		item = a;
	}
private:
	bool less(T a,T b)//比较两个变量大小
	{
		return a < b;
	}
	void swap(int i, int j)
	{
		T temp;
		temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}
};

运行结果:
在这里插入图片描述
为了找出最小的元素,每次都需要扫描全部剩余元素,且都不能为下次扫描提供任何信息,因此选择排序的时间复杂度是稳定的平方关系

插入排序

插入排序是i左边全部为有序的,再将i位置的元素插入到有序列中。

void insert_sort(std::vector<T> &item)
	 {
		 a = item;
		 int n = a.size();
		 for (int i = 1; i < n; i++)
		 {
			 for (int j = i; j > 0 && less(a[j], a[j - 1]); j--)
			 {
				 swap(j, j - 1);
			 }
		 }
		 item = a;
	 }

运行结果
在这里插入图片描述
插入排序对于非随机的序列是有效的。也就是说,原序列的有序度越高,插入排序所花费的时间就越少。同样的,如果原序列的排列很混乱,那么插入排序就需要更多的时间

希尔排序

希尔排序是一种分治法,他在局部使用插入排序,使得局部序列有序,然后再再逐步增加分出的序列的长度,对其使用插入排序 (上文已经说到插入排序在处理较为有序的序列时有其优势) ,最后使得整个序列有序

void shell_sort(std::vector<T> &item)
	 {
		 a = item;
		 int n = a.size();
		 int h = 1;
		 while (h < n / 3)
		 {
			 h = 3 * h + 1;//1 4 13 40 121 364 1093 ……
		 }
		 //h的划分不尽相同,也有使用h=n/2的做法的
		 while (h>=1)
		 {
			 for (int i = h;i < n; i++)
			 {
				 for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)
				 {
					 swap(j, j - h);
				 }
			 }
			 h = h / 3;
		 }
		 item = a;
	 }

运行结果
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值