算法基础学习笔记——①排序

博主:命运之光
专栏:算法基础学习

在这里插入图片描述


前言:算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持!

✨快速排序——分治

image.png

因为x参与交换之后仍然会被留在左右区间中的一个里。

1.确定分界点:(这里的分界点不一定是x,可以随意取值,常用取值方法如下)
q[l],q[(l+r)/2],q[r],随机//这里随机数的表示:q[rand() % (r - l) + l]
2.调整区间:
image.png
3.递归处理左右两段(<=x和>=x这两段)
image.png
如何实现2:
方法1.
image.png
方法2.
image.png
将两个指针i,j从两头挪向分界点,直到有一个i>=x,此时这个i
需要放到右半边,一个j<x,此时这个j需要放到左半边,此时交
换i.j(swap),故此时i<=x,j>x,直到i,j相遇就可以把整个区间
一分为二
image.png
j的后面(不包括j)>=3,i的前面(不包括i)<=3(注意边界)
🍓代码实现
image.png
image.png
🍓快速排序模板:

void quick_sort(int q[], int l, int r)//简单理解:这里的l一般0,r一般是个数-1(减去第0个数)
{
     if (l >= r) return;//排序首先看边界,如果区间里没有数或只有一个数则不用排序,否则如下进行上述的1,2,3点
     int i = l - 1, j = r + 1 ,x = q[l + r >> 1];//问:为什么不是i=l,j=r?答:因为是先移动完指针再进行判断,因此指针要先放在两个指针的左右两侧一格,这样往中间移动一格后才能到正真的边界,注意:这里的i,j,l,r都为下标。
     while (i < j) 
     {
         do i ++ ; while (q[i] < x);//指针移动的判断不带等号,因为如果选取的x是数组里最大的数,那么一直满足q[i]<=x,i会一直++发生越界都不会停下,j同理。eg.123,选取3,i<=3,i++,i=3也会向后继续移动,已越界,错误,故此不能加=
         do j -- ; while (q[j] > x);
         if (i < j) swap(q[i], q[j]);//如果这两个指针还没有相遇,则交换,如果不用swap可以写:int t=q[i];q[i]=q[j];q[j]=t;
     }
     quick_sort(q, l, j);
     quick_sort(q, j + 1, r);//eg.1 2排序:
}

🍓对以上快速排序代码进行测试,模板可用(●’◡’●)!
image.png
🍓测试代码

#include<bits/stdc++.h> 
using namespace std;
void quick_sort(int q[], int l, int r)
{
     if (l >= r) return;
     int i = l - 1, j = r + 1 ,x = q[l + r >> 1];
     while (i < j) 
     {
         do i ++ ; while (q[i] < x);
         do j -- ; while (q[j] > x);
         if (i < j) swap(q[i], q[j]);
     }
     quick_sort(q, l, j);
     quick_sort(q, j + 1, r);
}
int main()
{
	int a[5]={5,3,2,8,6};//对5,3,2,8,6进行排序 
	quick_sort(a,0,4);//传入数组,传入l,r进行快速排序 
	for(int i;i<5;i++)
	{
		cout<<a[i]<<" ";	//快速排序结果为:23568 
	}
	return 0;
}

✨归并排序——分治 O(nlogn)

image.png
1.确定分界点:mid=(l+r)/2

要格外注意分界点:归并排序是下标的中间值,快速排序是随机一个数组里面的值

2.递归排序left,right
3.归并——合二为一 //实际是一个双指针算法
image.png
🍓归并排序模板:

void merge_sort(int q[], int l, int r)
{
	int tmp[5];//可变
	if (l >= r) return;
	int mid = l + r >> 1;
	merge_sort(q, l, mid);//l是左半边起点
	merge_sort(q, mid + 1, r);//mid+1是右半边起点
	int k = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r)//i,j分别是左右两边的指针
	   if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];//tmp[k++]=q[i++]等价于tmp[k]=q[i],k++,i++
	   else tmp[k ++ ] = q[j ++ ];//比较q[i],q[j],哪个小就把哪个放到tmp里(最后tmp的顺序就可以从小到大依次排)
    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];//把左右两边没有循环完的数放到最后(因为左右两边本身就已经从小到大排好序故这些数一定从小到大)
    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];//将tmp里的数复制回q中
}

🍓对以上快速排序代码进行测试,模板可用(●’◡’●)!
image.png
🍓测试代码

#include<bits/stdc++.h> 
using namespace std;
void merge_sort(int q[], int l, int r)
{
	int tmp[5];
	if (l >= r) return;
	int mid = l + r >> 1;
	merge_sort(q, l, mid);
	merge_sort(q, mid + 1, r);
	int k = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r)
	   if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
	   else tmp[k ++ ] = q[j ++ ];
    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];
    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
int main()
{
	int a[5]={8,3,2,7,6};//对5,3,2,8,6进行排序 
	merge_sort(a,0,4);//传入数组,传入l,r进行快速排序 
	for(int i;i<5;i++)
	{
		cout<<a[i]<<" ";	//快速排序结果为:23568 
	}
	return 0;
}
  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

命运之光

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

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

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

打赏作者

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

抵扣说明:

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

余额充值