根据算法的复杂度,比较简单的排序算法有:选择排序、直接插入排序和冒泡排序。所以本节内容先着重介绍这三种排序算法,为以后更有难度的算法打打基础。
一、选择排序
基本思想:
每一趟(例如第 i 趟,i = 0, 1, ..., n-2)在后面 n- i 个待排序的数据元素中选出关键字最小的元素,作为有序元素序列的第 i 个元素,即与第 i 个元素进行交换。
实现代码:
void select_sort(int p[])//O(n*n)
{
int i = 0, j = 0, k = 0;
for(i=0; i<N; i++)
{
k = i;
/*j是扫描下标,找出最小的值,与无序头部的元素交换*/
for(j=i; j<N; j++)
{
if(p[k] > p[j])
{
k = j;
}
}
swap(p, i, k);
}
}
二、插入排序
基本思想:
当插入第 i (i >= 1)个数据元素时,前面的 v[0], v[1],... v[i-1]已经排好序。这时用 v[i]的关键字与 v[i-1],v [i-2]的关键字进行比较,找到插入的位置。即将 v[i]插入,原位置上的对象向后顺移。
实现代码:
void insertion_sort(int p[], int len) //O(n*n)
{
int i = 0, j = 0;
for(i=1; i<len; i++)
{
int tmp = p[i];
/*从i-1开始比较,切勿忘记第一个元素*/
for(j=i-1; j>=0; j--)
{
if(p[j] > tmp)
{
p[j+1] = p[j];
}
else if(p[j] < tmp)
{
break;
}
}
p[j+1] = tmp;
}
}
三、冒泡排序
基本思想:
设待排数据元素序列中的元素个数为n. 最多作n-1趟. 在第 i 趟中从后向前,j = n-1, n-2, ..., i,两两比较V[j-1] 和 V[j]的关键字。如果发现逆序,则交换 V[j-1] 和 V[j]
实现代码:
void bubble_sort(int p[], int len) //O(n*n)
{
int i = 0, j = 0;
for(i=0; i<len-1; i++)
{
int exchange = 0;//优化,当前序列已排好序的话,就可以提前退出。
/*每次都从序列尾部开始扫描*/
for(j=len-1; j>0; j--)
{
if(p[j] < p[j-1])
{
swap(p, j, j-1);
exchange = 1;
}
}
if(exchange == 0)
{
break;
}
}
/*打印出冒泡的次数*/
printf("i : %d\n", i);
}
总结:在实现的过程中,注意扫描指针的的起始情况。
选择排序:从
无序序列的头部开始扫描,找到比无序序列首部元素小且为剩余元素中最小的元素的下标,记录。然后将此元素与无序虚头头部的首元素交换。
插入排序:从
有序序列中的最后一个元素(i-1)开始扫描。
冒泡排序:每次都是从
序列的最后一个元素开始做逆序交换。