排序(冒泡,快速排序)c语言

目录

                1)冒泡排序

                                算法思想

                                代码

                                代码优化

                2)快速排序

                                算法思想

                                代码

                                代码讲解


1)冒泡排序

        算法思想:

将一组数字从小到大排序,依次进行两两比较换位一轮两两比较完之后,确定一位数字的位置,依次比较排列下去,直到将所有数字的位置确定好。

例如:一组数据:2,4,1,6,8,9,0,6,8

第一轮比较:第一次2和4进行比较,2<4,不做置换;第二次4和1进行比较,4>1,进行互换位置;第三次便是4和6进行比较,4<6,不做置换;依次比较下去,进行n-1次(n为这组数据的数字个数),第一轮比较完成后,确定了最大的数字9的位置。

第一轮比较完成后的序列为:2,1,4,6,8,0,6,8,9;

第二轮比较仍是上面的方式,完成后确定了倒数第二位数字8

第二轮比较完之后的序列为:1,2,4,6,0,6,8,8,9

如此进行n轮比较下去,便确定了n位数字的位置,排序便完成了;

        代码实现:

void swap(int *arr, int a, int b)//数组内两数字的互换
{
	int vlan;
	vlan = arr[a];
	arr[a] = arr[b];
	arr[b] = vlan;
}
void px(int *arr, int len)
{
	for (int j = 0; j <len; j++)//j为比较的轮次
	{
 
		for (int i = 0; i <len-1 ; i++)//第一轮对数组进行遍历,通过遍历进行两两比较
		{
			if (arr[i]>arr[i + 1])
			{
				swap(arr, i, i + 1);
				
			}
		
		}
		
		
	}
	
}
int main()
{
	int arr[] = { 1, 4, 2, 4, 7, 3, 0 };
	int len = sizeof(arr) / sizeof(arr[0]);
	px(arr, len);//len表示数组长度
	for (int k = 0; k < len; k++)
	{
		printf("%3d", arr[k]);
	}
}

                 代码优化:

                        思想优化:在上面的那一组数据中,我们发现进行几次比较之后,这一组数据已经按从小到大排序好了,但还是按照原先的算法执行了,这无疑是增大了算法的复杂度,因此对算法进行优化,优化思想为做一个标记,定义一个变量c=0,如果进入了每轮排序的比较c=1每轮比较完成后c重置为0,若哪轮的排序完c仍未0,则这组数已经排序完成,退出整个大循环。

                         代码优化:

void swap(int *arr, int a, int b)
{
	int vlan;
	vlan = arr[a];
	arr[a] = arr[b];
	arr[b] = vlan;
}
void px(int *arr, int len)
{
	int c = 0;//标记c
	for (int j = 0; j <len; j++)
	{
 
		for (int i = 0; i <len-1 ; i++)
		{
			if (arr[i]>arr[i + 1])
			{
				swap(arr, i, i + 1);
				c = 1;//如果该轮比较进行了交换,则标记改变
			}
		if (c == 0) break;//c仍为0,表示没有进行交换,即数组排序完成,退出循环
          c=0;//标记进行初始化
		}
		
		
	}
	
}
int main()
{
	int arr[] = { 1, 4, 2, 4, 7, 3, 0 };
	int len = sizeof(arr) / sizeof(arr[0]);
	px(arr, len);
	for (int k = 0; k < len; k++)
	{
		printf("%3d", arr[k]);
	}
}

2)快速排序

        算法思路:

先选择一个基准值,第一轮比较过去将比基准值大的放到右边,比基准值小的放到左边,接着将两边均选择一个基准值进行比较,多次排序即可(此处递归思想会多处用到)。

举例如下:选一组数据在此处进行举例 3,5,7,3,2,8,0,2,9;这一组数据中先以3为基准值,进行从后往前遍历,找到一个比3小的数字,然后将该数字放到3的位置上,也就是数组首位置。 放过去之后2的位置便空出来了,便开始从前往后找一个大于标记值的数字,也就是5,此时将5放在上面2空下来的位置,然后又空下来一个位置,从后往前遍历,找值进行替换,第一轮换位后得到的顺序是2,0,2,3,3,8,7,5,9然后分成两组进行排序,即2,0,2,3和8,7,5,9这两组,均取第一个为基准值,进行换位排序,第二轮排完顺序后为0,2,2,3,3,5,,7,8,9为最终结果。

        代码:

void quick_sort(int* arr, int left, int right){
	int x = arr[left];
	int i = left, j = right;
	while (i < j){
		while (i<j&&x<=arr[j])
			j--;
	        arr[i] = arr[j];
		while (i<j&&x>=arr[i])
			i++;
	        arr[j] = arr[i];
 
	}
	arr[i] = x;
	if (i-1>left)
	quick_sort(arr, left, i - 1);
	if (i + 1 < right)
	quick_sort(arr, i + 1, right);
 
}
int main(){
	int arr[] = { 3,5,7,3,2,8,0,2,9 };
	int len = sizeof(arr) / sizeof(arr[0]);
	quick_sort(arr, 0, len-1);
	for (int i = 0; i < len;i++)
	printf("%4d", arr[i]);
}

        代码讲解:

void quick_sort(int* arr, int left, int right){
	int x = arr[left];//基准值
	int i = left, j = right;//定义起始位置和终止位置
	while (i < j){
		while (i<j&&x<=arr[j])//i<j为循环终止条件,此处如果arr[j]的值大于基准值则继续遍历
			j--;
	        arr[i] = arr[j];//此处因为上面找到了小于基准值的数进入不了循环,所以此处进行换位赋值
		while (i<j&&x>=arr[i])//arr[i]小于基准值,进入循环,
			i++;
	        arr[j] = arr[i];//上面循环结束找到比基准值大的数,进行换位
 
	}
	arr[i] = x;
	if (i-1>left)//最终确定基准值的位置如果大于左边界,进行继续迭代
	quick_sort(arr, left, i - 1);
	if (i + 1 < right)//确定基准值小于右边界,进行迭代
	quick_sort(arr, i + 1, right);
 
}
int main(){
	int arr[] = { 3,5,7,3,2,8,0,2,9 };//初始化数组
	int len = sizeof(arr) / sizeof(arr[0]);//求数组长度
	quick_sort(arr, 0, len-1);
	for (int i = 0; i < len;i++)//验证是否排序成功
	printf("%4d", arr[i]);
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

*闲鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值