数据结构上机作业(c++)—— 六大排序算法

题目要求

实现折半插入排序、冒泡排序、快速排序、简单选择排序、归并排序、堆排序

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);
}

样例测试

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zyw2002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值