排序的定义:
- 假设含有 n 个记录的序列为{r1, r2…… rn},其相应的关键字分别为{k1, k 2 ,…… kn}, 需确定 1, 2 ,……, n 的一种排列 p1 , p2, …… pn,使其相应的关键字满足 kp1 <= kp2 <= ……<= k pn(非递减或非递增)关系,使得序列成为一个按关键字有序的序列{rp1, rp2 ,……rpn},这样的操作就称为排序。
排序的稳定性——针对排序方法而言
假设 kj = ki (1 <= i <= n, 1 <= j <= n , i ≠ j) ,且在排序前的序列中 ri 领先于 rj (即 i < j),如果排序后 ri 仍领先于 rj ,则称所用的排序方法是稳定的;反之,若可能使得排序后序列中 rj 领先于 ri,则称所用的排序方法是不稳定的。
内排序和外排序
内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中,外排序是由于排序的记录个数太多,不能同时放置在内存,整个排序过程需要在内外存之间多次交换数据才能进行。
对于内排序来说,排序算法的性能主要是受 3 个方面影响:
- 时间性能
排序是数据处理中经常执行的一种操作,往往属于系统的核心部分,因此排序算法的时间开销是衡量其好坏的最重要的标志,在内排序中,主要进行两种操作:比较和移动。
高效率的内排序算法应该是尽可能少的关键字比较次数和尽可能少的记录移动次数。
- 辅助空间
- 算法的复杂性
即算法本身的复杂度
※※※※※ 七种排序算法
简单算法: 冒泡排序、简单选择排序和直接插入排序
改进算法: 希尔排序、堆排序、归并排序、快速排序
排序用到的结构与函数
为了讲清楚排序算法的代码,下面是用于排序用的顺序表结构,此结构将用于之后我们要讲的所有排序算法。
#define MAXSIZE 10000 /* 用于要排序数组个数最大值,可根据需要修改 */
typedef struct
{
int r[MAXSIZE+1]; /* 用于存储要排序数组,r[0]用作哨兵或临时变量 */
int length; /* 用于记录顺序表的长度 */
}SqList;
另外,由于排序是最常用的操作是数组量元素之间的交换,我们把它写成函数,在之后的讲解中会大量的用到。
/* 交换L中数组r的下标为i和j的值 */
void swap(SqList *L,int i,int j)
{
int temp=L->r[i];
L->r[i]=L->r[j];
L->r[j]=temp;
}