关于排序
排序是计算机的一项基本应用。许多最终通过计算机生成的输出是以某种方式排序输出的,并且内部调用排序过程使得许多计算变得很有效率。因此在计算机科学中,排序也许是研究最多且最重要的一种运算。
接下来讨论 整数组元素 排序的问题。
插入排序(C++)
// 小-->大
void InSort(int *a, int length)
{
int j,temp;
for (int i = 1; i < length; i++)//数组下标从1(第二个元素)开始,temp作监视哨,第一个数据(a[0])无可比性
{
j = i - 1; //确定要比较元素的最右边
temp = a[i]; //给监视哨赋值
while ((j >= 0) && (temp < a[j]))
{
a[j + 1] = a[j]; //数据右移
j--; //移向左边一个没比较的数
}
a[j+1] = temp; //确定的位置插入a[i]
}
}
//测试
//int a[] = {25, 12, 36, 45, 2, 9, 39, 22, 98, 37 };
//InSort(a, 10);
Shell排序(C++)
/**
待排序记录按照下标增量分组,对每一组使用直接插入排序,
随着增量逐渐减少,魅族记录会越来越多,当增量减为1时,算法终止
**/
void ShellSort(int *a, int length)
{
//增量逐渐减少 n/2,n/4,n/8.....
int delta = length / 2; //求得数组下角标增量
int i,j,temp;
while (delta >= 1) //增量 >=1
{
for (j = delta; j < length; j++) //从增量处开始分组(0,Δ),(1,Δ+1)...
{
i = j - delta;
temp = a[j];
while ((i >= 0) && (temp < a[i]))
{
a[i + delta] = a[i]; //增量分组中实现插入排序
i = i - delta;
}
a[i + delta] = temp;
}
delta = delta / 2; //更换增量大小
}
}
//测试
//int a[] = {25, 12, 36, 45, 2, 9, 39, 22, 98, 37 };
//ShellSort(a, 10);
交换排序(C++)
//冒泡排序
/**
不断交换反序对,直到不再出现反序对为止
**/
void swap(int &a, int &b) //交换数值函数,传递引用
{
int temp;
temp = a;
a = b;
b = temp;
}
void BubbleSort(int *a, int length)
{
for (int i = length; i >= 1;i--) //一次冒泡出现最大数,第二此出现次大数......
{
for (int j = 0; j < i-1; j++) //内部循环从零开始,两两交换
{
if (a[j]>a[j+1])
{
//int temp;
//temp = a[j];
//a[j] = a[j+1];
//a[j+1] = temp; //等价于交换函数
swap(a[j], a[j + 1]); //交换函数
}
}
}
}
//冒泡排序改进算法
void BubbleSortA(int *a, int length)
{
int bound = length-1; //终止位置初始化
while (bound != 0)
{
int tempbound = 0; //记录一趟冒泡排序,最后交换记录的位置
for (int j = 0; j < bound; j++) //数组(0.....n-1) 最后为a[n-1],记录住最后一次交换的位置 bound
{
if (a[j] > a[j + 1])
{
int temp;
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
tempbound = j;
}
}
bound = tempbound; //更新边界
}
}
//测试
//int a[] = {25, 12, 36, 45, 2, 9, 39, 22, 98, 37 };
//ShellSortA(a, 10);
快速排序(C++)
//快速排序
/**
选取文件中中一个记录作为基准元素,然后按照关键词的大小进行排序,使得基准元素左边都小于它,右边都大于它
**/
int partition(int arr[], int left, int right) //找基准数划分,注:left,right 是数组中实实在在的下角标
{
int i = left;
int j = right + 1; //最右边增1
int temp = arr[left];
while (i < j)
{
while (arr[i] <= temp)
{
i++;
}
j = j - 1;
while (arr[j] > temp)
{
j--;
}
if (i < j)
swap(arr[i], arr[j]);
}
swap(arr[j], arr[left]); //注意:此时交换时,不要使用temp
return j;
}
void quick_sort1(int arr[], int left, int right)
{
if (left > right)
return;
int j = partition(arr, left, right);
quick_sort1(arr, left, j - 1);
quick_sort1(arr, j + 1, right);
}
//快速排序-填坑法
void quick_sort(int s[], int l, int r)
{
if (l < r)
{
int i = l, j = r, x = s[l];
while (i < j)
{
while (i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if (i < j)
s[i++] = s[j];
while (i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if (i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}
//测试
//int a[] = {277, 12, 36, 45, 2, 19, 39, 22, 98, 37 };
//quick_sort1(a, 0, 9);
//quick_sort(a, 0, 9);
选择排序(C++)
//6.选择排序
//直接选择排序-对文件进行n-1次选择,第i次操作是,选择第i小或大的记录放在第i个位置上
//选择排序
//直接选择排序-对文件进行n-1次选择,第i次操作是,选择第i小或大的记录放在第i个位置上
void SSort(int *a, int length)
{
for (int j = length-1; j >= 1; j--)// j 为每次比较后大值要放置的位置的下角标
{
int t = 0; //每次用第一项 来比较
for (int i = 1; i <= j; i++)// 获取最大值的下角标 赋值 t
{
if (a[t] < a[i])
{
t = i;
}
}
swap(a[j], a[t]);
}
}
void SelectSort(int *a, int length)
{
for (int i = 0; i < length - 1; i++)// i为每次循环比较后要放置的小值的下角标
{
int k = i;
for (int j = i + 1; j < length; j++)
{
if (a[j] < a[k])//获取小值的下角标
{
k = j;
}
}//确定最小值下角标
if (k != i)
{
swap(a[k], a[i]);
}
}
}
//测试
//int a[] = {27, 12, 36, 45, 2, 19, 39, 22, 98, 37 };
//SSort(a,10);
堆排序
void HeapAdjust( int S[], int i, int nlength)
{
int nChild;
int nTemp;
for (; 2 * i + 1 < nlength; i = nChild)
{
nChild = 2 * i + 1;
//得到子节点中较大的节点
if (nChild < nlength - 1 && S[nChild + 1] > S[nChild])
nChild++;
//如果较大的子节点大于父节点那么把较大的子节点往上移动,替换它的父节点
if (S[i] < S[nChild])
{
nTemp = S[i];
S[i] = S[nChild];
S[nChild] = nTemp;
}
else
break;
}
}
void Heapsort(int A[], int length)
{
int i;//调整序列的前半部分元素,调整完之后第一个元素是序列的最大元素
int temp;
for (i = length / 2 - 1; i >= 0; i--)
HeapAdjust(A, i, length);
//从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
for (i = length - 1; i >= 0; i--)
{
//把第一个元素和当前的最后一个元素交换
//保证当前的最后一个位置的元素都是现在这个序列中最大的
temp = A[0];
A[0] = A[i];
A[i] = temp;
//不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
HeapAdjust(A, 0, i);
}
}
//测试
//int a[] = {27, 12, 36, 45, 2, 19, 39, 22, 98, 37 };
//Heapsort(a,10);
//for(int i = 0;i<10;i++)
// cout<<a[i]<<" ";