zoukankan      html  css  js  c++  java
  • 归并排序,快速排序 木

    归并排序: 归并排序是每次都把有序的区间合并起来构成一个新的有序序列。初始时区间长度是1;模拟求解时: 区间段数是n。每次最后那段都合并到前一段上。 递归求解: 只要注意边界就好了,left>=right就递归结束返回程序上一层。总的时间复杂度为0(nlogn),空间复杂度为0(n);

    代码一:模拟合并区间

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define maxSize 200008
     8 int Temp[maxSize];
     9 
    10 // 输入要排序的数据
    11 void inPutData(int myArray[], int n){
    12     for ( int i=1; i<=n; ++i )
    13        scanf ("%d", myArray+i);
    14 }
    15 // 输出排序后结果
    16 void outPutData(int myArray[], int n) {
    17      for ( int i=1; i<=n; ++i ) {
    18           if(i-1) printf(" ");
    19           printf("%d", myArray[i]);
    20      }
    21      puts("");
    22 }
    23 
    24 // 合并区间[l,mid]和[mid+1,r];
    25 
    26 void merge( int a[], int l, int mid, int r){
    27     int startA = l, endA = mid-1, i=l;
    28     int startB = mid, endB = r;
    29     while(startA<=endA && startB<=endB){
    30          if(a[startA]<=a[startB]) Temp[i++] =  a[startA++];
    31          else Temp[i++] = a[startB++];
    32     }
    33     while(startA<=endA) Temp[i++] = a[startA++];
    34     while(startB<=endB) Temp[i++] = a[startB++];
    35     for(i=l; i<=r; ++i ) a[i] = Temp[i];
    36 };
    37 
    38 // 模拟合并的
    39 void mergeSort( int myArray[], int n ) {
    40     /**
    41     segNum 区间段数
    42     segLength 区间平均长度
    43     lastSegLength 最后一段的长度
    44     */
    45     int segNum = n, segLength = 1, lastSegLength = 1;
    46     int tmp_segNum, tmp_segLength, i, j;
    47     while(segNum > 1) {
    48          tmp_segNum = segNum; // 保存原来的段数用于判断区间
    49          segNum >>= 1; // 合并后段数减半
    50          tmp_segLength = segLength<<1; // 合并后区间长度加倍
    51          if( tmp_segNum&1 ) // 如果段数是奇数
    52          {
    53              for( i=1, j=1; i<=segNum; j+=tmp_segLength, ++i )
    54                merge(myArray, j, j+segLength, j+tmp_segLength-1);
    55              //最后一段和前一段已合并的区间合并
    56              j = n-lastSegLength-tmp_segLength+1;
    57              merge(myArray, j, j+tmp_segLength, n);
    58              // 注意每次合并后要更新最后一段长度和平均长度
    59              lastSegLength += tmp_segLength;
    60              segLength = tmp_segLength;
    61          }else
    62          {
    63              for(i=1, j=1; i<=segNum; ++i, j+=tmp_segLength)
    64              {
    65                  if(i<segNum)
    66                     merge(myArray, j, j+segLength, j+tmp_segLength-1);
    67                  else // 特别注意这段的范围
    68                     merge(myArray, j, j+segLength, n);
    69              }
    70 
    71              lastSegLength += segLength;
    72              segLength = tmp_segLength;
    73          }
    74     }
    75 }
    76 
    77 int main(){
    78     int n;
    79     int myArray[maxSize];
    80     while( ~scanf("%d", &n) ) {
    81          inPutData(myArray, n);
    82          mergeSort(myArray, n);
    83          outPutData(myArray, n);
    84     }
    85 };

     代码二:递归合并区间,代码简单。

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define maxSize 200008
     8 
     9 template <typename T>
    10 void Swap( T& a, T& b){
    11    T tmp = a; a = b; b  = tmp;
    12 }
    13 
    14 // 输入要排序的数据
    15 void inPutData(int myArray[], int n){
    16     for ( int i=1; i<=n; ++i )
    17        scanf ("%d", myArray+i);
    18 }
    19 // 输出排序后结果
    20 void outPutData(int myArray[], int n) {
    21      for ( int i=1; i<=n; ++i ) {
    22           if(i-1) printf(" ");
    23           printf("%d", myArray[i]);
    24      }
    25      puts("");
    26 }
    27 
    28 int b[maxSize];
    29 void merge( int a[], int l, int mid, int r){
    30      int startA = l, endA= mid, i = l;
    31      int startB = mid+1, endB = r;
    32      while(startA<=endA && startB<=endB) {
    33           if(a[startA] <= a[startB] ) b[i++]= a[startA++];
    34           else b[i++] = a[startB++];
    35      }
    36      while(startA<=endA) b[i++] = a[startA++];
    37      while(startB<=endB) b[i++] = a[startB++];
    38      for(i=l; i<=r; ++i )  a[i] = b[i];
    39 }
    40 
    41 void mergeSort(int a[], int l, int r){
    42      if(l>=r) return ;
    43      int mid = (l+r)>>1;
    44      mergeSort(a, l, mid);
    45      mergeSort(a, mid+1, r);
    46      merge(a, l, mid, r);
    47 }
    48 
    49 int main(){
    50     int n;
    51     int myArray[maxSize];
    52     while( ~scanf("%d", &n) ) {
    53          inPutData(myArray, n);
    54          mergeSort(myArray, 1, n);
    55          outPutData(myArray, n);
    56     }
    57 };

    快速排序:从数组中选一个关键字,按关键字把数组分为两部分,之后这两部分序列在关键字的两边。接着细分,分治思想。比如a[left]为关键字划分,找左边大于a[left]的和右边小于a[left]的元素进行交换。得到序列a[1].... a[left]  ....a[n], 接着划分[1,left这个位置-1]和[left这个位置+1, right]。 平均时间复杂度为o(nlogn),最差情况下会达到0(n*n), 空间复杂度为0(n)的堆栈。代码如下:

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define maxSize 200008
     8 
     9 template <typename T>
    10 void Swap( T& a, T& b){
    11    T tmp = a; a = b; b  = tmp;
    12 }
    13 
    14 // 输入要排序的数据
    15 void inPutData(int myArray[], int n){
    16     for ( int i=1; i<=n; ++i )
    17        scanf ("%d", myArray+i);
    18 }
    19 // 输出排序后结果
    20 void outPutData(int myArray[], int n) {
    21      for ( int i=1; i<=n; ++i ) {
    22           if(i-1) printf(" ");
    23           printf("%d", myArray[i]);
    24      }
    25      puts("");
    26 }
    27 
    28 // 以a[left]作为关键字;
    29 
    30 void quickSort(int a[], int left, int right)
    31 {
    32     if(left >=  right) return ;
    33     int tmp = a[left], i = left, j = right+1;///
    34     while(i <= j) {/// j最后是小于i的,j所在的位置是最后一个小于tmp的。
    35         do ++i; while(a[i] < tmp);
    36         do --j; while(a[j] > tmp);
    37         if(i < j) Swap(a[i], a[j]);
    38     }
    39     Swap(a[left], a[j]);
    40     quickSort(a, left, j-1);
    41     quickSort(a, j+1, right);
    42 }
    43 
    44 int main(){
    45     int n;
    46     int myArray[maxSize];
    47     while( ~scanf("%d", &n) ) {
    48          inPutData(myArray, n);
    49          quickSort(myArray, 1, n);
    50          outPutData(myArray, n);
    51     }
    52 };
  • 相关阅读:
    OAuth 2.0理论
    mvvm
    js中使用new所做的事情
    使用vue实现图片上传插件
    控制元素滚动位置
    float属性
    确定节点直接的关系
    react 开发中的问题简记
    深复制浅复制
    HTML和CSS实现常见的布局
  • 原文地址:https://www.cnblogs.com/TengXunGuanFangBlog/p/data_structure_sort.html
Copyright © 2011-2022 走看看