快速排序
快速排序的步骤:
1.准备工作,建立数组(尽量大)用来存放原始数据。
2.确定分界点X,一般确定为两端和中间(数组的)。
3.调整区间,使得该数组被分为两部分(一部分大于等于X,一部分小于等于X)
核心步骤:建立双指针,一个指针指向第一个数的前一个,另一个指向最后一个元素的后一个,便于我们书写,让两个指针不断比较移动(当指针停止时,交换当时前指针上的数)使其可以继续移动,最后数组被分为两部分,一部分小于X,一部分大于X。
4.递归不断缩小区间,使得两端变成有序的数组。
代码
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n;
int a[N];
void quick_sort(int a[], int l, int r)
{
if (l >= r)return;//如果递归到只有一个或者没有元素的时候,停止
int i = l - 1, j = r + 1, x = a[(l + r) / 2];//i取初始数组的前一位,j取最后一位的后一位,便于操作。
//x为标准数,将区间一分为二
while (i < j)
{
while (a[++i] < x);//让i前面的数字都小于x
while (a[--j] > x);//让j后面的数字都大于x
if (i < j)swap(a[i], a[j]);//当两个指针停止运行的时候,说明当前的两个数字不符合要求(a[i]>x,a[j]<x])
//那么交换两个数字使其满足要求
}
quick_sort(a, l, j);//递归处理,使得数组变得有序
quick_sort(a, j + 1, r);
}
int main()
{
cin >> n;//输入需要排序的个数
for (int i = 0; i < n; i++)cin >> a[i];//输入数组
quick_sort(a, 0, n - 1);
for (int i = 0; i < n; i++)cout << a[i] << " ";//输出数组
return 0;
}
归并排序:
归并排序的基本步骤:
1.准备工作,建立两个数组,一个数组用来存放原始数据,另一个数组用来存储排序后的数组
2.将原数组一分为二(选取分界点,一般选择中间为分界点),并对两部分的数组进行递归处理,使得两部分的数组都变得有序
3.经过步骤二,两部分的数组都是有序的(从小到大)
核心思想:两部分的数组从前到后依次比较(双指针),选择出当前最小的数,并将此数存放起来(第二个数组),最后会出现一个部分中的数全部用完,另一个部分会剩余一部分(此部分数都大于前面已排序的数),因此将这部分的数直接加入到第二个数组即可。
4.将第二个数组中的数全部放到第一个原始数组中去(简单的循环)
代码:
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n;
int a[N], b[N];//一个用来放原始数据,另一个放排序后的数组
void merge_sort(int a[], int l, int r)
{
if (l >= r)return;//边界问题,当数组只有一个数或者没有数的时候,直接返回
int mid = (l + r) / 2;//取分界点,一般为数组中间
merge_sort(a, l, mid);//递归处理两部分数使其变的有序
merge_sort(a, mid + 1, r);
int i = l, j = mid + 1, k = 0;//双指针,分别指向两部分的第一个数
while (i <= mid && j <= r)//当一部分的数比较完毕的时候直接退出
{
if (a[i] < a[j])b[k++] = a[i++];
else b[k++] = a[j++];
}
while (i <= mid)b[k++] = a[i++];//推出上面的排序后,会有一部分的数未使用(大于已排序的数),将其加入到排序的数组
while (j <= r)b[k++] = a[j++];
for (int i = l, j = 0; i <= r; i++, j++)a[i] = b[j];//将原始数据排序好
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)cin >> a[i];
merge_sort(a, 0, n-1);
for (int i = 0; i < n; i++)cout << a[i] << " ";
return 0;
}
这些算法主要是为了了解分治的思想,将大问题化小,从而逐个击破。
分治算法介绍
分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。
如果原问题可分割成k个子问题,1<k≤n,且这些子问题都可解并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。
sort 太好用了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!