zoukankan      html  css  js  c++  java
  • 《算法导论》(一)插入排序与合并排序

    插入排序

    书上说的很好,用打牌作比方。就是一边是排好序的,剩下的是待排序的,每次取一个待排序的元素,找到按序的位置,插入已排好序的部分中。元素取完也就结束了。复杂度O(n^2)。

    代码:

    1 #include <iostream>
    2  using namespace std;
    3  #define LENGTH 11
    4
    5  void insert_sort(int array[],int len)
    6 {
    7 int i,j;
    8
    9 for (i=1;i<len;i++)
    10 {
    11 int key=array[i];
    12 for (j=i-1;j>=0&&array[j]>key;j--)
    13 {
    14 array[j+1]=array[j];
    15 }
    16 array[j+1]=key;
    17 }
    18 }
    19  int main()
    20 {
    21 int array[LENGTH]={9,3,5,12,7,34,56,28,16,4,10};
    22 int i=0;
    23
    24 for (i=0;i<LENGTH;i++)
    25 {
    26 cout<<array[i]<<" ";
    27 }
    28 cout<<endl;
    29
    30 insert_sort(array,LENGTH);//sort
    31  
    32 for (i=0;i<LENGTH;i++)
    33 {
    34 cout<<array[i]<<" ";
    35 }
    36 cout<<endl;
    37 }

    合并排序

    合并排序是一种分治法,实现上用了递归结构。过程是:先将待排序的元素分为两部分,一般是对等长度的两部分,称为左右L、R,先分别将L,R进行合并排序,然后将排序好的L、R合并在一起,则所有元素都有序。复杂度O(nlgn)。

    代码

    1 #include <iostream>
    2  using namespace std;
    3  #define LENGTH 10
    4
    5  void merge(int array[],int start,int middle,int end)
    6 {
    7 int i,j,k;
    8 int n1=middle-start+1,n2=end-middle;
    9 int *L=new int[n1+1],*R=new int[n2+1];
    10
    11 for (i=0;i<n1;i++)
    12 {
    13 L[i]=array[start+i];
    14 }
    15 for (i=0;i<n2;i++)
    16 {
    17 R[i]=array[middle+i+1];
    18 }
    19 L[n1]=INT_MAX;
    20 R[n2]=INT_MAX;
    21
    22 i=0,j=0;
    23 for (k=start;k<=end;k++)
    24 {
    25 if(L[i]<=R[j])
    26 {
    27 array[k]=L[i];
    28 i++;
    29 }
    30 else
    31 {
    32 array[k]=R[j];
    33 j++;
    34 }
    35 }
    36 }
    37
    38  void merge_sort(int array[],int start,int end)
    39 {
    40 int i,j;
    41 if(start<end)
    42 {
    43 int middle=(start+end)/2;
    44 merge_sort(array,start,middle);
    45 merge_sort(array,middle+1,end);
    46 merge(array,start,middle,end);
    47 }
    48 }
    49
    50  int main()
    51 {
    52 int i=0;
    53 int array[LENGTH]={9,12,5,24,8,7,15,10,0,22};
    54 for (i=0;i<LENGTH;i++)
    55 {
    56 cout<<array[i]<<" ";
    57 }
    58 cout<<endl;
    59
    60 merge_sort(array,0,LENGTH-1);
    61
    62 for (i=0;i<LENGTH;i++)
    63 {
    64 cout<<array[i]<<" ";
    65 }
    66 cout<<endl;
    67
    68 return 0;
    69 }

    合并排序的扩展应用

    对合并排序稍作一些改动,可以以O(nlgn)的复杂度实现其他功能。

    思考题2.3.7

    思路:

    I  对集合S中的元素进行排序,选择复杂度为O(nlgn)的排序算法,这里是合并排序
    II 从两头开始遍历排序后S的元素,下标分别为i、j,若S[i]+S[j]==x,返回;若S[i]+S[j]>x,j--;若S[i]+S[j]<x,i++

    代码

    1 #include <iostream>
    2  using namespace std;
    3  #define LENGTH 10
    4
    5  void merge(int array[],int start,int middle,int end)
    6 {
    7 int i,j,k;
    8 int n1=middle-start+1,n2=end-middle;
    9 int *L=new int[n1+1],*R=new int[n2+1];
    10
    11 for (i=0;i<n1;i++)
    12 {
    13 L[i]=array[start+i];
    14 }
    15 for (i=0;i<n2;i++)
    16 {
    17 R[i]=array[middle+i+1];
    18 }
    19 L[n1]=INT_MAX;
    20 R[n2]=INT_MAX;
    21
    22 i=0,j=0;
    23 for (k=start;k<=end;k++)
    24 {
    25 if(L[i]<=R[j])
    26 {
    27 array[k]=L[i];
    28 i++;
    29 }
    30 else
    31 {
    32 array[k]=R[j];
    33 j++;
    34 }
    35 }
    36 }
    37
    38  void merge_sort(int array[],int start,int end)
    39 {
    40 int i,j;
    41 if(start<end)
    42 {
    43 int middle=(start+end)/2;
    44 merge_sort(array,start,middle);
    45 merge_sort(array,middle+1,end);
    46 merge(array,start,middle,end);
    47 }
    48 }
    49
    50  bool find_two_ele(int array[],int len,int x,int &x1,int &x2)
    51 {
    52 int i,j;
    53 for (i=0,j=len-1;i<len;)
    54 {
    55 int sum=array[i]+array[j];
    56 if(sum==x)
    57 {
    58 x1=array[i];
    59 x2=array[j];
    60 return true;
    61 }
    62 else
    63 if(sum>x)
    64 {
    65 j--;
    66 }
    67 else
    68 {
    69 i++;
    70 }
    71 }
    72 return false;
    73 }
    74  int main()
    75 {
    76 int i=0;
    77 int array[LENGTH]={9,12,5,24,8,7,15,10,0,22};
    78
    79 merge_sort(array,0,LENGTH-1);
    80
    81 int x=15,x1,x2;
    82
    83 if(find_two_ele(array,LENGTH,x,x1,x2))
    84 {
    85 cout<<"Yes."<<x<<"="<<x1<<"+"<<x2<<endl;
    86 }else
    87 {
    88 cout<<"No."<<endl;
    89 }
    90
    91 return 0;
    92 }

    练习题2-4

    逆序对问题,可以在合并的时候统计有多少逆序对。

    代码

    1 /****************
    2 逆序对问题
    3 ****************/
    4 #include <iostream>
    5  using namespace std;
    6  #define LENGTH 10
    7
    8  int Num=0;
    9
    10  int merge(int array[],int start,int middle,int end)
    11 {
    12 int i,j,k,count=0;
    13 int n1=middle-start+1,n2=end-middle;
    14 int *L=new int[n1+1],*R=new int[n2+1];
    15 for (i=0;i<n1;i++)
    16 {
    17 L[i]=array[start+i];
    18 }
    19 for (i=0;i<n2;i++)
    20 {
    21 R[i]=array[middle+i+1];
    22 }
    23 L[n1]=INT_MAX,R[n2]=INT_MAX;
    24
    25 i=0,j=0;
    26 for (k=start;k<=end;k++)
    27 {
    28 if(L[i]<R[j])
    29 {
    30 array[k]=L[i];
    31 i++;
    32 }
    33 else
    34 {
    35 array[k]=R[j];
    36 count+=middle-start-i+1;//count
    37   j++;
    38 }
    39 }
    40
    41 return count;
    42 }
    43
    44  int merge_sort(int array[],int start,int end)
    45 {
    46 if(start<end)
    47 {
    48 int middle=(start+end)/2;
    49 merge_sort(array,start,middle);
    50 merge_sort(array,middle+1,end);
    51 Num+=merge(array,start,middle,end);
    52
    53 return Num;
    54 }
    55 }
    56
    57  int main()
    58 {
    59 int array[LENGTH]={9,12,5,24,8,7,15,10,0,22};
    60
    61 cout<<merge_sort(array,0,LENGTH-1)<<endl;
    62
    63 for (int i=0;i<LENGTH;i++)
    64 {
    65 cout<<array[i]<<" ";
    66 }
    67 cout<<endl;
    68
    69 return 0;
    70 }
  • 相关阅读:
    python基础教程(第二版)---1.11字符串
    python基础教程(第二版)---1.91(我只记录了cmath模块相关)
    python基础教程(第二版)---1.7获取用户输入(讲的是input函数)
    python基础教程(第二版)---1.6语句
    openGL 进行图像处理
    uchar4
    709 与 601 公式上的区别
    J420P 黑白红青蓝黄对应的YUV 值
    混音的方法
    CPU周期, 时钟周期, 机器周期, 指令周期 总线周期
  • 原文地址:https://www.cnblogs.com/njucslzh/p/1815160.html
Copyright © 2011-2022 走看看