数据结构--排序

1.直接插入排序:

#include <stdio.h>
#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0; 
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

//----以下运算针对堆排序的程序
void CreateList1(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 1; i <= n; i++)			//R[1..n]存放排序记录
		R[i].key = keys[i - 1];
}

void DispList1(RecType R[], int n)	//输出顺序表
{
	for (i = 1; i <= n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

void InsertSort(RecType R[], int n) //对R[0..n-1]按递增有序进行直接插入排序
{
	int i, j; RecType tmp;
	for (i = 1; i < n; i++)
	{
		if (R[i].key < R[i - 1].key)	//反序时 
		{
			tmp = R[i];
			j = i - 1;

			do					//找R[i]的插入位置 
			{
				R[j + 1] = R[j];   	//将关键字大于R[i].key的记录后移
				j--;
			} while (j >= 0 && R[j].key > tmp.key);

			R[j + 1] = tmp;      		//在j+1处插入R[i]
		}
		printf("  i=%d: ", i); DispList(R, n);
	}
}

int main()
{
	int n = 10;
	RecType R[MAXL];
	KeyType a[] = { 9,8,7,6,5,4,3,2,1,0 };

	CreateList(R, a, n);

	printf("排序前:"); 
	DispList(R, n);

	InsertSort(R, n);
	printf("排序后:"); 
	DispList(R, n);

	return 0;
}

2.折半插入排序:

#include <stdio.h>
#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0;
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

void BinInsertSort(RecType R[], int n)
{
	int i, j, low, high, mid;
	RecType tmp;
	for (i = 1; i < n; i++)
	{
		if (R[i].key < R[i - 1].key)		//反序时 
		{
			tmp = R[i];		  			//将R[i]保存到tmp中
			low = 0;  high = i - 1;
			while (low <= high)	  		//在R[low..high]中查找插入的位置
			{
				mid = (low + high) / 2;		//取中间位置
				if (tmp.key < R[mid].key)
					high = mid - 1;			//插入点在左半区
				else
					low = mid + 1;			//插入点在右半区
			}                          	//找位置high
			for (j = i - 1; j >= high + 1; j--)	//集中进行元素后移
				R[j + 1] = R[j];
			R[high + 1] = tmp;				//插入tmp 
		}
		printf("  i=%d: ", i);
		DispList(R, n);
	}
}

int main()
{
	int n = 10;
	RecType R[MAXL];
	KeyType a[] = { 9,8,7,6,5,4,3,2,1,0 };
	
	CreateList(R, a, n);
	
	printf("排序前:"); 
	DispList(R, n);
	
	BinInsertSort(R, n);
	printf("排序后:"); 
	DispList(R, n);
	
	return 0;
}

3.希尔排序:

#include <stdio.h>
#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0;
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

void ShellSort(RecType R[], int n) //希尔排序算法
{
	int i, j, d;
	RecType tmp;
	d = n / 2;					//增量置初值
	while (d > 0)
	{
		for (i = d; i < n; i++) 	//对所有组采用直接插入排序
		{
			tmp = R[i];		//对相隔d个位置一组采用直接插入排序
			j = i - d;
			while (j >= 0 && tmp.key < R[j].key)
			{
				R[j + d] = R[j];
				j = j - d;
			}
			R[j + d] = tmp;
		}
		printf("  d=%d: ", d); DispList(R, n);
		d = d / 2;				//减小增量
	}
}

int main()
{
	int n = 10;
	RecType R[MAXL];
	KeyType a[] = { 9,8,7,6,5,4,3,2,1,0 };
	
	CreateList(R, a, n);
	
	printf("排序前:"); 
	DispList(R, n);
	
	ShellSort(R, n);
	printf("排序后:"); 
	DispList(R, n);

	return 0;
}

4.冒泡排序:

#include <stdio.h>
#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0;
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

void BubbleSort(RecType R[], int n)
{
	int i, j, k;
	RecType tmp;
	for (i = 0; i < n - 1; i++)
	{
		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;
			}
		printf("  i=%d: ", i);
		DispList(R, n);
	}
}

int main()
{
	int n = 10;
	RecType R[MAXL];
	KeyType a[] = { 9,8,7,6,5,4,3,2,1,0 };
	
	CreateList(R, a, n);
	
	printf("排序前:"); 
	DispList(R, n);
	
	BubbleSort(R, n);
	printf("排序后:"); 
	DispList(R, n);
	
	return 0;
}

5.改进后的冒泡排序:

#include <stdio.h>
#include <stdbool.h>

#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0;
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

void BubbleSort1(RecType R[], int n)
{
	int i, j;
	bool exchange;
	RecType tmp;
	for (i = 0; i < n - 1; i++)
	{
		exchange = false;					//一趟前exchange置为假
		for (j = n - 1; j > i; j--)				//归位R[i],循环n-i-1次
			if (R[j].key < R[j - 1].key)	//相邻两个元素反序时
			{
				tmp = R[j];				//将这两个元素交换
				R[j] = R[j - 1];
				R[j - 1] = tmp;
				exchange = true;			//一旦有交换,exchange置为真
			}
		printf("  i=%d: ", i);
		DispList(R, n);
		if (!exchange)					//本趟没有发生交换,中途结束算法
			return;
	}
}

int main()
{
	int n = 10;
	RecType R[MAXL];
	KeyType a[] = { 0,1,7,2,5,4,3,6,8,9 };
	
	CreateList(R, a, n);
	
	printf("排序前:"); 
	DispList(R, n);
	
	BubbleSort1(R, n);
	printf("排序后:"); 
	DispList(R, n);
	
	return 0;
}

6.快速排序:

#include <stdio.h>
#include <stdbool.h>

#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0;
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

int count = 0;
int partition(RecType R[], int s, int t)	//一趟划分
{
	int i = s, j = t;
	RecType tmp = R[i];			//以R[i]为基准
	while (i < j)  				//从两端交替向中间扫描,直至i=j为止
	{
		while (j > i && R[j].key >= tmp.key)
			j--;				//从右向左扫描,找一个小于tmp.key的R[j]
		R[i] = R[j];				//找到这样的R[j],放入R[i]处
		while (i < j && R[i].key <= tmp.key)
			i++;				//从左向右扫描,找一个大于tmp.key的R[i]
		R[j] = R[i];				//找到这样的R[i],放入R[j]处
	}
	R[i] = tmp;
	return i;
}

void QuickSort(RecType R[], int s, int t) //对R[s..t]的元素进行快速排序
{
	int i;
	RecType tmp;
	if (s < t) 					//区间内至少存在两个元素的情况
	{
		count++;
		i = partition(R, s, t);
		DispList(R, 10);			//调试用
		QuickSort(R, s, i - 1);		//对左区间递归排序
		QuickSort(R, i + 1, t);		//对右区间递归排序
	}
}

int main()
{
	int i, n = 10;
	RecType R[MAXL];
	KeyType a[] = { 6,8,7,9,0,1,3,2,4,5 };
	
	CreateList(R, a, n);
	
	printf("排序前:"); 
	DispList(R, n);
	
	QuickSort(R, 0, n - 1);
	printf("排序后:"); 
	DispList(R, n);
	printf("count=%d\n", count);
	
	return 0;
}

7.简单选择排序:

#include <stdio.h>
#include <stdbool.h>

#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0;
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

int partition(RecType R[], int s, int t)	//一趟划分
{
	int i = s, j = t;
	RecType tmp = R[i];			//以R[i]为基准
	while (i < j)  				//从两端交替向中间扫描,直至i=j为止
	{
		while (j > i && R[j].key >= tmp.key)
			j--;				//从右向左扫描,找一个小于tmp.key的R[j]
		R[i] = R[j];				//找到这样的R[j],放入R[i]处
		while (i < j && R[i].key <= tmp.key)
			i++;				//从左向右扫描,找一个大于tmp.key的R[i]
		R[j] = R[i];				//找到这样的R[i],放入R[j]处
	}
	R[i] = tmp;
	return i;
}

void SelectSort(RecType R[], int n)
{
	int i, j, k;
	RecType temp;
	for (i = 0; i < n - 1; i++)    	 	//做第i趟排序
	{
		k = i;
		for (j = i + 1; j < n; j++)  	//在当前无序区R[i..n-1]中选key最小的R[k]
			if (R[j].key < R[k].key)
				k = j;           	//k记下目前找到的最小关键字所在的位置
		if (k != i)          		//交换R[i]和R[k]
		{
			temp = R[i];
			R[i] = R[k];
			R[k] = temp;
		}
		printf("  i=%d: ", i); DispList(R, n);
	}
}

int main()
{
	int n = 10;
	RecType R[MAXL];
	KeyType a[] = { 9,8,7,6,5,4,3,2,1,0 };
	
	CreateList(R, a, n);
	
	printf("排序前:"); 
	DispList(R, n);
	
	SelectSort(R, n);
	printf("排序后:"); 
	DispList(R, n);
	
	return 0;
}

8.二路归并,自顶向上:

#include <stdio.h>
#include <stdlib.h>
#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0;
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

void Merge(RecType R[], int low, int mid, int high)
{
	RecType* R1;
	int i = low, j = mid + 1, k = 0; //k是R1的下标,i、j分别为第1、2段的下标
	R1 = (RecType*)malloc((high - low + 1) * sizeof(RecType));  //动态分配空间
	while (i <= mid && j <= high)     	//在第1段和第2段均未扫描完时循环
		if (R[i].key <= R[j].key)    	//将第1段中的记录放入R1中
		{
			R1[k] = R[i];
			i++; k++;
		}
		else                       		//将第2段中的记录放入R1中
		{
			R1[k] = R[j];
			j++; k++;
		}
	while (i <= mid)          	       	//将第1段余下部分复制到R1
	{
		R1[k] = R[i];
		i++; k++;
	}
	while (j <= high)                	//将第2段余下部分复制到R1
	{
		R1[k] = R[j];
		j++; k++;
	}
	for (k = 0, i = low; i <= high; k++, i++) //将R1复制回R中
		R[i] = R1[k];
}

void MergePass(RecType R[], int length, int n)	//对整个数序进行一趟归并
{
	int i;
	for (i = 0; i + 2 * length - 1 < n; i = i + 2 * length) 	//归并length长的两相邻子表
		Merge(R, i, i + length - 1, i + 2 * length - 1);
	if (i + length - 1 < n - 1)                		//余下两个子表,后者长度小于length
		Merge(R, i, i + length - 1, n - 1);  		//归并这两个子表
	printf("length=%d: ", length);
	DispList(R, n);
}

void MergeSort(RecType R[], int n)			//自底向上的二路归并算法
{
	int length;
	for (length = 1; length < n; length = 2 * length)//进行log2n趟归并
		MergePass(R, length, n);
}

int main()
{
	int n = 10;
	RecType R[MAXL];
	KeyType a[] = { 9,8,7,6,5,4,3,2,1,0 };
	CreateList(R, a, n);
	printf("   排序前:"); DispList(R, n);
	MergeSort(R, n);
	printf("   排序后:"); DispList(R, n);
	return 0;
}

9.二路归并,自顶向下(递归):

#include <stdio.h>
#include <stdlib.h>
#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{
	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void swap(RecType x, RecType y)	//x和y交换
{
	RecType tmp = x;
	x = y; y = tmp;
}

int i = 0;
void CreateList(RecType R[], KeyType keys[], int n)	//创建顺序表
{
	for (i = 0; i < n; i++)			//R[0..n-1]存放排序记录
		R[i].key = keys[i];
}

void DispList(RecType R[], int n)	//输出顺序表
{
	for (i = 0; i < n; i++)
		printf("%d ", R[i].key);
	printf("\n");
}

void Merge(RecType R[], int low, int mid, int high)
{
	RecType* R1;
	int i = low, j = mid + 1, k = 0; //k是R1的下标,i、j分别为第1、2段的下标
	R1 = (RecType*)malloc((high - low + 1) * sizeof(RecType));  //动态分配空间
	while (i <= mid && j <= high)     	//在第1段和第2段均未扫描完时循环
		if (R[i].key <= R[j].key)    	//将第1段中的记录放入R1中
		{
			R1[k] = R[i];
			i++; k++;
		}
		else                       		//将第2段中的记录放入R1中
		{
			R1[k] = R[j];
			j++; k++;
		}
	while (i <= mid)          	       	//将第1段余下部分复制到R1
	{
		R1[k] = R[i];
		i++; k++;
	}
	while (j <= high)                	//将第2段余下部分复制到R1
	{
		R1[k] = R[j];
		j++; k++;
	}
	for (k = 0, i = low; i <= high; k++, i++) //将R1复制回R中
		R[i] = R1[k];
}

void MergeSortDC(RecType R[], int low, int high)
//对R[low..high]进行二路归并排序
{
	int mid;
	if (low < high)
	{
		mid = (low + high) / 2;
		MergeSortDC(R, low, mid);
		MergeSortDC(R, mid + 1, high);
		Merge(R, low, mid, high);
	}
}

void MergeSort1(RecType R[], int n)	//自顶向下的二路归并算法
{
	MergeSortDC(R, 0, n - 1);
}

int main()
{
	int n = 10;
	RecType R[MAXL];
	KeyType a[] = { 9,8,7,6,5,4,3,2,1,0 };
	CreateList(R, a, n);
	printf("   排序前:"); DispList(R, n);
	MergeSort1(R, n);
	printf("   排序后:"); DispList(R, n);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值