归并排序

数据结构笔记17-排序技术

最后都变了- 提交于 2019-12-18 00:24:40
在排序问题中,通常将数据元素称为记录 排序的基本概念 正序:待排序序列中的记录已按关键码排好序。 逆序(反序):待排序序列中记录的排列顺序与排好序的顺序正好相反。 趟:在排序过程中,将待排序的记录序列扫描一遍称为一趟。 通常,一次排序过程需要进行多趟扫描才能完成 排序算法的性能 1.时间复杂性:基本操作。 内排序在排序过程中的基本操作: (1)比较:关键码之间的比较; (2)移动:记录从一个位置移动到另一个位置。 2.空间复杂性: 辅助存储空间。 辅助存储空间是指在数据规模一定的条件下,除了存放待排序记录占用的存储空间 之外,执行算法所需要的其他存储空间。 排序算法的存储结构 从操作角度看,排序是线性结构的一种操作,待排序记录可以用顺序存储结构 或链接存储结构存储。 插入类排序 插入排序的主要操作是插入, 其基本思想是: 每次将一个待排序的记录按其关键码的大小插入到一个已经排好序的有序序列 中,直到全部记录排好序为止。 插入类排序方法有以下两种: 直接插入排序 希尔排序 直接插入排序 基本思想:在插入第 i(i>1)个记录时,前面的 i-1个记录已经排好序。 需解决的关键问题: (1)如何构造初始的有序序列? 解决方法: 将第1个记录看成是初始有序表,然后从第2个记录起依次插入到这个有序表中,直 到将第n个记录插入。 算法描述: for (i=2; i<=n; i++) {

【数据结构】【归并排序】

萝らか妹 提交于 2019-12-17 09:18:06
#include<bits/stdc++.h> using namespace std; int k,n,ans=0; int a[500100],b[500100]; void merge_sort(int l,int r) { if(l==r)return ;//一个数不用排 int m=(l+r)>>1; merge_sort(l,m); merge_sort(m+1,r); int i=l,j=m+1,k=0;//i左边最小位置,j右边最小位置 while(i<=m&&j<=r) if(a[i]<=a[j])b[++k]=a[i++]; else ans+=m-i+1,b[++k]=a[j++];//加入右半段时,逆序对数增加 while(i<=m)b[++k]=a[i++];//加入左边剩余的数 while(j<=r)b[++k]=a[j++];//加入右边剩余的数 for(i=1; i<=k; i++)a[l+i-1]=b[i]; } int main() { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); merge_sort(1,n); for(int i=1;i<=n;i++) printf("%d ",b[i]); return 0; } 来源: CSDN 作者: 狠人王 链接: https:

归并排序

情到浓时终转凉″ 提交于 2019-12-17 06:00:40
输入 第一行为数列的总个数,第二行为待排序的数列 输出 排序后的数列 样例输入 8 10 4 6 3 8 2 5 7 样例输出 2 3 4 5 6 7 8 10 代码: #include<iostream> #include<cstring> int r[110]; int r1[110]; void Merge(int r[],int r1[],int s,int m,int t) { int i=s; int j=m+1; int k=s; while(i<=m&&j<=t) { if(r[i]<=r[j]) r1[k++]=r[i++]; else r1[k++]=r[j++]; } if(i<=m) { while (i<=m) r1[k++]=r[i++]; } else { while(j<=t) r1[k++]=r[j++]; } } void MergePass(int r[],int r1[],int n,int h) { int i=1; while(i<=n-2*h+1) { Merge(r,r1,i,i+h-1,i+2*h-1); i+=2*h; } if(i<n-h+1) Merge(r,r1,i,i+h-1,n); else for (int k=i; k<=n; k++) r1[k]=r[k]; } void MergeSort(int r[],int

归并排序、快速排序

笑着哭i 提交于 2019-12-15 07:47:33
归并排序:使用的是分而治之的思想,将大问题分解成小的子问题来解决,比如用归并排序来对一个数组进行排序,首先把数组从中间分成前后两部分,然后对它们分别排序,再将排好序的两部分合并在一起,这样整个数组就有序了。 任何情况下都是O(nlogn),在合并两个有序数组为一个有序数组时,需要借助额外的存储空间,n/2,n/4,…,1 ,所以空间复杂度为 O(n)。稳定。 public void mergeSort ( int [ ] a ) { int n = a . length ; if ( n <= 1 ) { return ; } merge ( a , 0 , n - 1 ) ; } private void merge ( int [ ] a , int l , int r ) { if ( l >= r ) { return ; } int mid = l + ( ( r - l ) >> 1 ) ; merge ( a , l , mid ) ; merge ( a , mid + 1 , r ) ; mergeTwo ( a , l , mid , r ) ; } private void mergeTwo ( int [ ] a , int l , int mid , int r ) { int [ ] tmp = new int [ r - l + 1 ] ; int i

归并排序与快速排序

♀尐吖头ヾ 提交于 2019-12-14 05:48:30
一、归并排序 思路分析: 对于一组序列,那么程序进行就是先将所有数字分成单个部分,然后再两两排序结合,就是先从第4步开始,然后调用merge函数到第5步,然后继续调用merge函数,到第6步,依次下来,直至序列排好。 c++代码实现: # include <iostream> using namespace std ; void merge ( int * arr , int L , int M , int R ) { int left_size = M - L ; int right_size = R - M + 1 ; int * L_arr = new int [ left_size ] ; int * R_arr = new int [ right_size ] ; for ( int i = L ; i < M ; i ++ ) L_arr [ i - L ] = arr [ i ] ; for ( int i = M ; i <= R ; i ++ ) R_arr [ i - M ] = arr [ i ] ; int i = 0 , j = 0 , k = L ; while ( i < left_size && j < right_size ) if ( L_arr [ i ] < R_arr [ j ] ) arr [ k ++ ] = L_arr [ i ++

归并排序的实现

北城以北 提交于 2019-12-13 22:52:02
import java . util . Arrays ; public class MergeSort { public static void main ( String [ ] args ) { int [ ] array = new int [ 6 ] ; for ( int i = 0 ; i < 6 ; i ++ ) { array [ i ] = ( int ) ( Math . random ( ) * 20 ) ; } System . out . println ( "待排序的数据为:" + Arrays . toString ( array ) ) ; int [ ] temp = new int [ array . length ] ; mergeSort ( array , 0 , array . length - 1 , temp ) ; System . out . println ( "排序过后的数据为:" + Arrays . toString ( array ) ) ; } public static void mergeSort ( int [ ] array , int left , int right , int temp [ ] ) { if ( left < right ) { int mid = ( left + right ) /

归并排序——很容易理解的一篇文章

南楼画角 提交于 2019-12-13 14:48:04
[图解] 归并排序 1. 图示过程 (1) 归并排序的流程 (2) 合并两个有序数组的流程 2. 动图展示 3. Java代码实现 public static void mergeSort ( int [ ] arr ) { sort ( arr , 0 , arr . length - 1 ) ; } public static void sort ( int [ ] arr , int L , int R ) { if ( L == R ) { return ; } int mid = L + ( ( R - L ) >> 1 ) ; sort ( arr , L , mid ) ; sort ( arr , mid + 1 , R ) ; merge ( arr , L , mid , R ) ; } public static void merge ( int [ ] arr , int L , int mid , int R ) { int [ ] temp = new int [ R - L + 1 ] ; int i = 0 ; int p1 = L ; int p2 = mid + 1 ; // 比较左右两部分的元素,哪个小,把那个元素填入temp中 while ( p1 <= mid && p2 <= R ) { temp [ i ++ ] = arr [ p1

归并排序

那年仲夏 提交于 2019-12-13 05:43:21
给定你一个长度为n的整数数列。 请你使用归并排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n。 第二行包含 n 个整数(所有整数均在 1 − 1 0 9 1-10^9 1 − 1 0 9 范围内),表示整个数列。 输出格式 输出共一行,包含 n 个整数,表示排好序的数列。 数据范围 1 ≤ n ≤ 1000001 ≤ n ≤ 100000 1≤n≤1000001≤n≤100000 1 ≤ n ≤ 1 0 0 0 0 0 1 ≤ n ≤ 1 0 0 0 0 0 输入样例: 5 3 1 2 4 5 输出样例: 1 2 3 4 5 # include <iostream> using namespace std ; const int N = 1e6 + 10 ; int a [ N ] , tmp [ N ] ; void merge_sort ( int l , int r ) { if ( l >= r ) return ; int mid = l + r >> 1 ; merge_sort ( l , mid ) , merge_sort ( mid + 1 , r ) ; int k = 0 , i = l , j = mid + 1 ; while ( i <= mid && j <= r ) if ( a [ i

归并排序总结

无人久伴 提交于 2019-12-11 10:23:31
#include <bits/stdc++.h> using namespace std; int n,r[1000],r1[1000]; void merge_(int r[],int r1[],int low,int mid,int high) { int i,j,k; i=low,j=mid+1,k=low; while((i<=mid)&&(j<=high)) if(r[i]<=r[j]) r1[k++]=r[i++]; else r1[k++]=r[j++]; while(i<=mid) r1[k++]=r[i++]; while(j<=high) r1[k++]=r[j++]; }//合成 void mergepass(int r[],int r1[],int length) { int i,j; i=0; while(i+2*length-1<n){ merge_(r,r1,i,i+length-1,i+2*length-1); i=i+2*length; } if(i+length-1<n-1) merge_(r,r1,i,i+length-1,n-1); else for(j=i;j<n;j++) r1[j]=r[j]; }//两个两个的归并 void mergesort(int r[]) { int length; length=1; while(length

LeetCode 148——排序链表(归并排序)

自作多情 提交于 2019-12-11 02:56:06
一、题目介绍 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 2: 输入: -1->5->3->4->0 输出: -1->0->3->4->5 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/sort-list 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 二、解题思路 利用归并排序完成该题目,因为是对链表排序,所以不需要引入太多的额外空间。归并排序分为以下三步: (1)计算链表长度 (2)自底向上分割链表,先按照长度为2^0分割,再按照2^1分割,再按照2^2分割,以此类推…… (3)每次分割之后,需要将分割后的链表,有序合并。 三、解题代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* cut(ListNode* node, int n) //以node为起点切掉n个节点,返回剩下链表的表头 {