基本排序方法实现:选择排序、插入排序、希尔排序

三个基本排序问题的实现,先给出几个公用的比较函数、元素交换函数和显示函数。

#include <iostream>
using namespace std;

#define ElementType char

bool lessFunc(ElementType cur, ElementType ref)   //比较函数
{
	return cur < ref;
}
void exch(ElementType a[], int curIndex, int refIndex)  //交换函数
{
	ElementType tmp;
	tmp = a[curIndex];
	a[curIndex] = a[refIndex];
	a[refIndex] = tmp;
}
void showFunc(ElementType a[], int N)
{
	for (int i = 0; i < N; i++)
		cout << a[i] << ' ';
	cout << '\n';
}

一、选择排序

原理:首先找到数组中最小的那个元素,其次将它和数组中的第一个元素交换位置;再次,在剩下的元素中找到最小的元素,将它与数组中的第二个元素交换位置。如此往复,直到将整个数组排序。

void ChooseSort(ElementType a[],int N)
{
	for (int i = 0; i < N; ++i)
	{
		int minIndex = i;
		for (int j = i + 1; j < N; ++j)
			if (lessFunc(a[j], a[minIndex])) 
				minIndex = j;
		exch(a, i, minIndex);
	}
}
int main()
{
	ElementType a[] = "SORTEXAMPLE";
	int len = strlen(a);   //当数组作为函数参数传递时,数组名代表的是数组的首址,而非数组内容,故无法使用sizeof和strlen;
	cout << "Raw Seq:\n";
	showFunc(a, len);
	cout << "Sorted Seq:\n";
	ChooseSort(a, len);
	showFunc(a, len);
	cin.get();
	return 0;
}

二、插入排序

将元素逐个插入,索引左侧的所有元素都是有序的,但它们 的最终位置还不确定,为了给更小元素腾出空间,它们可能会被移动。当索引到达数组右端时,数组排序就完成了。

void InsertSort(ElementType a[], int n)
{
	for (int i = 1; i < n; ++i)
	{
		for (int j = i; j >0 && lessfunc(a[j],a[j-1]); j--)
		{
			exch(a,j,j-1);
		}
	}
}

int main()
{
	ElementType a[] = "SORTEXAMPLE";
	int len = strlen(a);   //当数组作为函数参数传递时,数组名代表的是数组的首址,而非数组内容,故无法使用sizeof和strlen;
	cout << "Raw Seq:\n";
	showFunc(a, len);
	cout << "Sorted Seq:\n";
	InsertSort(a, len);
	showFunc(a, len);
	cin.get();
	return 0;
}

为了提高插入排序的速度,可以在内循环中将较大的元素都向右移动而总是交换两个元素。因为while循环可以提前终止,故访问数组的平均次数减半。

void InsertSort(ElementType a[], int N)
{
	for (int i = 1; i < N; ++i)
	{
		ElementType tmp = a[i];
		int j = i;  //j表示当前待排序元素
		while (j>0 && lessFunc(tmp,a[j-1]))   //将当前元素依次与左侧元素比较;将比a[i]大的元素右移一位,同时得到a[i]的位置j。
		{
			a[j] = a[j - 1];
			j--;
		}
		a[j] = tmp;
	}
}

三、希尔排序

基于插入排序的快速的排序算法。希尔排序为了加快速度简单地改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。

图解:https://www.cnblogs.com/chengxiao/p/6104371.html

void ShellSort(ElementType a[], int n)
{
	//递增序列
	int h = 1;
	while (h<n/3)
	{
		h = 3 * h + 1;
	}
	//排序 将数组变为h有序
	while (h>=1)
	{
		for (int i = h; i < n; i++)
		{   //将a[i]插入到a[i-h],a[i-2*h],a[i-3*h]...中
			for (int j = i; j >= h && lessFunc(a[j], a[j - h]); j -= h)
				exch(a,j,j-h);
		}
		h = h / 3;
	}
}

int main()
{
	ElementType a[] = "SORTEXAMPLE";
	int len = strlen(a);   //当数组作为函数参数传递时,数组名代表的是数组的首址,而非数组内容,故无法使用sizeof和strlen;
	cout << "Raw Seq:\n";
	showFunc(a, len);
	cout << "Sorted Seq:\n";
	ShellSort(a, len);
	showFunc(a, len);
	cin.get();
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值