zoukankan      html  css  js  c++  java
  • 归并排序

    归并排序思路:就是将数组拆成一个个有序的数组,然后再合并有序数组的过程。

    最开始数组中有序数组怎么找到? 像插入排序一样,将一个元素看成一个有序的数组,所以,归并就是先将数组分为一个个的元素,再合并起来。

    举个例子:4 7 3 2 5 6 1

    先递归到最深处

    4 7 调用函数Sort将这两个数组合并起来     :4 7

    3 2 调用函数Sort将这个两个数合并起来     :2  3

    然后返回上一层将这两个数组  4 7 和 2 3   合并起来  :2 3 4 7

    5 6 调用函数Sort将这个两个数合并起来   :5  6

    1 直接返回。

    返回上一层将这两个数组    5 6 和 1     合并起来    :1 5 6

    返回上一层将   2 3 4 7 和  1 5 6合并起来    :1 2 3 4 5 6 7

    代码:

    void Sort(int* arr,int low,int high)//把两个数组归并起来
    {
        int mid = low + (high-low)/2;
        int flag = low;
        int* tmp = (int*)malloc(sizeof(int)*(high-low+1));
        int id = 0;
    
        int j = mid+1;
        while(low <= mid && j <= high)
        {
            if(arr[low] <= arr[j])
            {
                tmp[id++] = arr[low];
                low++;
            }
            else
            {
                tmp[id++] = arr[j];
                j++;
            }
        }
        while(low <= mid)//前面的还有值
        {
                tmp[id++] = arr[low++];
        }
        while(j <= high)//后面的还有值
        {
                tmp[id++] = arr[j++];
        }
        for(int i = 0;i < high-flag+1;i++)
        {
            arr[flag+i] = tmp[i];
        }
    
        free (tmp);
        tmp = NULL;
    }
    void MergeSort(int* arr,int low,int high)
    {
        if(arr == NULL || low >= high) return;
        int mid = low+(high-low)/2;
        //先拆分
        MergeSort(arr,low,mid);
        MergeSort(arr,mid+1,high);
        //再合并
        Sort(arr,low,high);
    }

     多路归并:

    void MergeSort(int*arr, int nbegin,int nend,int n)
    {
        int* flag = new int[n];
        int length = nend - nbegin+1;
        for(int i = 0; i < n;i++)//每一路的开始下标
            flag[i] = nbegin + length*i/n;
        int* tmp = new int[length];
        int id = 0;
        vector<int> vec;
        for(int i = 0; i < n; i++)
            vec.push_back(arr[flag[i]]);
        int cnt = n;
        while(cnt && vec.size() >= n)
        {
            push_heap(vec.begin(),vec.end(),greater<int>());//小根堆
            tmp[id++] = vec[0];
            for(int i = 0; i < n;i++)
            {
                if(flag[i] == -1)
                {
    
                    continue;
                }
                if(vec[0] == arr[flag[i]])
               {
    
                  pop_heap(vec.begin(),vec.end(),greater<int>());//小根堆
                  vec.pop_back();
                  flag[i] = flag[i] + 1;
                  if(flag[i] <= nbegin + length*(i+1)/n-1)//将标记向下移
                  {
                      vec.push_back(arr[flag[i]]);
                  }
                  else//结束一路
                  {
                      flag[i] = -1;
                      cnt--;
                  }
                    break;
               }
            }
        }
        for(int i = 0; i < vec.size();i++)//根已经放过了
        {
             tmp[id++] = vec[i];
        }
    
        for(int i =0; i < id;i++ )//放回原数组
            arr[nbegin+i] = tmp[i];
        delete[] tmp;
        delete[] flag;
    
    }
  • 相关阅读:
    Fix RICHTX32.OCX Issue on Windows 7
    Solved: c:\windows\system32\config\systemprofile\desktop
    递归的现实应用
    Win 8 app 获取窗口的宽度和高度, 本地化, 及文本读取
    均匀设计U Star 665
    GridView.ScrollIntoView() doesn't work
    XML节点访问与更新
    Keyboard supports in Software Testing
    WordPress程序备受喜爱的原因:十八般武艺
    paypal注册教程(PP注册教程)paypal使用方法
  • 原文地址:https://www.cnblogs.com/Lune-Qiu/p/9116169.html
Copyright © 2011-2022 走看看