• poj 1006


    归并排序

    (一) 归并排序介绍

      归并排序是一种稳定的排序方法,时间复杂度O(n log(n)),主要思路是递归实现,把数组a[] ,分成两部分,分别进行排序,然后从新排序的两个(其中实现的时候用一个子数组就搞定了,这是个牛X的地方)子数组中取较小的数放入保存最后结果的数组中。核心思想:就是把两个已经排好的数组合成一个排序的数组。(显然是递归了) 

    (二) 归并排序的代码实现

    代码一:
    #include<iostream>
    using namespace std;
    
    int Sort(int a[],int merge[],int low,int high)//把a中的值排序到merge中
    {
        int b[100];//这是个temp局部值,它能保存两个半区
        int mid=(high+low)/2;
        int i=low,j=mid+1,k=low;
    /////////////////////////////////////////////////////////////////////////////////////
        if(low>=high)        //递归出口
        {
            if(low==high) merge[low]=a[low];
            return 0;
        }
        //////////////////////////////////////////////////////////////////////////////////////
        Sort(a,b,low,mid);     //分成两个子数组,进行排序
        Sort(a,b,mid+1,high);
      /////////////////////////////////////////////////////////////////////////////////////
        while((i<=mid)&&(j<=high))      //进行合并操作
        {
            if(b[i]<=b[j])
            {
                merge[k++]=b[i++];
            }
            else
            {
                merge[k++]=b[j++];
            }
        }
        while(i<=mid)
        {
            merge[k++]=b[i++];
        }
        while(j<=high)
        {
            merge[k++]=b[j++];
        }
        return 0;
    }
    //////////////////////////////////////////////////////////////////////////////////////
    int main()
    {
        int a[]={3,1,4,5,2,7,9,8,10};
        int merge[100];
        Sort(a,merge,0,8);
        for(int i=0;i<9;i++)
            cout<<merge[i]<<endl;
        return 0;
    }

    其实,该算法是递归排序中套一个合并(merge),所以可以改成两个函数,一个是merge_sort(),一个是merge() 。这样代码分割比较好:

    代码2
    #include<iostream>
    
    using namespace std;
    
    void merge(int a[],int low,int mid,int high)
    {
        int b[100];   //合并排序结果先保存到b中
        int i=low,j=mid+1,k=low;
        while((i<=mid)&&(j<=high))
        {
            if(a[i]<=a[j])
            {
                b[k++]=a[i++];
            }
            else
            {
                b[k++]=a[j++];
            }
        }
        while(i<=mid)
        {
            b[k++]=a[i++];
        }
        while(j<=high)
        {
            b[k++]=a[j++];
        }
        //把b中的值复制给a
        for(i=low;i<=high;++i)
        {
            a[i]=b[i];
        }
    }
    void Sort(int a[],int low,int high)
    {
        int mid=(high+low)/2;
        if(low<high) 
        {
            Sort(a,low,mid);
            Sort(a,mid+1,high);
            merge(a,low,mid,high);
        }
    }
    int main()
    {
        int a[]={3,1,4,5,2,7,9,8,10};
        Sort(a,0,8);
        for(int i=0;i<9;i++)
            cout<<a[i]<<endl;
        return 0;
    }

    (三)归并排序的应用:      

    (1)排序:

    (2)求逆序数:逆序数就是对于一个数列a[] ,若存在i<j && a[i] > a[j] ,则说(i,j)是一对逆序。其实就是在归并排序中合并的时候,加一个计数器就完事了。 。

    代码如下:

    #include<iostream>
    
     
    
    using namespace std;
    
     
    
    int merge(int a[],int low,int mid,int high)
    
    {
    
      int b[100];      //合并排序结果先保存到b中
    
      int i=low,j=mid+1,k=low;
    
      int count=0;     //计数
    
      int flag=0;
    
      while((i<=mid)&&(j<=high))
    
      {
    
             if(a[i]<=a[j])
    
             {
    
                    b[k++]=a[i++];
    
             }
    
             else
    
             {
    
                    b[k++]=a[j++];
    
                    count+=(mid-i+1);
    
             }
    
      }
    
     
    
      while(i<=mid)
    
      {
    
             b[k++]=a[i++];
    
      }
    
      while(j<=high)
    
      {
    
             b[k++]=a[j++];
    
            
    
      }
    
      //把b中的值复制给a
    
      for(i=low;i<=high;++i)
    
      {
    
             a[i]=b[i];
    
      }
    
      return count;
    
    }
    
     
    
    int InvertedNum(int a[],int low,int high)
    
    {
    
      int num1,num2,num3;
    
      int mid=(high+low)/2;
    
      int i=low,j=mid+1;
    
      if(low>=high)return 0;
    
      num1=InvertedNum(a,low,mid);
    
      num2=InvertedNum(a,mid+1,high);
    
      num3=merge(a,low,mid,high);
    
      return (num1+num2+num3);
    
    }
    
    int main()
    
    {
    
      int a[]={3,1,4,5,7,6,2};
    
      cout<<InvertedNum(a,0,6)<<endl;
    
      return 0;
    
    }

    函数学习:

    qsort

    语法:

       #include <stdlib.h>  void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );

    功能:buf 指向的数据(包含num 项,每项的大小为size)进行快速排序。如果函数compare 的第一个参数小于第二个参数,返回负值;如果等于返回零值;如果大于返回正值。函数对buf 指向的数据按升序排序。

    intcompare(constvoid*a,constvoid*b)
    {
      return*((int*)a)-*((int*)b);
    }
    qsort(array,num,sizeof(int),compare);

    memset

    语法:

     #include <string.h>
      void *memset( void *buffer, int ch, size_t count );

    功能: 函数拷贝chbuffer 从头开始的count 个字符里, 并返回buffer指针。 memset() 可以应用在将一段内存初始化为某个值。例如:

        memset( the_array, '\0', sizeof(the_array) );

    这是将一个数组的所以分量设置成零的很便捷的方法。

    memcpy

    语法:

      #include <string.h>
      void *memcpy( void *to, const void *from, size_t count );

    功能:函数从from中复制count 个字符到to中,并返回to指针。 如果tofrom 重叠,则函数行为不确定。

     

  • 相关阅读:
    Curl Get请求&漏参数
    【Java基础】日期操作(返回当前日期&日期比较)
    【Java基础】生产者消费者模式
    [Groovy] 在Groovy中优雅的实现do while
    【转载】时间复杂度的度量
    [转载]Spring Cloud初探
    [Maven] 使用Maven管理多模块项目
    JS基础三
    JS基础部分(二)
    笔记不详细记录了,学完css之后做出下面分布的导航页
  • 原文地址:https://www.cnblogs.com/limingluzhu/p/3028190.html
Copyright © 2020-2023  润新知