数据结构-排序

说明

    此代码文件包含排序类型:冒泡、选择、插入、shell、快速。

代码

/*
**	sort create by yubo.wang 2018.9.13
**	此文件包含排序类型:冒泡、选择、插入、shell、快速。
*/

#include <stdio.h>
#include <string.h>

/*	冒泡排序
*	通过无序区中相邻记录关键字间的比较和位置交换,使最小的关键字记录如气泡一样逐渐漂浮至水面
*	时间复杂度O(n²)
*	稳定
*/
/*
**	第1种:每一轮从前面往最后比较相邻把最大的往后面推
*/
int sort_bubble_1(int string[],int len)
{
	int i;
	int j;
	int tmp;
	for(i=1; i<len; i++)//i记录找到最大元素个数,最小的元素没有被记录是因为最后被交换到最前
	{
		for(j=0; j<len-i; j++)//从前面往最后比较相邻把最大的往后面推
		{
			if(string[j]>string[j+1])
			{
				tmp = string[j];
				string[j] = string[j+1];
				string[j+1] = tmp;
			}
		}
	}
	return 0;
}
/*
**	第2种:每一轮从从最后往前面比较相邻把最小的往前面推,并记录交换标志
*/
int sort_bubble_2(int string[],int len)
{
	int i,j,exchange;
	int tmp;
	for(i=0; i<len-1; i++)
	{
		exchange=0;
		for(j=len-1; j>i; j--)//从最后往前面比较相邻把最小的往前面推
		{
			if(string[j] < string[j-1])//后面的比前面元素小,就交换
			{
				tmp = string[j];
				string[j] = string[j-1];
				string[j-1] = tmp;
				exchange=1;
			}
		}
		if(0 == exchange)//本趟没有发生交换,说明已经有序所以退出
		{
			return 0;
		}	
	}
	return 0;
}

/*	选择排序
*	每步从待排序的记录中选出最小的记录,顺序放在已排序的记录序列的最前,直到全部排序完成。
*	时间复杂度O(n²)
*	不稳定,元素位置改变
*/
/*
**	第1种:每一轮找到比前面小的元素只进行记录不进行交换,找完后再进行交换。找到最小的放在第一位
*/
int sort_select_1(int string[],int len)
{
	int i;
	int j;
	int min;
	int temp;
	for(i = 0; i < len-1; i++)
	{
		min = i;//记录当前比较基准编号
		for(j=i+1; j<len; j++)//后面与这个min编号的比较
		{
			if(string[j]<string[min])
			{
				min=j;//用min指出每趟在无序区段的最小元素
			}
		}
		temp = string[i];//这一趟找到了最小的元素与基准编号交换
		string[i] = string[min];
		string[min] = temp;
	}
	return 0;
}
/*
**	第2种:每一轮中每一次找到比前面小的元素就进行交换。把最大的一直推到最后
*/
int sort_select_2(int string[],int len)
{
	int i;
	int j;
	int min;
	int temp;
	for(i=0; i<len-1; i++)
	{
		min = i;
		for(j=i+1; j<len; j++)
		{
			if(string[j]<string[min])
			{
				temp = string[i];
				string[i] = string[j];
				string[j] = temp;
			}
		}
	}
	return 0;
}

/*
*	直接插入排序
*	将前面排好序,后面的从后面以此比较插入到前面有序的数组里面,像打扑克牌齐牌时一样拿出一张往前插入有序的数组中
*	时间复杂度O(n²)
*	稳定,元素位置不变
*/
/*
**	第1种:从前面往后,记录后面要插入的元素,找到准确的位置再插入
*/
int sort_insert_1(int string[],int len)
{
	int i;
	int j;
	int temp;
	for(i=1; i<len; i++)
	{
		temp = string[i];//先记录要往前面插入的元素,因为后面会覆盖掉
		j=i-1;
		while(j>=0 && string[j]>temp)//把大与temp元素的进行后移一位覆盖掉temp元素,以便腾出一个位置插入temp
		{
			string[j+1]=string[j];
			j--;
		}
		string[j+1]=temp;//说明temp找到了准确的位置并开始插入
	}
	return 0;
}
/*
**	第2种:从前面往后,一直往前比较相邻,前面的大于后面就交换
*/
int sort_insert_2(int string[],int len)
{
	int i;
	int j;
	int temp;
	for(i=1; i<len; i++)
	{
		temp = string[i];//先记录要往前面插入的元素,因为后面会覆盖掉
		for(j=i-1; j>=0 && string[j]>temp; j--)//一直往前比较相邻,前面的大于后面就交换,
		{
			string[j+1] = string[j];
			string[j] = temp;
		}
	}
	return 0;
}

/*
*	shell排序
*	把记录按下标的一定增量d分组,对每组记录采用直接插入排序方法进行排序,随着增量逐渐减小,所分成的组包含的记录越来越多,
*	到增量减小到为1时,整个数据合成一组,构成一组有序记录。
*	时间复杂度O(nlog₂n)
*	
*/
int sort_shell_1(int string[],int n)
{
	int gap;
	int i;
	int j;
	int temp;
	for(gap = n/2; gap > 0; gap /=2)
	{
		for(i = gap; i < n; i++)
		{
			for(j = i-gap; (j>=0)&&(string[j]>string[j+gap]); j-=gap)
			{
				temp = string[j];
				string[j] = string[j+gap];
				string[j+gap] = temp;
			}
		}
	}
	return 0;
}

int sort_shell_2(int string[],int n)
{
	int gap;
	int i;
	int j;
	int temp;
	gap = n/2;//增量置初值
	while(gap > 0)
	{
		for(i = gap; i < n; i++)//对所有相隔gap位置的元素组进行排序
		{
			temp = string[i];
			j = i-gap;
			while(j>=0 && temp<string[j])//对相隔gap位置的元素组进行排序
			{
				string[j+gap] = string[j];
				j=j-gap;//移到本组的前一个元素
			}
			string[j+gap] = temp;
			j=j-gap;
		}
		gap /=2;//减小增量
	}
	return 0;
}

/*	快速排序
*	由冒泡排序改进而来,在待排序的n个记录中任取一个记录(通常取第一个记录),把该记录放入最终位置后,
	整个数据区间被此记录分割成两个子区间,比该记录小的放在前子区间,比它大的放在后子区间,并把该记录
	排在这两个子区间的中间,这个过程称作一趟快速排序。
*	时间复杂度
*	稳定?
*/
void sort_quick(int string[],int s,int len)
{
	int i=s,j=len;
	int tmp;
	if(s<len)//区间内至少存在一个元素的情况
	{
		tmp=string[s];//用区间的第1个记录作为基准
		while(i!=j)//从区间两端交替向中间扫描,直到i=j为止
		{
			while(j>i && string[j]>tmp)
				j--;//从右向左扫描,找到第一个关键字小于tmp的string[j]
			string[i]=string[j];//找到这样的string[j],则与string[i]交换

			while(i<j && string[i]<tmp)
				i++;//从左向右扫描,找到第一个关键字大于tmp的string[i]
			string[j]=string[i];//找到这样的string[i],则与string[j]交换
		}
		string[i]=tmp;
		sort_quick(string, s, i-1);//对左区间递归排序
		sort_quick(string, i+1, len);//对右区间递归排序
	}
}


int main(void)
{
	int i = 0;
	int string[] = {4,3,2,1};
	int len = sizeof(string)/sizeof(int);
	printf("len=%d\n",len);

	sort_quick(string, 0, len);
	
	for(i=0; i<len; i++)
	{
		printf("%d ", string[i]);
	}
	printf("\n");

	return 0;
}

/*	归并排序
*
*
*
*/

/*	基数排序
*
*
*
*/
/*	堆排序
*
*
*
*/

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值