排序算法即是一种能将一串数据依照特定排序方式进行排列的一种算法。本文将简单介绍几种常用的排序算法,并给出源代码,仅供参考。
1.直接插入排序:是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
2.希尔排序:是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。实质上是一种分组插入方法。
3.冒泡排序:重复地遍历要排序的数列,一次比较相邻两个元素,如果顺序颠倒(取决于排序要求)就把他们交换过来。直到不再需要交换,也就是说此时该序列已经排序完成。
4.简单选择排序:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找次小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
5.堆排序:堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是一种近似于完全二叉树的结构。大根堆的要求是每个节点的值都不大于其父结点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。
6.归并排序:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
#include "stdio.h"
typedef struct table
{
int data[10];
int length;
}table;
void create(table &T); //创建线性表
void swap(int &a, int &b); //交换两变量值
void insert_sort(table T); //直接插入排序
void shell_sort(table T); //希尔排序
void bubble_sort(table T); //冒泡排序
void select_sort(table T); //简单选择排序
void heap_sort(table T); //堆排序
void merge_sort(table &s, int left, int right); //归并排序
void quick_sort(table &T, int left, int right); //快速排序
int main()
{
table T;
create(T);
insert_sort(T); //直接插入排序
shell_sort(T); //希尔排序
bubble_sort(T); //冒泡排序
select_sort(T); //简单选择排序
heap_sort(T); //堆排序
table s = T;
merge_sort(s, 0, T.length); //归并排序
printf("归并排序后结果为:");
for(int j = 0; j < s.length; ++j)
printf("%d ", s.data[j]);
printf("\n\n");
printf("快速排序前序列为:");
for(j = 0; j < T.length; ++j)
printf("%d ", T.data[j]);
printf("\n\n");
quick_sort(T, 0, T.length-1); //快速排序
printf("快速排序后结果为:");
for(j = 0; j < T.length; ++j)
printf("%d ", T.data[j]);
printf("\n");
return 0;
}
void create(table &T)
{
int a[8] = {6, 2, 4, 8, 5, 3, 7, 1};
T.length = 8;
for(int i = 0; i < T.length; ++i)
T.data[i] = a[i];
printf("线性表中元素:");
for(i = 0; i < T.length; ++i)
printf("%d ", T.data[i]);
printf("\n\n");
}
//交换两变量值
void swap(int &a, int &b)
{
int k;
k = a;
a = b;
b = k;
}
//直接插入排序
void insert_sort(table T)
{
int i, j;
for(i = 1; i < T.length; ++i)
for(j = i; j > 0; --j)
if(T.data[j-1] > T.data[j])
swap(T.data[j-1], T.data[j]);
printf("直接插入排序后结果为:");
for(i = 0; i < T.length; ++i)
printf("%d ", T.data[i]);
printf("\n\n");
}
//折半查找排序
void shell_sort(table T)
{
int i, d, j;
for(d = T.length/2; d >= 1; d = d/2)
for(i = d; i < T.length; ++i)
for(j = i; j > 0; j = j - d)
if((j - d >= 0) && (T.data[j] < T.data[j-d]))
swap(T.data[j-d], T.data[j]);
printf("希尔排序后结果为:");
for(i = 0; i < T.length; ++i)
printf("%d ", T.data[i]);
printf("\n\n");
}
//冒泡排序
void bubble_sort(table T)
{
int i, j;
for(i = 0; i < T.length - 1; ++i)
{
for(j = 0; j < T.length - 1 - i; ++j)
if((j < T.length) && (T.data[j] > T.data[j+1]))
swap(T.data[j+1], T.data[j]);
printf("冒泡排序第%d趟结果:", i+1);
for(j = 0; j < T.length; ++j)
printf("%d ", T.data[j]);
printf("\n");
}
printf("\n");
}
//简单选择排序
void select_sort(table T)
{
int i, j, min;
for(i = 0; i < T.length; ++i)
{
min =T.data[T.length-1];
for(j = T.length-2; j >= 0; --j)
if(min >= T.data[j])
min = T.data[j];
else
{
swap(T.data[j+1], T.data[j]);
min = T.data[j];
}
}
printf("简单选择排序后结果为:");
for(j = 0; j < T.length; ++j)
printf("%d ", T.data[j]);
printf("\n\n");
}
//堆排序
void heapadjust(table &T, int k, int len)
{
int a = T.data[k];
for(int i = 2*k+1; i <= len-1; i = i*2+1)
{
if((i < len-1) && (T.data[i] < T.data[i+1]))
++i;
if(a >= T.data[i])
break;
else
{
T.data[k] = T.data[i];
k = i;
}
}
T.data[k] = a;
}
void heap_sort(table T)
{
int i;
for(i = (T.length/2-1); i >= 0; --i)
heapadjust(T, i, T.length);
for(i = T.length-1; i >= 1; --i)
{
swap(T.data[0], T.data[i]);
heapadjust(T, 0, i);
}
printf("堆排序后结果为:");
for(int j = 0; j < T.length; ++j)
printf("%d ", T.data[j]);
printf("\n\n");
}
//归并排序
void merge_sort(table &s, int left, int right)
{
if(left + 1< right)
{
int p = left, q = right;
int mid = (p + q)/2;
merge_sort(s, left, mid);
merge_sort(s, mid, right);
int a[8];
for(int t = 0; t < s.length; ++t)
a[t] = s.data[t];
int i = p, j = mid;
for(int k = i; (i < mid) && (j < q); ++k)
if(a[i] < a[j])
s.data[k] = a[i++];
else
s.data[k] = a[j++];
while(i < mid)
s.data[k++] = a[i++];
while(j < q)
s.data[k++] = a[j++];
}
}
//快速排序
void quick_sort(table &T, int left, int right)
{
int p = left, q = right;
if(p > q)
return;
int k = T.data[p];
while(p < q)
{
while((p < q) && (k <= T.data[q]))
q--;
if(p < q)
T.data[p++] = T.data[q];
while((p < q) && (k >= T.data[p]))
p++;
if(p < q)
T.data[q--] = T.data[p];
}
T.data[p] = k;
quick_sort(T, left, p-1);
quick_sort(T, p+1, right);
}
示例:(读者可自行验证)