插入类排序,交换类排序,选择类排序,归并类排序,基数排序综合算法

## **内部排序**+外部排序**
```c
#include  <stdio.h>
#include "stdlib.h"
#define  KEYTYPE    int
#define  MAXSIZE    100
#define N 10
#define RADIX 10
typedef  struct
{ KEYTYPE   key;
}RcdType;
typedef  struct {
	RcdType   r[MAXSIZE+1]; // r[0]闲置
	int   length;            // 顺序表长度
	int maxkey;
} SqList;                                // 顺序表类型
typedef struct{
	int key;
	int next;
}SLcell;
typedef struct{
	SLcell *r;
	int keynum;
	int recnum;	
}SLlist;
typedef int ArrType[RADIX];
void createList(SqList  &L)
{ 
	int k;
	printf("\n>>>>>>>>>>系统将随机产生长度为%d的一张待排序的顺序表L<<<<<<<<<<\n\n",N);
	k = 0;L.maxkey=0;
	while(k<N) 
	{
		k++; 
		L.r[k].key = rand()%1000;
		if(L.r[k].key>L.maxkey)
			L.maxkey=L.r[k].key;
	}
	L.length=k;
}
void print_SqList(SqList  L)
{int i;
for (i = 0; i < L.length; i++)  
	printf("  %d",L.r[i+1].key);
printf("\n");
}
void insertsort(SqList  &L)
{/*直接插入排序*/
	int i,j;
	for(i = 2; i <= L.length; i++)
	{ L.r[0] = L.r[i];   j = i - 1;     /*r[0]是监视哨,j表示当前已排好序列的长度*/
	while(L.r[0].key < L.r[j].key)    /*确定插入位置*/
	{L.r[j + 1] = L.r[j];   j--;}
	L.r[j + 1] = L.r[0];              /*元素插入*/
	}
}
void insertsort_bin(SqList&L)
{/*折半插入排序*/
	int i,j,low,high,mid;
	for(i = 2; i <= L.length; i++)
	{ 
		if(L.r[i].key<L.r[i-1].key)	
		{
			L.r[0]=L.r[i];
			low=1;high=i-1;
			while(low<=high)
			{
				mid=(low+high)/2;
				if(L.r[mid].key<L.r[0].key)
					low=mid+1;
				else 
					high=mid-1;
			}
			for(j=i;j>high+1;j--)
				L.r[j]=L.r[j-1];
			L.r[high+1]=L.r[0];
		}
	}
}
void ShellInsert(SqList&L,int dk)
{/*对顺序表L做一趟希尔插入排序,前后记录的增量是dk,而不是1 ,0号单元只是暂存单元,不是哨兵。当j<=0时,插入位置已找到*/
	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];//暂存在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];//插入到正确的位置
	}
}
void ShellSort(SqList&L,int dlta[],int t)
{//按增量序列dlta[0..t-1]对顺序表L作希尔排序
	for(int k=0;k<t;++k)
		ShellInsert(L,dlta[k]);//一趟增量为dlta[k]的插入排序
}
void bublesort(SqList  &L)
{/*简单交换排序:冒泡排序*/
	int i, j,swapflag=1;
	RcdType temp;
	for(i = 1; i < L.length&&swapflag; i++)
	{
		swapflag=0;
		for(j = L.length - 1; j >= i; j--)
			if(L.r[j + 1].key < L.r[j].key)
			{temp = L.r[j + 1];  
		L.r[j + 1] = L.r[j];  
		L.r[j] = temp;
		swapflag=1;}
	}
}
int partition(SqList  &L, int low, int high)
{/*一趟快速排序,返回i,产生了两个独立的待排子序列*/
	int i, j;
	RcdType	 temp;
	i = low;  j = high;
	temp = L.r[i];                                         /*枢轴记录保存在temp变量中*/
	do{ while((L.r[j].key >= temp.key) && (i < j))  j--;   /*j指针记录和枢轴记录比较*/
	if(i < j)    { L.r[i] = L.r[j];   i++;}
	while((L.r[i].key <= temp.key) && (i < j))   i++;   /*i指针记录和枢轴记录比较*/
	if(i < j)     { L.r[j] = L.r[i];   j--;}
	}while(i != j);
	L.r[i] = temp;                                         /*枢轴记录的排序位置确定在i*/
	return i;
}
void quicksort(SqList  &L ,int start, int end)
{/*快速排序*/
	int i;
	if(start < end)
	{ i = partition(L, start, end);  /*一趟快速排序,返回i,产生了两个独立的待排子序列*/
	quicksort(L, start, i - 1);      /*对两个独立的待排子序列分别递归调用快速排序算法*/
	quicksort(L, i + 1,end);}
}
void selectsort(SqList  &L)
{/*简单选择排序*/
	int i,j,k;
	RcdType temp;
	for(i = 1; i < L.length; i++)
	{ k = i;                       /*k:最小关键字的初始位置*/
	for(j = i + 1; j <= L.length; j++)
		if(L.r[j].key < L.r[k].key)
			k = j;                  /*k:跟踪记录当前最小关键字的位置*/
	if(k != i)                   /*最小关键字元素和待排序列的第一个元素交换*/
	{temp = L.r[i];   L.r[i] = L.r[k];   L.r[k] = temp;}
	}
}
void sift(SqList  &L, int i, int m)
{/*i是根结点编号,m是以i结点为根的子树中最后一个结点的编号*/
	int j;
	RcdType temp;
	temp = L.r[i];
	j = 2 * i;       /*j为i根结点的左孩子*/
	while(j <= m)
	{if(j < m && (L.r[j].key < L.r[j + 1].key))
	j++;                                  /*当i结点有左右孩子时,j取关键字大的孩子结点编号*/
	if(temp.key < L.r[j].key)
	{ L.r[i] = L.r[j];   i = j;   j = 2 * i;}/*按堆定义调整,并向下一层筛选调整 */
	else   break;                          /*筛选调整完成,跳出循环 */
	}
	L.r[i] = temp;
}
void heapsort(SqList  &L)
{/*堆排序: n为r表中记录数,从r[1]开始放起*/
	int i;
	RcdType temp;
	for(i = L.length/2; i >= 1; i--)
		sift(L, i, L.length);             /*将无序序列建成大堆*/
	for(i = L.length; i >= 2; i--)
	{temp = L.r[1];              /*堆顶及堆尾元素交换*/
	L.r[1] = L.r[i];
	L.r[i] = temp;
	sift(L,1,i - 1);          /*交换后,从第一个元素开始调整为大堆,每次记录个数少一个*/
	}         
}
void merge(RcdType SR[], RcdType TR[], int low, int high ,int mid)  
{  
	int i = low;  
	int k = low;  
	int j = mid + 1;  
	while ( i<= mid&&j<= high)  
	{  
		if (SR[i].key<SR[j].key)  
			TR[k++] = SR[i++];  
		else  
			TR[k++] = SR[j++];  
	}  
	while (i <= mid)  
		TR[k++] = SR[i++];  
	while (j <= high)  
		TR[k++] = SR[j++];  
}  
void MSort(RcdType SR[], RcdType TR[] ,int low, int high, int max_size)  
{  
	if (low == high)  
		TR[low] = SR[low];  
	else  
	{  
		int mid = (low + high) / 2;  
		RcdType * TR2 = (RcdType *)malloc(sizeof(RcdType) * max_size);  
		if (TR2)  
		{  
			MSort( SR, TR2, low, mid, max_size);  
			MSort( SR, TR2, mid+1, high, max_size);  
			merge( TR2, TR, low, high, mid);  
		}     
		free(TR2);  
	}  
}  
void Merge_Sort(SqList&L)  
{  
	MSort( L.r, L.r, 1, L.length, L.length+1);  
} 
//基数排序相关操作

int ord(int a,int i){//取第i个关键字
	int e,t;
	e=a;t=i;
	while(t>1){e/=10;t--;}
	e=e%10;
	return e;
}
void Distribute(SLlist &H,int i,ArrType &f, ArrType &e){
	int j;
	int p,q;
	for(j=0;j<RADIX;j++)f[j]=0;
	for(p=H.r[0].next;p;p=H.r[p].next){
		j=ord(H.r[p].key,i);
		if(!f[j])f[j]=p;
		else H.r[e[j]].next=p;
		e[j]=p;
	}
	printf("第%d趟分配后顺序为:",i);
	for (j=0;j<RADIX;j++)
	{if(f[j])
	{	p=f[j];q=e[j];
	while(p!=q){printf("%d ",H.r[p].key); p=H.r[p].next;}
	printf("%d ",H.r[q].key);
	}

	}printf("\n");
}
void Collect(SLlist &H,int i,ArrType &f,ArrType &e)
{
	int j,t,k;
	for (j=0;j<RADIX&&(f[j]==0);j++);
	H.r[0].next=f[j]; t=e[j];
	for (k=j+1;k<RADIX;k++)
		if(f[k])  {	H.r[t].next=f[k];t=e[k];}
		H.r[t].next=0;
}
void printSList(SLlist &H)
{
	printf("当前静态链表为:");
	int i;
	for(i=1;H.r[i].next;i=H.r[i].next)
		printf("%d->",H.r[i].key);
	printf("%d\n",H.r[i].key);
}
void RadixSort(SqList &L){//将顺序表L先转化为链表H,对H进行操作
	SLlist H;
	int i,k,t;
	ArrType f,e;
	H.recnum=L.length;
	if(L.maxkey<10)
		H.keynum=1;
	else
		if(L.maxkey<100)
			H.keynum=2;
		else if(L.maxkey<1000)
			H.keynum=3;
		else H.keynum=4;
		H.r=(SLcell*)malloc(MAXSIZE*sizeof(SLcell));
		for(i=0;i<H.recnum;i++){
			H.r[i].next=i+1;
			H.r[i+1].key=L.r[i+1].key;
		}//将顺序表L先转化为链表H
		H.r[H.recnum].next=0;
		printSList(H);
		for(i=1;i<=H.keynum;i++){
			Distribute(H,i,f,e);
			Collect(H,i,f,e);

		}

		t=H.r[0].next;
		for(i=1;i<=L.length;i++){
			L.r[i].key=H.r[t].key;
			t=H.r[t].next;

		}
}

void menu()
{
	printf("|==================================|\n");
	printf("|    ****---- 选择式菜单 ----****  |\n");
	printf("|==================================|\n");
	printf("|                                  |\n");
	printf("|           1:插入类排序           |\n");
	printf("|                                  |\n");
	printf("|           2:交换类排序           |\n");
	printf("|                                  |\n");
	printf("|           3:选择类排序           |\n");
	printf("|                                  |\n");
	printf("|           4:归并类排序           |\n");
	printf("|                                  |\n");
	printf("|           5:基数排序             |\n");
	printf("|                                  |\n");
	printf("|           0:退出菜单             |\n");
	printf("|                                  |\n");
	printf("|==================================|\n");
}//menu
void menu1()
{
	printf("|==================================|\n");
	printf("|    ****---插入类排序菜单---****  |\n");
	printf("|==================================|\n");
	printf("|                                  |\n");
	printf("|           1:直接插入排序         |\n");
	printf("|                                  |\n");
	printf("|           2:折半插入排序         |\n");
	printf("|                                  |\n");
	printf("|           3:希尔                 |\n");
	printf("|                                  |\n");
	printf("|           0:返回上层             |\n");
	printf("|                                  |\n");
	printf("|==================================|\n");
}//menu1
void menu2()
{
	printf("|==================================|\n");
	printf("|    ****---交换类排序菜单---****  |\n");
	printf("|==================================|\n");
	printf("|                                  |\n");
	printf("|           1:冒泡排序             |\n");
	printf("|                                  |\n");
	printf("|           2:快速排序             |\n");
	printf("|                                  |\n");
	printf("|           0:返回上层             |\n");
	printf("|                                  |\n");
	printf("|==================================|\n");
}//menu2
void menu3()
{
	printf("|==================================|\n");
	printf("|    ****---选择类排序菜单---****  |\n");
	printf("|==================================|\n");
	printf("|                                  |\n");
	printf("|           1:简单选择排序         |\n");
	printf("|                                  |\n");
	printf("|           2:堆选择排序           |\n");
	printf("|                                  |\n");
	printf("|           0:返回上层             |\n");
	printf("|                                  |\n");
	printf("|==================================|\n");
}//menu3
int main() {
	SqList L;
	int k,k1,k2,k3;
	int loop=1,loop1=1,loop2=1,loop3=1;
	int dlta[3]={5,3,1};//希尔排序增量序列
	while (loop) {
		system("cls");
		menu();
		printf(" 请选择项号:");
		scanf("%d",&k);
		switch(k) {
		case 0: loop = 0;
			break;
		case 1:  
			system("cls");
			loop1=1;
			while (loop1) {
				menu1();
				printf(" 请选择项号:");
				scanf("%d",&k1);
				switch(k1) {
				case 0: loop1 = 0;
					break;
				case 1:  
					system("cls");
					createList(L);
					printf("\n直接插入排序前: ");
					print_SqList(L);
					insertsort(L);
					printf("\n直接插入排序后: ");
					print_SqList(L);
				break;
				case 2:  
					system("cls");
					createList(L);
					printf("\n折半插入排序前: ");
					print_SqList(L);
					insertsort_bin(L);
					printf("\n折半插入排序后: ");
					print_SqList(L);
					break;
				case 3:  
					system("cls");
					createList(L);
					printf("\n希尔排序前: ");
					print_SqList(L);
					ShellSort(L,dlta,3);
					printf("\n希尔排序后: ");
				    print_SqList(L);
					break;
				default:system("cls");
					printf("警告!你给的选项号非法,请重新输入\n");
				}
			}
			break;
		case 2:  
			system("cls");
			loop2=1;
			while (loop2) {
				menu2();
				printf("请选择项号:");
				scanf("%d",&k2);
				switch(k2) {
				case 0: loop2 = 0;
					break;
				case 1:  
					system("cls");
					createList(L);
					printf("\n冒泡排序前: ");
					print_SqList(L);
					bublesort(L);
					printf("\n冒泡排序后: ");
					print_SqList(L);
			       break;	
				case 2:
					system("cls");
					createList(L);
					printf("\n快速排序前: ");
					print_SqList(L);
					quicksort(L, 1, L.length);
					printf("\n快速排序后: ");
					print_SqList(L);
					break;
				default:system("cls");
					printf("警告!你给的选项号非法,请重新输入\n");
				}
			}
			break;
		case 3: 
			system("cls");
			loop3=1;
			while (loop3) {
				menu3();
				printf("请选择项号:");
				scanf("%d",&k3);
				switch(k3) {
				case 0: loop3 = 0;
					break;
				case 1:
				   system("cls");
			       createList(L);
				   printf("\n简单选择排序前: ");
			        print_SqList(L);
			        selectsort(L);
					printf("\n简单选择排序后: ");
			       print_SqList(L);
			     break;
				case 2:
					system("cls");
					createList(L);
					 printf("\n堆选择排序前: ");
					print_SqList(L);
					heapsort(L);
					 printf("\n堆选择排序后: ");
					print_SqList(L);
					break;
				default:system("cls");
					printf("警告!你给的选项号非法,请重新输入\n");
				}
			}
			break;
		case 4: 
			system("cls");
			createList(L);
			printf("\n归并排序前: ");
			print_SqList(L);   
			Merge_Sort(L);
			printf("\n归并排序后: ");
			print_SqList(L); 
			system("pause");
			break;   
		case 5: 
			system("cls");
			createList(L); 
			printf("\n基数排序前: ");
			print_SqList(L);   
			RadixSort(L);
			printf("\n基数排序后: ");
			print_SqList(L); 
			system("pause");
			break;  
		default:system("cls");
			printf("警告!你给的选项号非法,请重新输入\n");
		}

	}
	return 0;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值