C++-数据结构-基本排序方法

目录

算法概述

插入排序

选择排序

冒泡排序

梳排序


算法概述

1、十种常见排序算法可以分为两大类:

非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。

线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。 

2、算法复杂度

3、相关概念

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。 


插入排序

1、思想:逐个比较。将data[i]逐个与data[j](0<j<i),从而将data[i]放在data[]中合适的位置

 

2、复杂度:O(n^2)

3、缺点:存在多次多余且重复的移动,使效率低。

4、源代码:

#include <iostream>
using namespace std;

template<class T>
void insertionsort(T data[],int n)
{
	for (int i = 1,j;i < n;++i) {//注意,这里不能用i<=n,因为data[n]超出了索引范围
								 //int data[7]为data内有7点int,但data[7]已经超出范围,从零开始计算
		T tem = data[i];
		for (j = i;j > 0 && tem < data[j-1];--j) {
			data[j] = data[j - 1];
		}
		data[j] = tem;
	}
}

template<class T>
void printdata(T data[], int n)
{
	for (int i = 0;i < n;++i) {//注意,这里不能用i<=n
		cout << data[i] << "    ";
	}
}

int main() {
	double data[] = { 10, 165, 12.5, 16, 5.5, 132, 1 ,651 };
	insertionsort(data, 8);
	printdata(data, 8);
	system("pause");
	return 0;
}

选择排序

1、思想:将数据放置在数组正确的位置上。

      datat[]中有n个数据,在data[]中找到最小值,与data[0]交换;此后在data[1]与data[n-1]中继续找到最小值,与data[1]交换;在data[2]与data[n-1]中继续找到最小值,与data[2]交换。

2、复杂度:O(n^2)

3、缺点:

4、源代码:

#include <iostream>
using namespace std;

template<class T>
void selectionsort(T data[], int n)
{
	T tem;
	int temi;
	for (int j = 0;j < n;j++) {
		tem = data[j];
		temi = j;
		for (int i=j+1;i < n;++i) {//遍历寻找最小值
			if (data[i] < tem) {
				tem = data[i];
				temi = i;
			}
		}
		if (temi != j) {//倘若原先data[j]已在合适的位置,便不在交换
			data[temi] = data[j];//交换数组的数值,将最小值放在合适的位置
			data[j] = tem;
		}

	}
}

template<class T>
void printdata(T data[], int n)
{
	for (int i = 0;i < n;++i) {//注意,这里不能用i<=n
		cout << data[i] << "    ";
	}
}

int main() {
	int data[] = { 10, 165, 12.5, 16, 5.5, 132, 1 ,651 };
	selectionsort(data, 8);
	printdata(data, 8);
	system("pause");
	return 0;
}

冒泡排序

1、思想:依次遍历数组,比较相邻的两个元素,如果它们的顺序错误就把它们交换过来,直到没有再需要交换的元素。之所以为冒泡,是因为越小的元素慢慢地往前面冒出来。

2、复杂度:O(n^2)

3、源代码

#include <iostream>
using namespace std;

template<class T>
void bubblesort(T data[], int n)
{
	bool is_swap = true;//若在一次遍历中无交换,则说明此时排序已完成
	for (int j = 0;j < n - 1 && is_swap;++j) {
		is_swap = false;
		for (int i = 0;i < n-1;++i) {
			if (data[i] > data[i + 1]) { 
				is_swap = true;
				swap(data[i], data[i + 1]);
			}
		}
	}
}

template<class T>
void printdata(T data[], int n)
{
	for (int i = 0;i < n;++i) {//注意,这里不能用i<=n
		cout << data[i] << "    ";
	}
}

int main() {
	int data[] = { 10, 165, 12.5, 16, 5.5, 132, 1 ,651 };
	bubblesort(data, 8);
	printdata(data, 8);
	system("pause");
	return 0;
}

梳排序

1、思想:将待排序序列通过增量分为若干个子序列,然后对子序列进行一趟冒泡排序,一步步减小增量,直至增量为1。

梳排序增量是根据递减率减小的,递减率的设定影响着梳排序的效率,原作者以随机数作实验,得到最有效递减率为1.3的。 

2、排序举例
     举例:待排序序列为{8, 6, 5, 2, 1, 4, 3,7} 
     (1)初始increment = 8/1.3 =6。分为子序列{8, 3}{6, 7}{5}{2}{1}{4}进行一趟冒泡排序,得到{3, 6, 5, 2,                    1, 4, 8, 7} (每一个子序列在父序列的索引相差increment )
     (2)increment = 6/1.3 = 4。分为子序列{3, 1}{6, 4}{5, 8}{2, 7}进行一趟冒泡排序,得到{1, 4, 5, 2, 3, 6,                 8, 7}。 
     (3)increment = 4/1.3 = 3。分为子序列{1, 2, 8}{4, 3, 7}{5, 6}进行一趟冒泡排序,得到{1, 3, 5, 2, 4, 6,                     8, 7}。 
     (4)increment = 3/1.3 = 2。分为子序列{1, 5, 4, 8}{3, 2, 6, 7}进行一趟冒泡排序,得到{1, 2, 4, 3, 5, 6, 8,                  7}。 
     (5)increment = 2/1.3 = 1。分为子序列{1, 2, 4, 3, 5, 6, 8, 7}进行一趟冒泡排序,得到{1, 2, 3, 4, 5, 6, 7,                   8}。

3、复杂度:O(nlgn)

4、源代码:

#include <iostream>
using namespace std;

template<class T>
void combsort(T data[], int n)
{
	int step=n/1.3;//将索引相差step的元素进行冒泡排序
	while (step>1)
	{
		for (int i = 0;i + step <= n - 1;++i)
			if (data[i] > data[i + step])
				swap(data[i], data[i + step]);
		step = step / 1.3;
	}
	//最后一次为step为1的冒泡排序
	bool is_swap = true;//若在一次遍历中无交换,则说明此时排序已完成
	for (int j = 0;j < n - 1 && is_swap;++j) {
		is_swap = false;
		for (int i = 0;i < n - 1 - j;++i)
			if (data[i] > data[i + 1]) {
				is_swap = true;
				swap(data[i], data[i + 1]);
			}
	}
}

template<class T>
void printdata(T data[], int n)
{
	for (int i = 0;i < n;++i) {//注意,这里不能用i<=n
		cout << data[i] << "    ";
	}
}

int main() {
	int data[] = { 10, 165, 12, 16, 5, 132, 1 ,651 };
	combsort(data, 8);
	printdata(data, 8);
	system("pause");
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值