前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >算法基础学习笔记——①排序

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

作者头像
命运之光
发布2024-03-20 10:49:43
1230
发布2024-03-20 10:49:43
举报
文章被收录于专栏:我在本科期间写的文章

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

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

✨快速排序——分治

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

1.确定分界点:(这里的分界点不一定是x,可以随意取值,常用取值方法如下) q[l],q[(l+r)/2],q[r],随机//这里随机数的表示:q[rand() % (r - l) + l] 2.调整区间:

3.递归处理左右两段(<=x和>=x这两段)

如何实现2: 方法1.

方法2.

将两个指针i,j从两头挪向分界点,直到有一个i>=x,此时这个i 需要放到右半边,一个j<x,此时这个j需要放到左半边,此时交 换i.j(swap),故此时i<=x,j>x,直到i,j相遇就可以把整个区间 一分为二

j的后面(不包括j)>=3,i的前面(不包括i)<=3(注意边界) 🍓代码实现

image.png
image.png

🍓快速排序模板:

代码语言:javascript
复制
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排序:
}

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

🍓测试代码

代码语言:javascript
复制
#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)

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

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

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

🍓归并排序模板:

代码语言:javascript
复制
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中
}

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

🍓测试代码

代码语言:javascript
复制
#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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ✨快速排序——分治
  • ✨归并排序——分治 O(nlogn)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档