题目要求
实现折半插入排序、冒泡排序、快速排序、简单选择排序、归并排序、堆排序
C++ 源码
/*
上机序号:25~30
功能:排序
*/
#include <stdio.h>
#include <stdlib.h>
/* 宏定义 */
#define FALSE 0
#define TRUE 1
#define MAXINT INT_MAX
#define MAXSIZE 20 //一个用作示例的小顺序表的最大长度
#define ERROR -1
#define OK 1
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
typedef int KeyType;
typedef int Status;
typedef struct //顺序表结构
{
KeyType key; //关键字项
//使用结构体便于使用中扩展
}RcdType; //记录类型、
/* 顺序表存储结构 */
typedef struct
{
RcdType r[MAXSIZE + 1]; //r[0]闲置或用作哨兵单元
int length; //顺序表长度
}SqList_sort; //顺序表类型
/*静态链表存储结构 */
typedef struct
{
RcdType rc; //记录项
int next; //指针项
}SLNode; //表结点类型
typedef struct
{
SLNode r[MAXSIZE]; //0号单元为表头结点
int length; //链表当前长度
}SLinkList_sort; //静态链表类型
//顺序表的建立
Status CreateSortList(SqList_sort* L)
{
int i;
printf("请输入顺序表长度\n");
scanf("%d", &((*L).length));
if ((*L).length > MAXSIZE)
return ERROR;
printf("请输入顺序表中的元素\n");
for (i = 1; i <= (*L).length; i++)
{
scanf("%d", &((*L).r[i].key));
}
return OK;
}
//打印键值
void PrintKey(KeyType e)
{
printf("%d ", e);
}
//顺序表的遍历
void Traverse(SqList_sort L, void(Visit)(KeyType))
{
int i;
for (i = 1; i <= L.length; i++)
Visit(L.r[i].key);
printf("\n");
}
//折半插入排序
void BInsertSort(SqList_sort* L)
{
int i, j, low, high, m;
for (i = 2; i <= (*L).length; ++i)
{
(*L).r[0] = (*L).r[i]; //将(*L).r[i]暂存到(*L).r[0]
low = 1;
high = i - 1;
while (low <= high) //在r[low..high]中折半查找有序插入的位置
{
m = (low + high) / 2; //折半
if (LT((*L).r[0].key, (*L).r[m].key)) //插入点在低半区
high = m - 1;
else //插入点在高半区
low = m + 1;
}
for (j = i - 1; j >= high + 1; --j) //记录后移
(*L).r[j + 1] = (*L).r[j];
(*L).r[high + 1] = (*L).r[0]; //插入
}
}
//冒泡排序
void BubbleSort(SqList_sort* L)
{
int i, j;
RcdType tmp;
Status tag;
for (i = (*L).length; i >= 2; i--)
{
tag = FALSE; //tag标记遍历过程是否发生的交换
for (j = 1; j <= i - 1; j++)
{
if (LT((*L).r[j + 1].key, (*L).r[j].key))
{
tmp = (*L).r[j + 1];
(*L).r[j + 1] = (*L).r[j];
(*L).r[j] = tmp;
tag = TRUE; //若遍历不发生交换,说明序列已经有序
}
}
if (!tag)
break;
}
}
//快速排序
int Partition(SqList_sort* L, int low, int high)
{
int pivotkey;
(*L).r[0] = (*L).r[low]; //用子表第一个记录作枢轴记录
pivotkey = (*L).r[low].key; //枢轴记录关键字
while (low < high) //从表的两端交替地向中间扫描
{
while (low<high && (*L).r[high].key>pivotkey)
high--;
(*L).r[low] = (*L).r[high]; //将比枢轴记录小的记录交换到低端
while (low < high && (*L).r[low].key <= pivotkey)
low++;
(*L).r[high] = (*L).r[low]; //将比枢轴记录大的记录交换到高端
}
(*L).r[low] = (*L).r[0]; //枢轴记录到位
return low; //返回枢轴所在位置
}
void QSort(SqList_sort* L, int low, int high)
{
int pivotloc;
if (low < high) //长度大于1
{
pivotloc = Partition(L, low, high); //将(*L).r[row..high]一分为二
QSort(L, 1, pivotloc - 1); //对低子表递归排序,pivotloc是枢轴位置
QSort(L, pivotloc + 1, high); //对高子表递归排序
}
}
void QuickSort(SqList_sort* L)
{
QSort(L, 1, (*L).length);
}
//简单选择排序
int SelectMinKey(SqList_sort L, int i)
{
int min, k;
min = i;
L.r[0] = L.r[i];
for (k = i; k <= L.length; k++)
{
if (L.r[k].key < L.r[0].key)
{
min = k;
L.r[0] = L.r[k];
}
}
return min;
}
void SelectSort(SqList_sort* L)
{
int i, j;
RcdType tmp;
for (i = 1; i < (*L).length; i++)
{
j = SelectMinKey(*L, i);
if (i != j)
{
tmp = (*L).r[i];
(*L).r[i] = (*L).r[j];
(*L).r[j] = tmp;
}
}
}
//归并排序
void Merge(RcdType SR[], RcdType TR[], int i, int m, int n)
{
int j, k;
for (j = m + 1, k = i; i <= m && j <= n; ++k) //将SR中记录由小到大地并入TR
{
if (LQ(SR[i].key, SR[j].key))
TR[k] = SR[i++];
else
TR[k] = SR[j++];
}
while (i <= m) //将剩余的SR[i..m]复制到TR
TR[k++] = SR[i++];
while (j <= n) //将剩余的SR[j..n]复制到TR
TR[k++] = SR[j++];
}
void MSort(RcdType SR[], RcdType TR[], int s, int t)
{
int m;
RcdType R[MAXSIZE + 1];
if (s == t)
TR[s] = SR[s];
else
{
m = (s + t) / 2; //将SR[s..t]平分为SR[s..m]和SR[m+1..t]
MSort(SR, R, s, m); //递归地将SR[s..m]归并为有序的R[s..m]
MSort(SR, R, m + 1, t); //递归地将SR[m+1..t]归并为有序的R[m+1..t]
Merge(R, TR, s, m, t); //将R[s..m]和R[m+1..t]归并到TR[s..t]
}
}
void MergeSort(SqList_sort* L)
{
MSort((*L).r, (*L).r, 1, (*L).length);
}
//堆排序
typedef SqList_sort HeapType;
void HeapAdjust(HeapType* H, int s, int m)
{
int j;
RcdType rc;
rc = (*H).r[s];
for (j = 2 * s; j <= m; j *= 2) //沿key较大的孩子结点向下筛选
{
if (j < m && LT((*H).r[j].key, (*H).r[j + 1].key))
j++; //j为key较大的记录的下标
if (!LT(rc.key, (*H).r[j].key))
break; //rc应插入在位置s上
(*H).r[s] = (*H).r[j];
s = j;
}
(*H).r[s] = rc; //插入
}
void HeapSort(HeapType* H)
{
int i;
RcdType tmp;
for (i = (*H).length / 2; i > 0; i--) //把H.r[1..H.length]建成大顶堆
HeapAdjust(H, i, (*H).length);
for (i = (*H).length; i > 1; i--)
{
tmp = (*H).r[1]; //将堆顶记录和当前未经排序子序列Hr[1..i]中最后一个记录交换
(*H).r[1] = (*H).r[i];
(*H).r[i] = tmp;
HeapAdjust(H, 1, i - 1); //将H.r[1..i-1]重新调整为大顶堆
}
}
int main()
{
printf("-------------------折半插入排序----------------\n");
SqList_sort L1;
printf("创建并输出一个任意的序列\n");
CreateSortList(&L1);
printf("排序前\n");
Traverse(L1, PrintKey);
printf("排序后\n");
BInsertSort(&L1);
Traverse(L1, PrintKey);
printf("-------------------冒泡排序----------------\n");
SqList_sort L2;
printf("创建并输出一个任意的序列\n");
CreateSortList(&L2);
printf("排序前\n");
Traverse(L2, PrintKey);
printf("排序后\n");
BubbleSort(&L2);
Traverse(L2, PrintKey);
printf("-------------------快速排序----------------\n");
SqList_sort L3;
printf("创建并输出一个任意的序列\n");
CreateSortList(&L3);
printf("排序前\n");
Traverse(L3, PrintKey);
printf("排序后\n");
QuickSort(&L3);
Traverse(L3, PrintKey);
printf("-------------------简单选择排序----------------\n");
SqList_sort L4;
printf("创建并输出一个任意的序列\n");
CreateSortList(&L4);
printf("排序前\n");
Traverse(L4, PrintKey);
printf("排序后\n");
SelectSort(&L4);
Traverse(L4, PrintKey);
printf("-------------------归并排序----------------\n");
SqList_sort L5;
printf("创建并输出一个任意的序列\n");
CreateSortList(&L5);
printf("排序前\n");
Traverse(L5, PrintKey);
printf("排序后\n");
MergeSort(&L5);
Traverse(L5, PrintKey);
printf("-------------------堆排序----------------\n");
SqList_sort L6;
printf("创建并输出一个任意的序列\n");
CreateSortList(&L6);
printf("排序前\n");
Traverse(L6, PrintKey);
printf("排序后\n");
HeapSort(&L6);
Traverse(L6, PrintKey);
}