8.3 交换排序
交换排序的基本思想是:
两两比较待排序记录的关键字,一旦发现两个记录不满足次序要求时则进行交换,直到整个序列全部满足要求为止。
8.3.1 冒泡排序
【基本思想】
两两比较相邻记录的关键字,如果发生逆序,则进行交换。
从而使关键字小的记录如气泡一般逐渐往上 "漂浮"(左移),或者使关键字大的记录如石块一样逐渐向下 "坠落 ” (右移)。
【算法特点】
(1) 稳定排序。
(2) 可用于链式存储结构。
(3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 26
typedef int KeyType;
typedef char InfoType;
typedef struct
{
KeyType key;
InfoType otherinfo;
}RedType;
typedef struct
{
RedType r[MAXSIZE + 1]; //r[O]闲置或用做哨兵单元
int length;
}SqList;
void CreateSqList(SqList& L);
void BubbleSort(SqList& L);
void printSqList(SqList L);
int main()
{
SqList L = {
{
0},0 };
CreateSqList(L);
BubbleSort(L);
printSqList(L);
return 0;
}
void CreateSqList(SqList& L)
{
int i = 0;
printf("请输入顺序表的元素个数:");
scanf_s(" %d", &L.length);
for (i = 1; i <= L.length; i++)
{
printf("请输入第%d个关键字:", i);
scanf_s(" %d", &L.r[i].key);
}
}
//算法8.4 冒泡排序
void BubbleSort(SqList& L)
{
int m = L.length - 1;
int flag = 1; //flag用来标记某一趟排序是否发生交换
int j = 0;
RedType temp = {
0,'\0' };
while (m > 0 && flag == 1)
{
flag = 0; //flag置为0, 如果本趟排序没有发生交换,则不会执行下一趟排序
//第 L.length - m 趟冒泡排序
for (j = 1; j <= m; j++) //j最大值只能取到m.每趟冒泡排序针对的是从L.r[1]到L.r[m+1],将其中最大的,放到最后一个位置,即L.r[m+1]处
{
if (L.r[j].key > L.r[j + 1].key) //当L.r[j].key == L.r[j+1].key时,不会发生交换,保证了本冒泡排序的稳定性。
{
flag = 1; //flag置为1, 表示本趟排序发生了交换
//交换前后两个记录
temp = L.r[j];
L.r[j] = L.r[j + 1];
L.r[j + 1] = temp;
}
}
//序列中从L.r[m + 1]到L.r[L.length]处的元素都有序了
--m;
//【m自减之后】下一次冒泡排序针对的仍然是从L.r[1]到L.r[m+1]的关键字
}
}
void printSqList(SqList L)
{
int i = 0;
printf("\n\n排序后的序列为:");
for (i = 1; i <= L.length; i++)
{
printf("\nr[%d].key = %d", i, L.r[i].key);
}
}
8.3.2 快速排序
【基本思想】
通过两个(不相邻) 记录的一次比较及交换,消除多个逆序。
在待排序的n个记录中任取一个记录(通常取第一个记录)作为枢轴(或支点),设其关键字为pivotkey。经过一趟排序后,把所有关键字小于pivotkey 的记录交换到前面,把所有关键字大于pivotkey 的记录交换到后面,结果将待排序记录分成两个子表,最后将枢轴放置在分界处的位置。
然后,分别对左、右子表重复上述过程,直至每一子表只有一个记录时,排序完成。
【算法特点】
(1)记录非顺次的移动导致排序方法是不稳定的。
(2)排序过程中需要定位表的下界和上界,所以适合用于顺序结构,很难用于链式结构。
(3)当n较大时,在平均情况下快速排序是所有内部排序方法中速度最快的一种,所以其适合初始记录无序、 n较大时的情况。
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 26
typedef int KeyType;
typedef char InfoType;
typedef s