您现在的位置是:首页 >技术教程 >深入浅出C语言——排序网站首页技术教程
深入浅出C语言——排序
排序的概念
- 排序就是使用使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
常见的排序算法
冒泡排序
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这步做完后,最后的元素会是最大的数。针对所有的元素重复以上的步骤(除了最后一个)即可完成排序。
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void BubbleSort(int* a, int n)
{
assert(a);
//外层循环走n-1次,因为最后一趟不需要比较
for (int i = 0; i < n - 1; i++)
{
int flag = 0;
//每次外层循环能确定一个最大的数在正确的位置,所以只需要比较n-i次
for (int j = 1; j < n - i; j++)
{
//比较相邻的两个元素,如果他们的顺序错误就把他们交换过来
if (a[j-1] > a[j])
{
Swap(&a[j - 1], &a[j]);
flag = 1;
}
}
//如果走了一趟都没有交换说明已经有序
if (flag == 0)
break;
}
}
选择排序
每一次从待排序的数据元素中选出最小和最大的一个元素,存放在序列的起始位置,在剩余的array[i]–array[n-2](array[i+1]–array[n-1])集合中,重复上述步骤,直到集合剩余1个元素 。因为可能把相同的元素换到不同的位置,所以选择排序也是不稳定的。
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void SelectSort(int* a, int n)
{
assert(a);
int begin = 0, end = n - 1;
while (begin < end)//迭代的过程中,n为奇数个数会相遇,偶数个会错过
{
int mini = begin;
int maxi = begin;
for (int i = begin + 1; i <= end; ++i)
{
//找最小元素
if (a[i] < a[mini])
mini = i;
//找最大元素
if (a[i] > a[maxi])
maxi = i;
}
//开头和最大交换
Swap(&a[begin], &a[mini]);
// 如果begin和maxi重叠,那么上一步中就把max换走了,那么max就到了min的位置
if (begin == maxi)
{
maxi = mini;
}
//结尾和最小交换
Swap(&a[end], &a[maxi]);
//迭代
++begin;
--end;
}
}
插入排序
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为
止,得到一个新的有序序列。即:当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与 array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。
每一次从待排序的数据元素中选出最小和最大的一个元素,存放在序列的起始位置,在剩余的array[i]–array[n-2](array[i+1]–array[n-1])集合中,重复上述步骤,直到集合剩余1个元素 。最好的情况是接近有序;最坏的情况是逆序。
void InsertSort(int* a, int n)
{
assert(a);
//外层循环n-1次
for (int i = 0; i < n - 1; ++i)
{
// [0,end]有序,把end+1位置的值插入,保持有序
int end = i; //每次都要对end重新赋值
int tmp = a[end + 1]; //tmp保存end+1位置的元素
while (end >= 0)
{
//如果不满足条件就把前面的元素后移,直到数组起始位置
if (tmp < a[end])
{
a[end + 1] = a[end];
--end;
}
else
{
break;
}
}
//到这里就满足条件了,证明end前面的元素就是tmp应该存放的位置
a[end + 1] = tmp;
}
}
希尔排序
希尔排序法又称缩小增量法。希尔排序法的基本思想是:把待排序文件中所有记录分组,所有距离为Gap的分在同一组内,并对每一组内的记录进行排序。待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。 预排序的时候,相同的数据可能分到了不同的组,所系希尔排序是不稳定的。