• 合并排序


    分治算法:

    用分治策略实现n个元素进行排序的方法。

    基本思想:

    将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终排好序的子集合合并成所要求的排好序的集合。

    源码:

    /*
     * mergeSort.cpp
     *  合并排序算法,算法导论P.17
     *  Created on: 2011-12-21
     *      Author: LiChanghai
     */
    //#include <iostream>
    #include <vector>
    #include <iostream>
    #include <iterator>
    using namespace std;
    #define FLT_MAX 1.0E38 //定义一个很大的值作为哨兵
    
    //对于待排序的数组 A[p...r], 其子数组A[p...q],A[q+1...r]已排好序
    //函数 subMerge(A, p, q, r), 将两个已排好序的子数组A[p...q],A[q+1...r]
    //合并成一个有序的数组代替当前的数组A[p...r]
    template<typename T>
    void subMerge(vector<T> &array,
                             typename vector<T>::iterator iterBegin,
                             typename vector<T>::iterator iterBarrier,
                             typename vector<T>::iterator iterEnd)
    {
        //创建两个数组,分别存放以iterBarrier为界线的array的左边部分和右边部分
        vector<T> arrayLeft(iterBegin, iterBarrier+1);
        vector<T> arrayRight(iterBarrier+1, iterEnd);
    
        //在两个数组尾部分别放一个“哨兵”
        T temp = T(FLT_MAX);
        arrayLeft.push_back(temp);
        arrayRight.push_back(temp);
    
        //定义分别指向两个数组的迭代器
        typename vector<T>::iterator iterLeft = arrayLeft.begin();
        typename vector<T>::iterator iterRight = arrayRight.begin();
    
        //定义指向原数组array的迭代器
        typename vector<T>::iterator iterArray = iterBegin;
    
        for(; iterArray != iterEnd; ++iterArray)
            if(*iterLeft < *iterRight) //如果左边小,将左边的值放入原数组
            {
                *iterArray = *iterLeft;
                ++iterLeft;
            }
            else //如果右边小,将右边的值放入原数组
            {
                *iterArray = *iterRight;
                ++iterRight;
            }
        return;
    }
    
    //函数 mergeSort(A, p, r) 调用subMerge对任意数组排序,p, r为下标
    //mergeSort(A, p, r)首先将数组A分为两部分
    //然后递归调用其本身对这两部分 分别排序
    //依次递归下去,直到只剩2个数的时候完成这两个数的排序
    //然后再层层返回调用处,将已排好序的子序列合并成更大的有序序列
    //最后一次调用subMerge时完成数组的排序
    template<typename T>
    void mergeSort(vector<T> &vec,
                             typename vector<T>::iterator iterHead,
                             typename vector<T>::iterator iterTail)
    {
    
        //测试 mergeSort 调用了多少次
        //static int times_mergeSort=0;
        //cout<<"the "<<++times_mergeSort<<" call mergeSort()"<<endl;
    
        //测试 subMerge 调用了多少次
        //static int times_subMerge=0;
    
        if(iterHead < iterTail-1)
        {
            //数组长度的一半(错误的方法)
            //typename vector<T>::size_type halfLength = (vec.size()-1)/2;
    
            //数组长度的一半(正确方法)
            typename vector<T>::difference_type halfLength=( (iterTail-iterHead)-1)/2;
    
            //定义一个迭代器指向数组 vec 中间位置
            typename vector<T>::iterator iterDivide = iterHead + halfLength;
    
            mergeSort(vec, iterHead, iterDivide+1); //递归调用自身对前半段排序
            mergeSort(vec, iterDivide+1, iterTail); //递归调用自身对后半段排序
            //cout<<"the "<<++times_subMerge<<" call subMerge()"<<endl;
            subMerge(vec, iterHead, iterDivide, iterTail); //将上面排好序的两段合并
        }
        return;
    
    }
    int main()
    {
        
        vector<int> vec;
        vec.push_back(0);
        vec.push_back(9);
        vec.push_back(8);
        vec.push_back(7);
        vec.push_back(6);
        vec.push_back(5);
        vec.push_back(4);
        vec.push_back(3);
        vec.push_back(2);
        vec.push_back(1);
        int size = vec.size();
        int *phead = &vec[0];
        int *ptail = &vec[size];
        mergeSort(vec,phead,ptail);
        for(int i=0;i<10;i++)
            cout<<vec[i]<<" ";
        cout<<endl;
        return 0;
    }

    运行结果:

  • 相关阅读:
    信息安全系统设计基础实验五报告
    实验六报告
    实验五报告
    第六周学习总结
    实验四
    第五周学习总结
    第四周学习总结
    实验三报告
    《数据结构与面向对象程序设计》第二、三周学习总结
    20182319《数据结构与面向对象程序设计》实验二报告
  • 原文地址:https://www.cnblogs.com/xing901022/p/2725185.html
Copyright © 2020-2023  润新知