排序算法

1. 插入排序:每一趟将一个待排序的记录,按其关键字值得大小插入到已经排序的部分文件中的适当的位置上,直到插入完成

1.1 直接插入查询

基本思想:依次将每个记录插入到一个有序的序列中区。

#include <stdio.h>
#define MaxSize 100
typedef int KeyType;		/*关键字类型*/
typedef char ElemType[10];	/*其他数据项类型*/
typedef struct 
{	
	KeyType key;   			/*关键字域*/
	ElemType data; 			/*其他数据域*/
} LineList;					/*线性表元素类型*/
void InsertSort(LineList R[],int n)
{
	int i,j;
	LineList tmp;
	for (i=1;i<n;i++)
	{	
		tmp=R[i];
		j=i-1;
		while (j>=0 && tmp.key<R[j].key)/*元素后移,以便腾出一个位置插入tmp*/
		{	
			R[j+1]=R[j];
			j--;
		}
		R[j+1]=tmp;		/*在j+1位置处插入tmp*/
	}
}
void main()
{
	LineList R[MaxSize];
	KeyType a[]={75,87,68,92,88,61,77,96,80,72};
	int n=10,i;
	for (i=0;i<n;i++)
		R[i].key=a[i];
	printf("排序前:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
	InsertSort(R,n);
	printf("排序后:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
}


1.2 希尔排序

基本思想:把记录下标的一定增量d分组,对每组记录采用直接插入排序方法进行排序,随着增量的逐渐减小,所分成的组包含的记录越来越多,到增量为1时,整个数据合成为一组,构成一组有序记录,则完成排序。

#include <stdio.h>
#define MaxSize 100
typedef int KeyType;		/*关键字类型*/
typedef char ElemType[10];	/*其他数据项类型*/
typedef struct 
{	
	KeyType key;   			/*关键字域*/
	ElemType data; 			/*其他数据域*/
} LineList;					/*线性表元素类型*/
void ShellSort(LineList R[],int n)
{
	int i,j,gap;
	LineList tmp;
	gap=n/2;					/*增量置初值*/
	while (gap>0)
	{	
		for (i=gap;i<n;i++)  	/*对所有相隔gap位置的所有元素组进行排序*/
		{
			tmp=R[i];
			j=i-gap;
			while (j>=0 && tmp.key<R[j].key)/*对相隔gap位置的元素组进行排序*/
			{
				R[j+gap]=R[j];
				j=j-gap;					/*移到本组中的前一个元素*/
			}
			R[j+gap]=tmp;
			j=j-gap;
		}
		gap=gap/2;	/*减小增量*/
	}
}
void main()
{
	LineList R[MaxSize];
	KeyType a[]={75,87,68,92,88,61,77,96,80,72};
	int n=10,i;
	for (i=0;i<n;i++)
		R[i].key=a[i];
	printf("排序前:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
	ShellSort(R,n);
	printf("排序后:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
}

2. 选择排序:每步从待排序的记录中选出关键字最小的记录,顺序放在已经排序的记录序列的最后,直到全部排完为止

2.1 直接选择排序

基本思想:每一趟排序在n-i-1(i=1,2,...,n-1)个记录中选取关键字最小的记录,并和第i个记录进行比较。

#include <stdio.h>
#define MaxSize 100
typedef int KeyType;		/*关键字类型*/
typedef char ElemType[10];	/*其他数据项类型*/
typedef struct 
{	
	KeyType key;   			/*关键字域*/
	ElemType data; 			/*其他数据域*/
} LineList;					/*线性表元素类型*/
void SelectSort(LineList R[],int n)
{
	int i,j,k;
	LineList tmp;
	for (i=0;i<n-1;i++)
	{	
		k=i;
		for (j=i+1;j<n;j++)
			if (R[j].key<R[k].key) 
				k=j;		/*用k指出每趟在无序区段的最小元素*/
		tmp=R[i];			/*将R[k]与R[i]交换*/
		R[i]=R[k];
		R[k]=tmp;
	}
}
void main()
{
	LineList R[MaxSize];
	KeyType a[]={75,87,68,92,88,61,77,96,80,72};
	int n=10,i;
	for (i=0;i<n;i++)
		R[i].key=a[i];
	printf("排序前:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
	SelectSort(R,n);
	printf("排序后:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
}

2.2 堆排序

基本思想:堆是一个顺序存储的完全二叉树。首先,按堆得定义将R[i..n]调整为堆(这个过程叫做初始建堆),交换R[1]和R[n];然后,将R[1..n-1]调整为堆,交换R[1]和R[n-1];如此反复进行,直到交换了R[1]和R[2]为止。

#include <stdio.h>
#define MaxSize 100
typedef int KeyType;		/*关键字类型*/
typedef char ElemType[10];	/*其他数据项类型*/
typedef struct 
{	
	KeyType key;   			/*关键字域*/
	ElemType data; 			/*其他数据域*/
} LineList;					/*线性表元素类型*/
void Sift(LineList R[],int low,int high)
{
	int i=low,j=2*i;     		/*R[j]是R[i]的左孩子*/
	LineList tmp=R[i];
	while (j<=high) 
	{	if (j<high && R[j].key<R[j+1].key) 	/*若右孩子较大,把j指向右孩子*/
			j++;    				/*j变为2i+1,指向右孩子结点*/
		if (tmp.key<R[j].key) 
		{	R[i]=R[j];           /*将R[j]调整到双亲结点位置上*/
			i=j;                  /*修改i和j值,以便继续向下筛选*/
			j=2*i;
		}
		else break;              /*筛选结束*/
	}
	R[i]=tmp;                     /*被筛选结点的值放入最终位置*/
}
void HeapSort(LineList R[],int n)
{
	int i;
	LineList tmp;
	for (i=n/2;i>=1;i--)  	/*循环建立初始堆*/
		Sift(R,i,n); 
	for (i=n;i>=2;i--)   	/*进行n-1次循环,完成堆排序*/
	{  	tmp=R[1];        	/*将第一个元素同当前区间内R[1]对换*/
		R[1]=R[i];
		R[i]=tmp;
		Sift(R,1,i-1);     	/*筛选R[1]结点,得到i-1个结点的堆*/
	}
}
void main()
{
	LineList R[MaxSize];
	KeyType a[]={0,75,87,68,92,88,61,77,96,80,72};	/*有效数据从a[1]开始*/
	int n=10,i;
	for (i=0;i<=n;i++)
		R[i].key=a[i];
	printf("排序前:");
	for (i=1;i<=n;i++)
		printf("%3d",R[i].key);
	printf("\n");
	HeapSort(R,n);
	printf("排序后:");
	for (i=1;i<=n;i++)
		printf("%3d",R[i].key);
	printf("\n");
}

3. 交换排序:两两比较待排序记录的关键字,并交换不满足次序要求的那些偶对,知道全部满足为止
3.1 冒泡排序
基本思想:通过无序区中相邻记录关键字间的比较和位置交换,使关键字最小的记录如气泡一般逐渐往上漂浮直至水面。

#include <stdio.h>
#define MaxSize 100
typedef int KeyType;		/*关键字类型*/
typedef char ElemType[10];	/*其他数据项类型*/
typedef struct 
{	
	KeyType key;   			/*关键字域*/
	ElemType data; 			/*其他数据域*/
} LineList;					/*线性表元素类型*/
void BubbleSort(LineList R[],int n)
{
	int i,j,exchange;
	LineList tmp;
	for (i=0;i<n-1;i++) 
	{	exchange=0;
		for (j=n-1;j>i;j--)	/*比较,找出最小关键字的记录*/
			if (R[j].key<R[j-1].key)   	
			{	tmp=R[j];  /*R[j]与R[j-1]进行交换,将最小关键字记录前移*/
				R[j]=R[j-1];
				R[j-1]=tmp;
				exchange=1;
			}
		if (exchange==0) 	/*本趟未发生交换时结束算法*/
			return;
	}
}
void main()
{
	LineList R[MaxSize];
	KeyType a[]={75,87,68,92,88,61,77,96,80,72};
	int n=10,i;
	for (i=0;i<n;i++)
		R[i].key=a[i];
	printf("排序前:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
	BubbleSort(R,n);
	printf("排序后:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
}

3.2 快速排序
基本思想:在待排序的n个记录中任取一个记录(通常取第一个记录),把该记录放入最终的位置后,整个数据区间被此分割成两个子区间。所有关键字比该记录关键字小的放置在前子区间中,所有比它大的放置在后子区间中,并把该记录排在这两个子区间的中间,这个过程称作一趟快速排序。之后对所有的两个子区间分别重复上述过程,直至每个子区间内只有一个记录为止。简而言之,每趟排序使表中的第一个元素入终位,将数据区间一分为二,对于子区间按递归方式继续这种划分,直至划分的子区间长为1.

#include <stdio.h>
#define MaxSize 100
typedef int KeyType;		/*关键字类型*/
typedef char ElemType[10];	/*其他数据项类型*/
typedef struct 
{	
	KeyType key;   			/*关键字域*/
	ElemType data; 			/*其他数据域*/
} LineList;					/*线性表元素类型*/
void QuickSort(LineList R[],int s,int t) /*对R[s]至R[t]的元素进行快速排序*/
{
	int i=s,j=t;
	LineList tmp;
	if (s<t) 				/*区间内至少存在一个元素的情况*/
	{	tmp=R[s];     		/*用区间的第1个记录作为基准*/
		while (i!=j)  		/*从区间两端交替向中间扫描,直至i=j为止*/
		{	while (j>i && R[j].key>tmp.key) 
				j--;  		/*从右向左扫描,找第1个关键字小于tmp.key的R[j]*/ 
			R[i]=R[j];		/*找到这样的R[j],则R[i]和R[j]交换*/
			while (i<j && R[i].key<tmp.key) 
				i++;		/*从左向右扫描,找第1个关键字大于tmp.key的R[i]*/
			R[j]=R[i];		/*找到这样的R[i],则R[i]和R[j]交换*/
		}
		R[i]=tmp;
		QuickSort(R,s,i-1);	/*对左区间递归排序*/
		QuickSort(R,i+1,t);	/*对右区间递归排序*/
	}
}
void main()
{
	LineList R[MaxSize];
	KeyType a[]={75,87,68,92,88,61,77,96,80,72};
	int n=10,i;
	for (i=0;i<n;i++)
		R[i].key=a[i];
	printf("排序前:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
	QuickSort(R,0,n-1);
	printf("排序后:");
	for (i=0;i<n;i++)
		printf("%3d",R[i].key);
	printf("\n");
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值