快速排序

归并排序与快速排序模板与图解笔记(转载)

ⅰ亾dé卋堺 提交于 2020-03-04 07:20:10
https://blog.csdn.net/zpznba/article/details/83745205 C++ 归并排序与快速排序 2018年11月05日 15:15:31 zpznba 阅读数 948 归并排序: 【算法逻辑】 归并的思路(分治)是把一个大问题a拆解成两个小问题b和c,解决了两个子问题再整合一下,就解决了原问题。用递归的方法,先分解再合并(分治是一种解决问题的处理思想,递归是一种编程技巧,这两者并不冲突): 【代码实现】 # include <iostream> using namespace std; void Merge ( int arr[], int l, int q, int r){ int n=r-l+ 1; //临时数组存合并后的有序序列 int* tmp= new int[n]; int i= 0; int left=l; int right=q+ 1; while(left<=q && right<=r) tmp[i++] = arr[left]<= arr[right]?arr[left++]:arr[right++]; while(left<=q) tmp[i++]=arr[left++]; while(right<=r) tmp[i++]=arr[right++]; for( int j= 0;j<n;++j) arr[l+j]=tmp

快速排序

别来无恙 提交于 2020-03-04 01:49:33
快速排序 快速排序就是在待排序数组选取一个基准值,把比基准值大的元素放在右边,小的元素放在左边,然后递归的去对左边和右边执行相同操作。 public static void quickSort ( int [ ] arr , int left , int right ) { int l = left ; int r = right ; int pivot = arr [ ( left + right ) / 2 ] ; // 基准值 while ( l < r ) { // 当左边的值小于基准值时,向右移动 while ( arr [ l ] < pivot ) l ++ ; // 当右边的值大于基准值时,向左移动 while ( arr [ r ] > pivot ) r -- ; // 左边的已经小于等于基准值,右边的已经大于等于基准值 if ( l > r ) break ; // 交换 swap ( arr , l , r ) ; // 交换后左边的值等于基准值,继续向右移动 if ( arr [ l ] == pivot ) l ++ ; // 交换后右边的值等于基准值,向左移动 if ( arr [ r ] == pivot ) r -- ; // System.out.println("第一轮"); // System.out.println(Arrays

golang 快速排序

断了今生、忘了曾经 提交于 2020-03-03 22:00:14
golang 快速排序 package main import ( "fmt" "strconv" ) func quickSort(arr []int, low, high int) { if low < high { var pivot = partition(arr, low, high) quickSort(arr, low, pivot) quickSort(arr, pivot + 1, high) } } func partition(arr []int,low,high int) int { var pivot = arr[low] var i = low var j= high // 6 5 4 3 2 1 // 6 1 2 3 4 7 for i< j{ for arr[j] >= pivot && j > low { j-- } // for arr[i]<= pivot && i<high{ i++ } if i<j { arr[i],arr[j]=arr[j],arr[i] } } arr[low],arr[j] = arr[j],pivot // return j } func printArray(arr []int) { for i := 0; i < len(arr); i++ { fmt.Print(strconv.Itoa(arr[i]) +

数据结构-快速排序 归并排序

£可爱£侵袭症+ 提交于 2020-03-03 16:03:46
文章目录 归并排序 (Merge sort) 简介 代码 性能分析 快速排序(Quick sort) 简介 代码 性能分析 排序算法的结合 总结 注:所有的代码在我的 Github 中有均具体C++代码实现。 这里主要讲的是时间复杂度为O(nlogn)的两种排序算法:快速排序(Qiuck sort)和 归并排序 (Merge sort)。 这两种排序都是用了分治的思想,我们因此可以借鉴这个思想来解决非排序的一些问题,例如: 如何在O(n)的时间复杂度内查找一个无序数组中的第K大的元素? 归并排序 (Merge sort) 简介 简单地说,如果要排序一个数组,我们首先吧数组从中间分成前后两个部分,然后对前后两个部分分别排序,最后将排序好的两部分进行合并。 这里使用了分治的思想,也就是分而治之,将一个大问题分成几个小的子问题来解决,小的问题解决了,大的问题也就解决了。 这里,主要就是merge函数的实现问题了, merge(A[p...r], A[p...q], A[q+1...r]) 也就是将已经有序的 A[p...q] 和 A[q+1...r] 合并成一个有序的数组,这里我们使用了一个额外的临时数组,其空间带下为 r - p + 1 ,具体操作如下: 代码 void merge(int arr[], int l, int m, int r) { int n = r - l + 1;

PAT basic 1045 快速排序 (25分) 测试点 2 3 5 错误原因及解决方法

烂漫一生 提交于 2020-03-03 05:23:54
一、题目描述 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元? 例如给定 N = 5 N = 5 N = 5 , 排列是1、3、2、4、5。则: 1 的左边没有元素,右边的元素都比它大,所以它可能是主元; 尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元; 尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主元; 类似原因,4 和 5 都可能是主元。 因此,有 3 个元素可能是主元。 输入格式: 输入在第 1 行中给出一个正整数 N(≤10​5​​ ); 第 2 行是空格分隔的 N 个不同的正整数,每个数不超过 10​9​​ 。 输出格式: 在第 1 行中输出有可能是主元的元素个数;在第 2 行中按递增顺序输出这些元素,其间以 1 个空格分隔,行首尾不得有多余空格。 输入样例: 5 1 3 2 4 5 输出样例: 3 1 4 5 二、代码 //1045 # define _CRT_SECURE_NO_WARNINGS # include <iostream> # include <vector> # include <algorithm> using

快速排序

牧云@^-^@ 提交于 2020-03-03 05:14:39
void quicksort ( int * a , int l , int r ) { if ( l >= r ) return ; int temp = a [ l ] ; //哨兵 int i = l , j = r ; while ( i < j ) { while ( i < j ) { //从右开始往左判断 if ( a [ j ] >= temp ) { j -- ; } else { a [ i ++ ] = a [ j ] ; break ; } } while ( i < j ) { //从左开始往右判断 if ( a [ i ] <= temp ) { i ++ ; } else { a [ j -- ] = a [ i ] ; break ; } } } a [ i ] = temp ; //将哨兵放回中间位置 quicksort ( a , l , i - 1 ) ; //左边排序 quicksort ( a , i + 1 , r ) ; //右边排序 } 来源: CSDN 作者: qq_44877376 链接: https://blog.csdn.net/qq_44877376/article/details/104617933

常用的排序算法(一)

萝らか妹 提交于 2020-03-02 04:38:22
Date: 2016-02-14 #####排序算法的学习 #### 冒泡排序 时间复杂度:当顺序为正序的时候,为最好状态时间复杂度为O(N),平均时间复杂的为O(N^2) 因为没有创建新的存储结构所以空间复杂度为O(1) 冒泡排序是一种稳定的排序算法 #include <stdio.h> void Bubble_sort(int A[],int n); void Bubble_sort(int A[],int n){ int i,j,temp; for(i= 0 ;i < n - 1 ;i++){ for(j = 0;j< n -1 - i;j++){ if(A[j] > A[j+1]){ temp = A[j+1]; A[j+1] = A[j]; A[j] = temp; } } } } int main(int argc, const char * argv[]) { int A[7]={3,1,2,4,6,8,1}; Bubble_sort(A, 7); for(int i =0; i < 7;i++){ printf("%d",A[i]); } } ####改进的冒泡排序 使用冒泡排序对N个数据进行排序,一共需要进行n-1次比较,本来是正常顺序的数据也需要进行n-1次排序,所以当判断所有的数据为有序的时候不在进行排序直接跳出循环, void Bubble_sort(int

为什么quicksort比mergesort更好?

妖精的绣舞 提交于 2020-03-01 23:34:53
我在接受采访时被问到这个问题。 他们都是O(nlogn),但大多数人使用Quicksort而不是Mergesort。 这是为什么? #1楼 在所有条件相同的情况下,我希望大多数人都能使用最方便的东西,而且往往是qsort(3)。 除了快速排序之外,已知数组上的快速排序非常快,就像mergesort是列表的常见选择一样。 我想知道为什么看到 基数 或桶排序这么罕见。 它们是O(n),至少在链表上,所需要的只是将密钥转换为序数的一些方法。 (字符串和浮点数工作正常。) 我认为原因与计算机科学的教学方式有关。 我甚至不得不向算法分析的讲师证明,确实可以比O(n log(n))更快地排序。 (他有证据证明你不能比O(n log(n))更快地 进行比较 ,这是真的。) 在其他新闻中,浮点数可以按整数排序,但您必须在之后转换负数。 编辑:实际上,这是一种更加恶毒的方式来整理浮点数 - 整数: http : //www.stereopsis.com/radix.html 。 请注意,无论您实际使用哪种排序算法,都可以使用位翻转技巧... #2楼 对于原始值的DualPivotQuickSort带来的变化,答案会略微倾向于快速排序。 它在 JAVA 7中 用于在 java.util.Arrays中 进行排序 It is proved that for the Dual-Pivot

快速排序与归并排序

独自空忆成欢 提交于 2020-03-01 20:56:40
快速排序与归并排序 快速排序 快速排序又称”快排”。排序思路:给定一个数组,选定一个分区点pivot,使得小于等于pivot的元素放在左边,大于pivot放在右边,递归使得区间为1那么排序已经是从小到大了。 递归公式:quick_sort(p,q) = quick_sort(p,r-1) + quick_sort(r+1,q)满足p>=q则终止。 代码实现 /** * @Author : zzz * @Date : Created in 16:25 2020/2/22 * @Description : TODO */ public class SortDemo { private int [ ] arr = new int [ ] { 2 , 5 , 3 , 6 , 8 , 1 , 4 , 7 , 10 , 9 } ; public static void main ( String [ ] args ) { SortDemo sort = new SortDemo ( ) ; //快速排序 sort . quick_sort ( ) ; } public void print ( int [ ] a ) { for ( int i = 0 ; i < a . length ; i ++ ) { System . out . print ( a [ i ] + " " ) ; }

快速排序算法

孤街浪徒 提交于 2020-02-29 21:25:35
一、前言 快排是体现了分治法的经典算法,那么我们能从中获取的绝对不止是学到了一个排序算法,更重要的是分治法的核心思想—分。 快排的核心是如何分,然后才是治之。即分而治之。 二、快排的实现 快排的核心在于对待排序数组的划分,然后把小的都放在左边,大的都放在右边,不断的缩小划分的范围,最后出来的就是一个升序的数组。 一个元素是大还是小是相对于一个比较的值而言的,那这个值就叫主元。 例如: {4,3,1} 我们定3为主元,那么1应该放到3左边,4应该放到3的右边, 最后出来的就是 {1,3,4} 这样一个有序的数组。 一个长度为20的数组,第一次划分出左10个右10个元素(划分主元理想状态下) 然后左边的10个再5、5划分,右边的元素再5、5划分,依次进行,每次划分的范围都越来越小,重复着划分排序这一步骤,最后进行合并即可(其实都不用合并,因为当划分完后就是一个有序的数组了)。 很明显这是一个递归调用。划分,每次除了规模大小不一样之外,其他都是一样的。注意:主元也是会动态改变的,并不是固定的。 重点:划分 快排的核心在于划分,划分有三种算法。 掌握划分算法与思想,才是我们学习快排的目的。 划分算法有三种: 1、单向扫描法 思路: 三定一循环两交换 步骤 定义一个主元p, 默认为左边界第一个元素 定义一个左指针 left(起点,p+1) 定义一个右指针 right(终点