数据结构之七大排序算法合并版

该文提供了一组C++实现的排序算法,包括直接插入排序、折半插入排序、希尔排序、冒泡排序、快速排序、简单选择排序和归并排序。每种算法都有详细的代码实现,并通过示例数据展示排序过程。文章关注点在于各种排序算法的效率和实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//以下算法不足
//1.效率有点低,做不到 就差一个就排好序的情况下一步即可,而这里始终都是n-1次排序
#include <iostream>
using namespace std;
#define  MAXSIZE  20          						//顺序表的最大长度

typedef struct {
	int key;
	char *otherinfo;
} ElemType;

//顺序表的存储结构
typedef struct {
	ElemType *r;	         						//存储空间的基地址
	int  length;            						//顺序表长度
} SqList;											//顺序表类型

void show(SqList L) {
	int i;
	for (i = 1; i <= L.length; i++)
		cout << L.r[i].key << "  ";
	cout << endl;
}

//折半插入
void BInsertSort(SqList &L) {

	int m, low, high, j, i;
	for ( i = 2; i <= L.length; i++) {
		L.r[0] = L.r[i];
		low = 1;
		high = i - 1;
		while (low <= high) {
			m = low + high / 2;
			if (L.r[0].key < L.r[m].key) {
				high = m - 1;
			} else {
				low = m + 1;
			}
		}
		//找到位置high为i的前一个位置,因此i要插入到high+1位置,high+1后面的要后移
		for (j = i - 1; j >= high; --j) {
			L.r[j + 1] = L.r[j];

		}
		L.r[high + 1] = L.r[0];
		printf("第%d次排序情况:", i - 1);
		show(L);
		printf("\n");
	}




	//将r[0]即原r[i],插入到正确位置
}												//for



//直接插入
void InsertSort(SqList &L) {
	//对顺序表L做直接插入排序
	int i, j;

	for (i = 2; i <= L.length; ++i) {

		if (L.r[i].key < L.r[i - 1].key) {
			//"<",需将r[i]插入有序子表
			L.r[0] = L.r[i];				 			//将待插入的记录暂存到监视哨中
			L.r[i] = L.r[i - 1];	            		//r[i-1]后移
			for (j = i - 2; L.r[0].key <= L.r[j].key; --j)			//从后向前寻找插入位置
				L.r[j + 1] = L.r[j];					//记录逐个后移,直到找到插入位置
			L.r[j ] = L.r[0];						//将r[0]即原r[i],插入到正确位置
		}
		printf("第%d次排序情况:", i - 1);
		show(L);
		printf("\n");
	}									//if
}													//InsertSort

void Create_Sq(SqList &L) {
	int i, n;
	cout << "请输入数据个数,不超过" << MAXSIZE << "个。" << endl;
	cin >> n;											//输入个数
	cout << "请输入待排序的数据:\n";

	while (n > MAXSIZE) {
		cout << "个数超过上限,不能超过" << MAXSIZE << ",请重新输入" << endl;
		cin >> n;
	}

	for (i = 1; i <= n; i++) {
		cin >> L.r[i].key;
		L.length++;
	}
}


//希尔核心算法
void ShellInsert(SqList &L, int dk) {
	//对顺序表L做一趟增量是dk的希尔插入排序
	int i, j;
	for (i = dk + 1; i <= L.length; ++i)

		if (L.r[i].key < L.r[i - dk].key) {
			//需将L.r[i]插入有序增量子表
			L.r[0] = L.r[i];						//暂存在L.r[0]
			for (j = i - dk; j > 0 && L.r[0].key < L.r[j].key; j -= dk)
				L.r[j + dk] = L.r[j];				//记录后移,直到找到插入位置
			L.r[j + dk] = L.r[0];	//将r[0]即原r[i],插入到正确位置



		}										//for


	show(L);
	printf("\n");
}

//希尔趟数
void ShellSort(SqList &L, int dt[ ], int t) {
	//按增量序列dt[0..t-1]对顺序表L作t趟希尔排序
	int k;
	for (k = 0; k < t; ++k)
		//printf("%d\n", k);
		ShellInsert(L, dt[k]);//5,3,1			 		//一趟增量为dt[t]的希尔插入排序

}												//ShellSort


//冒泡排序
void BubbleSort(SqList L) {
	//对顺序表L做冒泡排序
	int m, j, flag, i = 1;
	ElemType t;//ElemType
	m = L.length - 1;
	flag = 1; 				//flag用来标记某一趟排序是否发生交换

	while ((m > 0) && (flag == 1)) {
		flag = 0;           				//flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序
		for (j = 1; j <= m; j++)
			if (L.r[j].key > L.r[j + 1].key) {
				flag = 1;					//flag置为1,表示本趟排序发生了交换
				t = L.r[j];
				L.r[j] = L.r[j + 1];
				L.r[j + 1] = t;	//交换前后两个记录
			}							//if
		--m;
		printf("第%d次排序情况:", i);
		i++;
		show(L);
		printf("\n");
	}									//while
}										//BubbleSort

//快速排序2
int Partition(SqList &L, int low, int high) {
	//对顺序表L中的子表r[low..high]进行一趟排序,返回枢轴位置
	int pivotkey;
	L.r[0] = L.r[low];                    	//用子表的第一个记录做枢轴记录
	pivotkey = L.r[low].key;		   			//枢轴记录关键字保存在pivotkey中

	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];					//将比枢轴记录大的记录移到高端
	}//while
	L.r[low] = L.r[0];
	//int i = 1;						//枢轴记录到位
	printf("排序情况:");
	show(L);
	printf("\n");
	return  low;							//返回枢轴位置
}//Partition

//快速排序
void QSort(SqList &L, int low, int high) {
	//调用前置初值:low=1; high=L.length;
	//对顺序表L中的子序列L.r[low..high]做快速排序
	int pivotloc;
	int i = 1;

	if (low < high) {
		//长度大于1
		pivotloc = Partition(L, low, high); 		//将L.r[low..high]一分为二,pivotloc是枢轴位置
		QSort(L, low, pivotloc - 1);				//对左子表递归排序
		QSort(L, pivotloc + 1, high);        	//对右子表递归排序
	}
}											//QSort

void SelectSort(SqList &L) {
	//对顺序表L做简单选择排序
	int i, j, k;
	ElemType t;

	for (i = 1; i < L.length; ++i) {
		//在L.r[i..L.length] 中选择关键字最小的记录
		k = i;
		for (j = i + 1; j <= L.length; ++j)
			if (L.r[j].key < L.r[k].key)
				k = j;			//k指向此趟排序中关键字最小的记录
		if (k != i) {
			t = L.r[i];    //交换r[i]与r[k]
			L.r[i] = L.r[k];
			L.r[k] = t;
		}
		printf("第%d次排序情况:", i);
		show(L);
		printf("\n");

	}
}

//归并三
//用算法8.10 相邻两个有序子序列的归并
void Merge(ElemType R[], ElemType T[], int low, int mid, int high) {
	//将有序表R[low..mid]和R[mid+1..high]归并为有序表T[low..high]
	int i, j, k;
	i = low;
	j = mid + 1;
	k = low;

	while (i <= mid && j <= high) {
		//将R中记录由小到大地并入T中
		if (R[i].key <= R[j].key)
			T[k++] = R[i++];
		else
			T[k++] = R[j++];
	}
	while (i <= mid)                            		//将剩余的R[low..mid]复制到T中
		T[k++] = R[i++];
	while (j <= high)                           		//将剩余的R[j.high]复制到T中
		T[k++] = R[j++];


}//Merge

//归并2
void MSort(ElemType R[], ElemType T[], int low, int high) {
	//R[low..high]归并排序后放入T[low..high]中
	int mid;
	ElemType *S = new ElemType[MAXSIZE];
	if (low == high)
		T[low] = R[low];

	else {
		mid = (low + high) / 2;       					//将当前序列一分为二,求出分裂点mid
		MSort(R, S, low, mid);							//对子序列R[low..mid] 递归归并排序,结果放入S[low..mid]
		MSort(R, S, mid + 1, high);						//对子序列R[mid+1..high] 递归归并排序,结果放入S[mid+1..high]
		Merge(S, T, low, mid, high);					//将S[low..mid]和S [mid+1..high]归并到T[low..high]
	}//else

}

int main() {
	SqList L;
	L.r = new ElemType[MAXSIZE + 1];
	L.length = 0;
	// 输入数据,插入顺序表

	printf("1.直接插入排序、2.折半插入排序、3.希尔排序、4.冒泡排序、5.快速排序、6.简单选择排序、7.归并排序\n\n");
	printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
	int i, t; //增量数组的长度
	int *dt = new int[MAXSIZE]; //增量数组
	int a = 0;
	scanf("%d", &a);

	while (1) {
		switch (a) {

			//注意在这里不能放一个大括号,不然会死循环

			case 1:
				printf("请先输入要排序的数据\n\n");
				Create_Sq(L);
				printf("1.直接插入排序\n");
				InsertSort(L);
				cout << "排序后最终的结果为:" << endl;
				show(L);//打印
				printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
				scanf("%d", &a);
				break;
			case 2:
				printf("请先输入要排序的数据\n\n");
				Create_Sq(L);
				printf("2.折半排序\n");
				BInsertSort(L);
				cout << "排序后最终的结果为:" << endl;
				show(L);//打印
				printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
				scanf("%d", &a);
				break;
			case 3:
				printf("请先输入要排序的数据\n\n");
				Create_Sq(L);
				printf("3.希尔排序\n");
				cout << "请输入增量个数:\n";
				cin >> t;
				//把增量存入数组
				for (i = 0; i < t; i++) {
					cout << "第" << i + 1 << "个增量:\n";
					cin >> dt[i];
				}

				ShellSort(L, dt, t);//希尔
				cout << "排序后最终的结果为:" << endl;
				show(L);//打印
				printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
				scanf("%d", &a);
				break;
			case 4:
				printf("请先输入要排序的数据\n\n");
				Create_Sq(L);
				printf("4.冒泡排序\n");
				BubbleSort(L);//冒泡
				cout << "排序后最终的结果为:" << endl;
				show(L);//打印
				printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
				scanf("%d", &a);
				break;
			case 5:
				printf("请先输入要排序的数据\n\n");
				Create_Sq(L);
				printf("5.快速排序\n");
				QSort(L, 1, L.length); //快速排序
				cout << "排序后最终的结果为:" << endl;
				show(L);//打印
				printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
				scanf("%d", &a);
				break;

			case 6:
				printf("请先输入要排序的数据\n\n");
				Create_Sq(L);
				printf("6.简单选择排序\n");
				SelectSort(L);//选择排序
				cout << "排序后最终的结果为:" << endl;
				show(L);//打印
				printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
				scanf("%d", &a);
				break;

			case 7:
				printf("请先输入要排序的数据\n\n");
				Create_Sq(L);
				printf("7.简单选择排序\n");
				SqList R;
				MSort(L.r, L.r, 1, L.length);
				cout << "排序后最终的结果为:" << endl;
				show(L);//打印
				printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
				scanf("%d", &a);
				break;
		}
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值