讲解的视频-->快速排序与归并排序_哔哩哔哩_bilibili
开始呢,我先sorry一下,最近比较忙,可能没有很仔细,不过,后期我会陆续更新讲解
小tip:
为什么,我说归并和快排差不多?因为看过我前期(直达-->快速排序) 的童鞋,就可以大致了解
快速排序的思想:
1.先找目标值(target),根据其排为左边都是“<=target”,右边都是“>=target”的状态
2.将其继续分割,再递归上一步排序,一直分割到不能分割,就说明排好了
就利用的“分治回溯”的思想,而归并就更为明显
归并排序的思想:
1.先分割,分到不能再分,分到两个数组的元素都为1(两个指针指向相邻元素)
2.将连个指针作为队头进行比较,谁小谁放空数组,然后后移再与之前大的呢个指针的数比较,最后把排好序的原数组进行覆盖
说白了,就是切蛋糕切的不能再切了,再拿着每次同时切的两块比大小,谁小谁放前面,再把蛋糕按顺序拼好
题目描述
给定你一个长度为n的整数数列。
请你使用归并排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在1~10^9范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
#include<iostream>
#include<vector>
using namespace std;//格式记住就行
const int N=100010;//固定N的值
int n;
int temp[N];//定义全局变量
void merge_sort(int l,int r)//定义边界
{
if(l>=r) return;//如果切到不能再切,就开始回溯判断
int mid=l+r>>1;//相当于除2,但要速度快
merge_sort(l,mid);//切蛋糕,每次切一半
merge_sort(mid+1,r);
// vector<int> g;
int g[N];//定义一个空数组
int k=0,a=l,b=mid+1;//定义两个指针,指向两个数组的头
while(a<=mid&&b<=r)//在两个相邻数组中数字的是按顺序的,就从两个头开始比较,将两个顺序的数组合并
{//其中一个超出范围就停下来
if(temp[a]<=temp[b]) g[k++]=temp[a++];//如果第一个数组的第一个元素小,呢就把它先放在空数组里,同时向后移一位
else g[k++]=temp[b++];//否则第二个数组第一个元素小,同理上
}
while(a<=mid) g[k++]=temp[a++];//这两个数组其中一个放完了,另一个还没放完,就继续
while(b<=r) g[k++]=temp[b++];
for(int i=l,j=0;i<=r;i++,j++)//将排好序的数组,赋予给原数组
temp[i]=g[j];
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
scanf("%d",&temp[i]);
merge_sort(0,n-1);
for(int i=0;i<n;i++)
printf("%d ",temp[i]);
return 0;
}
错误补充:我一直以为vector动态数组,可以直接赋值,然后我发现报错了,no!
通过实践(并没有去查具体资料,如果有其他大佬,知道求指正)
如果想直接赋值,就必须要像数组一样定义容器大小,如果不定义要用push_back
而且完全没必要我发现,直接定义一个数组,嘎嘎香,甚至更快!
更改后的代码
void merge_sort(int l,int r)//定义边界
{
if(l>=r) return;//如果切到不能再切,就开始回溯判断
int mid=(l+r)/2;//相当于除2,但要速度快
merge_sort(l,mid);//切蛋糕,每次切一半
merge_sort(mid+1,r);
vector<int> g;
// int g[N];//定义一个空数组
int k=0,a=l,b=mid+1;//定义两个指针,指向两个数组的头
while(a<=mid&&b<=r)//在两个相邻数组中数字的是按顺序的,就从两个头开始比较,将两个顺序的数组合并
{//其中一个超出范围就停下来
if(temp[a]<=temp[b])
// g[k++]=temp[a++];//如果第一个数组的第一个元素小,呢就把它先放在空数组里,同时向后移一位
g.push_back(temp[a++]);
else
// g[k++]=temp[b++];//否则第二个数组第一个元素小,同理上
g.push_back(temp[b++]);
}
while(a<=mid)
// g[k++]=temp[a++];//这两个数组其中一个放完了,另一个还没放完,就继续
g.push_back(temp[a++]);
while(b<=r)
// g[k++]=temp[b++];
g.push_back(temp[b++]);
for(int i=l,j=0;i<=r;i++,j++)//将排好序的数组,赋予给原数组
temp[i]=g[j];
}
心得:(就是废话) O(∩_∩)O
哎,马上要蓝桥杯了 ,最近压力是真的大。早就知道自己差的好远,走弯路太多了,而且还是不勤奋,感觉这次去就是给各位大佬当垫脚石了(心甘情愿),所以我决定要持续更新了,为明年备战吧,算是,其实上大学才发现,躺着不动很舒服,但凡你走起来,就会遇到跑的人,看着他们的背影,你又会感叹,为什么自己在走,道阻其长吧!/(ㄒoㄒ)/~~
欢迎来到一日一题的小菜鸟频道,睡不着就看看吧!