一、排序的基本概念
排序:把一个无序的元素序列按照元素的关键字递增或递减排列为有序的序列。
假设包含n个元素(记录)的的序列
(E1,E2,….,En)
对应的关键字为
(k1,k2,…,kn)
,需确定1,2,…,n的一种排列
p1,p2,…,pn
,使关键字满足非递减(或非递增)关系
kp1≤kp2≤…≤kpn
,从而使元素构成一个非递减(或非递增)的序列
(Ep1,Ep2,….,Epn)
,这个的一种操作被称为排序。
稳定排序和不稳定排序:在待排序的记录序列中,若存在两个或两个以上关键字相等的记录。假设
ki=kj(1≤i≤n,1≤j≤n,i≠j)
,且排序前对应的记录
Ei
(即
i<j
)。在排序之后,如果元素
Ei
仍领先于
Ej
,则称这种排序采用的方法是稳定的。如果经过排序之后元素
Ej
领先于
Ei
,则称这种排序方法是不稳定的。
内排序和外排序:由于待排序的记录数量不同,使得排序过程中涉及的存储器不同,可将排序方法分为内部排序和外部排序两类。内部排序也称内排序,指的是待排序记录存在在计算机随机存储器中进行的排序过程;瓦布排序也称为外排序,指的是是待排序记录的数据量很大,一致内存不能容纳全部记录,在排序的过程中需要不断对外存进行访问的排序过程。
一个排序算法的好坏主要可以通过时间复杂度、空间复杂度和稳定性来衡量。无论算法稳定还是不稳定,都不会影响到排序的最终结果。通常只考虑比较关键字的次数和移动记录的次数。当关键字是字符串时,比较关键字要占用较多的时间,是影响时间复杂性的主要因素。而当记录很大时,为了交换记录的位置,移动记录成为影响时间复杂性的主要因素。
在排序过程中需要一下两种基本操作:
- 比较两个元素相应关键字的大小。
- 将元素从一个位置移动到另一个位置。
第一种操作对大多数排序算法来说是必要的,第二中操作可通过改变记录的存储方式避免。
待排序的记录序列可由下列3中存储方式:
- 顺序存储:待排序的元素存储在一组连续的存储单元中,这类似于线性表的顺序存储,在序列中相邻的两个记录 Ei 和 Ej ,它们的物理位置也相邻。在这种存储方式中,记录之间的次序关系由其存储位置决定,则实现排序必须移动记录。
- 链式存储:待排序的元素存储在一组不连续的存储单元中,这类似于线性表的链式存储,序列中相邻的两个记录 Ei 和 Ej ,它们的物理位置不一定相邻。在这种存储方式中,不需要移动元素,只需要修改指针即可。
- 静态链表:待排序记录存放在静态链表中,记录之间的关系由被称为游标的指针指示,实现排序不需要移动元素,只需要修改游标即可。
为了算法实现方便, 本文的排序算法主要采用顺序存储,相应的元素类型描述如下:
#define MaxSize 100
typedef int KeyType;
typedef struct /*数据元素类型定义*/
{
KeyType key;/*关键字*/
}DataType;
typedef struct /*顺序表类型定义*/
{
DataType data[MaxSize];
int length;
}SqList;
二、插入排序
1.直接插入排序
详情请点击查看直接插入排序
2.折半插入排序
详情请点击查看折半插入排序
3.2-路插入排序
详情请点击查看2-路插入排序
4.表插入排序
详情请点击查看表插入排序
5.希尔排序
详情请点击查看希尔排序
三、交换排序
1.冒泡排序
详情请点击查看冒泡排序
2.快速排序
详情请点击查看快速排序
四、选择排序
1.简单选择排序
详情请点击查看简单选择排序
2.树形选择排序
详情请点击查看树形选择排序
3.堆排序
详情请点击查看堆排序
五、归并排序
详情请点击查看归并排序
六、基数排序
详情请点击查看基数排序