【记录学习】C语言数据结构实现一些常见排序

本篇代码包括:直接插入排序、折半插入排序、希尔插入排序、冒泡排序、快速排序、简单选择排序、2路归并排序

实现代码如下:
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>

//内部排序
/*本篇代码包括:直接插入排序、折半插入排序、希尔插入排序、冒泡排序、快速排序、简单选择排序、2路归并排序*/

//定义结构体数组
typedef struct Array
{
	int length;
	int * pBase;
}Array, * PArr;

//初始化数组
PArr init_Array(PArr pArr);

/*
直接插入排序:
空间复杂度:O(1);时间复杂度:最好O(n),平均O(n2),最坏O(n2);稳定性:稳定
适用于顺序存储和链式存储
*/
void InsertSort(PArr pArr);

/*
折半插入排序:
空间复杂度:O(1);时间复杂度:最好O(n),平均O(n2),最坏O(n2);稳定性:稳定
适用于顺序存储
*/
void bin_InsertSort(PArr pArr);

/*
希尔插入排序:
空间复杂度:O(1);时间复杂度:一般O(n1.3),最坏O(n2);稳定性:不稳定
适用于顺序存储
*/
void Shell_InsertSort(PArr pArr);

/*
冒泡排序:
空间复杂度:O(1);时间复杂度:最好O(n),平均O(n2),最坏O(n2);稳定性:稳定
适用于顺序存储和链式存储
*/
void bubbleSort(PArr pArr);

/*
快速排序:
空间复杂度:O(log2n);时间复杂度:最好O(nlog2n),平均O(nlog2n),最坏O(n2);稳定性:不稳定
适用于顺序存储(链式存储)
*/
void quickSort(PArr pArr,int low,int high);
//辅助快速排序的Partition函数
int Partition(PArr pArr,int low,int high);


/*
简单选择排序:
空间复杂度:O(1);时间复杂度:最好O(n2),平均O(n2),最坏O(n2);稳定性:不稳定
适用于顺序存储和链式存储
*/
void SelectSort(PArr pArr);

/*
2路归并排序:
空间复杂度:O(n);时间复杂度:最好O(nlog2n),平均O(nlog2n),最坏O(nlog2n);稳定性:稳定
适用于顺序存储和链式存储
*/
void MergeSort(PArr pArr,int low,int high);
//2路归并排序辅助函数Merge
void Merge(PArr pArr,int low,int mid,int high);
//2路归并辅助数组
int ArrayLength = 100;
int * B = (int *)malloc(sizeof(int) * ArrayLength);



int main(void)
{
	int i;
	Array arr;
	PArr pArr = init_Array(&arr);

	//验证数组是否初始化成功
	printf("数组元素分别为:");
	for(i=0; i<=pArr->length; i++)
		printf("%d  ", pArr->pBase[i]);
	printf("\n注:数组下标为0(数组第一位)的一位元素为哨兵,不在排序范围内,作为辅助排序使用。\n");
	
	//直接插入排序
	InsertSort(pArr);
	printf("直接插入排序后元素分别为:");
	for(i=0; i<=pArr->length; i++)
		printf("%d  ", pArr->pBase[i]);
	printf("\n");

	//折半插入排序
	bin_InsertSort(pArr);
	printf("折半插入排序后元素分别为:");
	for(i=0; i<=pArr->length; i++)
		printf("%d  ", pArr->pBase[i]);
	printf("\n");

	//希尔(Shell)插入排序
	Shell_InsertSort(pArr);
	printf("希尔插入排序后元素分别为:");
	for(i=0; i<=pArr->length; i++)
		printf("%d  ", pArr->pBase[i]);
	printf("\n");

	//冒泡排序
	bubbleSort(pArr);
	printf("冒泡排序后元素分别为:");
	for(i=0; i<=pArr->length; i++)
		printf("%d  ", pArr->pBase[i]);
	printf("\n");

	//快速排序
	quickSort(pArr,1,pArr->length);
	printf("快速排序后元素分别为:");
	for(i=0; i<=pArr->length; i++)
		printf("%d  ", pArr->pBase[i]);
	printf("\n");

	//简单选择排序
	SelectSort(pArr);
	printf("简单选择排序后元素分别为:");
	for(i=0; i<=pArr->length; i++)
		printf("%d  ", pArr->pBase[i]);
	printf("\n");

	/**/
	//2路归并排序
	MergeSort(pArr,1,pArr->length);
	printf("2路归并排序后元素分别为:");
	for(i=0; i<=pArr->length; i++)
		printf("%d  ", pArr->pBase[i]);
	printf("\n");
	


	return 0;
}

//初始化数组
//数组第一位作为哨兵帮助排序
PArr init_Array(PArr pArr)
{
	int n;
	printf("请输入创建数组的长度:");
	scanf("%d",&pArr->length);
	pArr->pBase = (int *)malloc(sizeof(int) * (pArr->length+1));
	if(NULL == pArr->pBase)
	{
		printf("动态内存分配失败!\n");
		exit(-1);
	}
	for(int i = 1; i<=pArr->length; i++)
	{
		printf("请输入第%d位元素的数据:",i);
		scanf("%d",&n);
		pArr->pBase[i] = n;
	}
	return pArr;
}

//直接插入排序
void InsertSort(PArr pArr)
{
	int i,j;
	for(i=2; i<=pArr->length; i++)
	{
		pArr->pBase[0] = pArr->pBase[i];
		for(j=i-1; pArr->pBase[0]<pArr->pBase[j]; j--)
			pArr->pBase[j+1] = pArr->pBase[j];
		pArr->pBase[j+1] = pArr->pBase[0];
	}
}

//折半插入排序
void bin_InsertSort(PArr pArr)
{
	int i, j;
	int low, high, mid;
	for(i=2; i<=pArr->length; i++)
	{
		pArr->pBase[0] = pArr->pBase[i];
		
		//折半查找
		low=1; high=i-1;
		while(low<=high)
		{
			mid = (low+high) / 2;
			if(pArr->pBase[0] < pArr->pBase[mid])
				high = mid - 1;
			else
				low = mid + 1;
		}

		for(j=i-1; j>=high+1; j--)
			pArr->pBase[j+1] = pArr->pBase[j];
		pArr->pBase[high+1] = pArr->pBase[0];
	}	
}

//希尔排序
void Shell_InsertSort(PArr pArr)
{
	for(int dk=pArr->length/2; dk>=1; dk=dk/2)
	{
		for(int i=dk+1; i<=pArr->length; i++)
		{
			if(pArr->pBase[i] < pArr->pBase[i-dk])
			{
				pArr->pBase[0] = pArr->pBase[i];
				for(int j=i-dk; j>0 && pArr->pBase[0]<pArr->pBase[j]; j--)
					pArr->pBase[j+dk] = pArr->pBase[j];
				pArr->pBase[j+dk] = pArr->pBase[0];
			}
		}
	}
}

//冒泡排序
void bubbleSort(PArr pArr)
{
	for(int i=0; i<pArr->length; i++)
	{
		bool flag = true;
		for(int j=pArr->length; j>i; j--)
		{
			if(pArr->pBase[j] < pArr->pBase[j-1])
			{
				pArr->pBase[0] = pArr->pBase[j];
				pArr->pBase[j] = pArr->pBase[j-1];
				pArr->pBase[j-1] = pArr->pBase[0];
				flag = false;
			}
		}
		if(flag)
			return;
	}
}

//辅助快速排序的Partition函数
int Partition(PArr pArr,int low,int high)
{
	//将哨兵位当做pivot
	pArr->pBase[0] = pArr->pBase[low];
	while(low < high)
	{
		while(low<high && pArr->pBase[high]>=pArr->pBase[0])
			high--;
		pArr->pBase[low] = pArr->pBase[high];
		while(low<high && pArr->pBase[low]<=pArr->pBase[0])
			low++;
		pArr->pBase[high] = pArr->pBase[low];
	}
	pArr->pBase[low] = pArr->pBase[0];
	return low;
}

//快速排序
void quickSort(PArr pArr,int low,int high)
{
	if(low < high)
	{
		int pivotpos = Partition(pArr,low,high);
		quickSort(pArr,low,pivotpos-1);
		quickSort(pArr,pivotpos+1,high);
	}
}

//简单选择排序
void SelectSort(PArr pArr)
{	
	int temp;
	for(int i=1; i<=pArr->length; i++)
	{
		pArr->pBase[0] = pArr->pBase[i];
		for(int j=i+1; j<=pArr->length; j++)
			if(pArr->pBase[j] < pArr->pBase[0])
				pArr->pBase[0] = pArr->pBase[j];
		if(pArr->pBase[0] != pArr->pBase[i])
		{
			temp = pArr->pBase[0];
			pArr->pBase[0] = pArr->pBase[i];
			pArr->pBase[i] = temp;
		}
	}
}


//2路归并排序辅助函数Merge
void Merge(PArr pArr,int low,int mid,int high)
{
	int i, j, k;
	for(k=low; k<=high; k++)
		B[k] = pArr->pBase[k];
	for(i=low,j=mid+1,k=i; i<=mid && j<=high; k++)
	{
		if(B[i] <= B[j])
			pArr->pBase[k] = B[i++];
		else
			pArr->pBase[k] = B[j++];
	}
	while(i<=mid)
		pArr->pBase[k++] = B[i++];
	while(j<=high)
		pArr->pBase[k++] = B[j++];

}

//2路归并排序
void MergeSort(PArr pArr,int low,int high)
{
	if(low<high)
	{
		int mid = (low+high) / 2;
		MergeSort(pArr,low,mid);
		MergeSort(pArr,mid+1,high);
		Merge(pArr,low,mid,high);
	}
}

(tips:如有发现错误和问题欢迎提醒和指正,Thanks♪(・ω・)ノ~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值