归并排序和快速排序模版

摘自Acwing

归并排序

 1 #include <iostream>
 2 using namespace std;
 3
 4 const int N = 1e5 + 10;
 5
 6 int n;
 7 int q[N], tmp[N];
 8 void merge_sort(int q[], int l, int r)
 9 {
10     if (l >= r)
11         return;
12     int mid = l + r >> 1;
13     merge_sort(q, l, mid), merge_sort(q, mid + 1, r); // recurse until
14
15     int k = 0, i = l, j = mid + 1;
16     while (i <= mid && j <= r) // two pointer
17     {
18         if (q[i] <= q[j])
19             tmp[k++] = q[i++];
20         else
21             tmp[k++] = q[j++];
22     }
23     while (i <= mid) // remaining of left part
24         tmp[k++] = q[i++];
25     while (j <= r)
26         tmp[k++] = q[j++]; // remaining of right part
27     for (i = l, j = 0; i <= r; i++, j++) // place them in the correct location
28         q[i] = tmp[j];
29 }
30 int main()
31 {
32     scanf("%d", &n);
33     for (int i = 0; i < n; ++i)
34         scanf("%d", &q[i]);
35     merge_sort(q, 0, n - 1);
36     for (int i = 0; i < n; ++i)
37         printf("%d ", q[i]);
38     return 0;
39 }

N:最大数组长度(+10防止溢出)

n: 数组长度

q:原未排序数组 -> 排好序数组

tmp: 当前分离的两部分通过双指针找到的排好序的数组(类似选择排序)

每次得到tmp之后要把它放到正确的q的位置,所以加了26 - 27行

快速排序

 1 #include <iostream>
 2 using namespace std;
 3 const int N = 1e5 + 10;
 4
 5 int n;
 6 int q[N];
 7
 8 void quick_sort(int q[], int l, int r)
 9 {
10     if (l >= r)
11         return;
12     int x = q[(l + r) / 2], i = l - 1, j = r + 1;
13     while (i < j)
14     {
15         while (q[++i] < x);
16         while (q[--j] > x);
17         if (i < j) swap(q[i], q[j]);
18     }
19     quick_sort(q, l, j);
20     quick_sort(q, j + 1, r);
21 }
22
23 int main()
24 {
25     scanf("%d", &n);
26     for (int i = 0; i < n; ++ i)
27         scanf("%d", &q[i]);
28     quick_sort(q, 0, n - 1);
29     for (int i = 0; i < n; ++ i)
30         printf("%d ", q[i]);
31     return 0;
32 }

N:最大数组长度(+10防止溢出)

n: 数组长度

q:原未排序数组 -> 排好序数组

x:partition point

i和j:最左和最右的指针(类似selection sort)

与merge sort不同的是先排序再递归,首先使用双指针把小于x的和大于x的放在x的左边和右边(一样的既在左边也可以在右边,所以算法不稳定)

partition的位置既可以是最左边,右边,中间,也可以是随机的,平均的是见复杂度是O(n)

原文地址:https://www.cnblogs.com/goldenticket/p/12128458.html

时间: 2024-07-31 15:29:09

归并排序和快速排序模版的相关文章

JavaScript算法(归并排序与快速排序)

归并排序与快速排序这两个算法放在一起,也是因为时间复杂度都是对数级别的. 目前看过的资料,归并排序看<学习JavaScript数据结构与算法>介绍的归并排序吧,快速排序直接看百度百科,讲的不错.通过这两份资料弄明白实现原理之后,最后看<学习JavaScript数据结构与算法>一书里的JS实现代码. 和之前的一样,嗯,<学习JavaScript数据结构与算法>这本书里都有现成ES5代码,就不在这儿写了,关键是弄清楚原理,然后JS代码每天写两遍,就OK了.ES6的代码周五之

对比归并排序和快速排序的性能

对比归并排序和快速排序的性能 实验数据: {99,95,90,88,85,83,80,75,70,65,60,55,50} 伪代码表示: 核心代码: 实现代码: #include<iostream> using namespace std; /************声明归并排序函数*****************/ void Merge(int r[],int r1[],int s,int m,int t); void MergeSort(int r[],int s,int t); /**

插入排序,希尔排序,堆排序,归并排序,快速排序Java实现

参看:数据结构与算法分析-c语言描述 public class Main { public static void main(String[] args) { String[] a = { "a", "d", "e", "f", "m" }; String[] b = { "a", "h", "g", "l", "z&

分治算法-归并排序、快速排序

分治算法:把一个任务,分成形式和原任务相同,但规模更小的几个部分任务(通常是两个部分),分别完成,或只需要选一部完成.然后再处理完成后的这一个或几个部分的结果,实现整个任务的完成. 分治的典型应用:归并排序.快速排序 归并排序动态图: 1 package com.inbreak.cnblogs.sort; 2 3 import com.inbreak.cnblogs.Helper; 4 5 /** 6 * 归并排序: 7 * 分别前一半.后一半排序 8 * 将前半部分.后半部分归并到一个有序数组

JavaScript 数据结构与算法之美 - 归并排序、快速排序、希尔排序、堆排序

1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算法和方便以后复习. 之所以把归并排序.快速排序.希尔排序.堆排序放在一起比较,是因为它们的平均时间复杂度都为 O(nlogn). 请大家带着问题:快排和归并用的都是分治思想,递推公式和递归代码也非常相似,那它们的区别在哪里呢 ? 来阅读下文. 2. 归并排序(Merge Sort) 思想 排序一个数

分治算法——归并排序与快速排序

1.归并排序 分治思想:每次从中间分开为两个子问题,对每个子问题排序完成之后,将两个已排序的部分进行归并操作即得到最终排序的结果. (1)如果数组S中元素个数为0或者1返回 (2)选取中间位置的元素下标,对左半部分SL递归排序,对右半部分SR递归排序 (3)将排好序的SL.SR进行归并后返回最终结果 平均时间复杂度O(NlogN),最坏情况也为O(NlogN),最好情况为O(N). C++模版实现: template <typename T> void TMergeSort(vector<

归并排序、快速排序

归并排序 对于一个数字序列,它越接近已排好序的状态,插入排序的效率越高.对已经排好序的数列,插入排序只用比较n-1次就可以了. 我们可以不准确的把归并排序看作插入排序的并行运行,即划分-->子项分别插入排序-->合并 - - - - - - - - - - - -|- - - - - -|- -|- -|- - -|-|-|-|-|-|-|- 从上到下,对一个数组进行不断划分,从下到上看,子项分别插入排序-->合并.在这个过程中,我们实际对插入排序进行了分治. void merge_so

冒泡排序,插入排序,归并排序,快速排序的学习笔记

这几个很基础的排序非常有用,我重新整理了下代码 1 #include<iostream> 2 #include<algorithm> 3 4 using namespace std; 5 6 void Bouble_Sort(int * Arry,int Lenth) //冒泡排序 7 { 8 int i,k; 9 10 int flag = 0; 11 12 for(i = Lenth - 1;i >= 0; i--) 13 { 14 for(k=0;k<i;k++)

三种排序算法(归并排序、快速排序,堆排序)

归并排序:建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. 归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n)),算法不是自适应的,不需要对数据的随机读取. 工作原理: 1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后