三个基本排序问题的实现,先给出几个公用的比较函数、元素交换函数和显示函数。
#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;
}