| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2078 人关注过本帖
标题:想了很久很久,分治排序总是排不了序,请教
只看楼主 加入收藏
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:7 
想了很久很久,分治排序总是排不了序,请教
估计是递归那里出错,暂时搞不懂递归的逻辑,总之排序就和没排的一样
程序代码:
#include <iostream>
#include<vector>
#include<algorithm>
#include <iterator>
void mergesort(std::vector<int>&myarray,size_t l,size_t r);
void msort(std::vector<int>&myarray,size_t l,size_t m,size_t r)

 {
         size_t n1=m-l+1;
         size_t n2=r-m;
         std::vector<int>L(n1);
         std::vector<int>R(n2);
         for(size_t i=0;i<n1;++i)
         {
             L[i]=myarray[i];//std::cout<<L[i]<<std::endl;
         }
          for(size_t i=1;i<n2;++i)
         {
             R[i]=myarray[i+m];//std::cout<<R[i]<<std::endl;
         }
         /**< 小黄和大绿,小黄的第一个元素是否小于大绿的第一个元素 ,小于的话就把该元素放在总桶的第一个,
         比较小黄的第二个和大黄的第一个比较*/

         for(size_t k=l,i=0,j=1;k<r;++k)
         {
              if(R[j]<L[i])
                 {
                myarray[k]=R[j];
                j+=1;
                 }
              else
                {myarray[k]=L[i];
                i+=1;}
                }


    }
         void mergesort(std::vector<int>&myarray,size_t l,size_t r)
         {
             if(l>r)
             {  size_t m=(l+r)/2;
             mergesort(myarray,l,m);//递归这是跟着算法导论的伪代码敲的,一层递归我还是能理解的,双层递归现在理解起来有点难
             mergesort(myarray,m+1,r);
             msort(myarray,l,m,r);}
         }
int main()
{
  std::vector<int>myarray{1,3,5,7,9,2,4,6,8};
  // msort(myarray,0,(myarray.size()/2),myarray.size());
   mergesort(myarray,0,myarray.size());
   for(std::vector<int>::size_type i=0;i<myarray.size();++i)
           {
               std::cout<<myarray.at(i)<<std::endl;
           }

}

搜索更多相关主题的帖子: std int vector 递归 排序 
2020-04-05 16:18
雪影辰风
Rank: 6Rank: 6
来 自:衡阳市
等 级:贵宾
威 望:22
帖 子:177
专家分:387
注 册:2019-6-17
收藏
得分:10 
STL容器我不是很会用,所以跟你讲讲原理吧……

分治排序的原理就是,把一个大问题不断分解成小问题
这里你的算法应该是二分(也就是每次分解成两个小问题实现)
比如说我有如下几个数需要排序:1,3,5,7,9,2,4,6,8
然后我们进行问题分解,求出数集的中间元素也就是下标最靠中的那个(偶数的话会有两个结果,取左取右都可以),也就是9,记录下标是4(注意下标从0开始),则左边有一个区间下标0-3,右边5-8(这里大致讲个原理,实际我也不知道,因为你的代码用了STL,我看不懂,不好意思)然后进行两次递归
第一次:1,3,5,7 求出数集的中间元素也就是下标最靠中的那个,也就是3(根据习惯取值,这里取左值),记录下标是1(注意下标从0开始),则左边有一个区间下标0-0,右边2-3
    然后再次递归左区间,和右区间,如此循环往复
第二次:2,4,6,8 求出数集的中间元素也就是下标最靠中的那个,也就是4(根据习惯取值,这里取左值),记录下标是6(注意下标从0开始),则左边有一个区间下标5-5,右边7-8
    然后再次递归左区间,和右区间,如此循环往复

【大致就是这个原理,肯可能有点绕,看不懂我再想办法吧……】
2020-04-05 17:33
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
收藏
得分:0 
谢谢,已经很好了,我马上用c语法翻译一遍,不行呀,Windows上不能动态的写数组长度
比如
int n;
int a[n];
这样是不可以的,还是需要用vector写
还是手机端的IDE强大


[此贴子已经被作者于2020-4-5 17:42编辑过]


把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2020-04-05 17:37
雪影辰风
Rank: 6Rank: 6
来 自:衡阳市
等 级:贵宾
威 望:22
帖 子:177
专家分:387
注 册:2019-6-17
收藏
得分:0 
回复 3楼 叶纤
C/C++是可以动态申请空间的
int* arrow;
arrow=new int[数组大小]
2020-04-05 17:46
雪影辰风
Rank: 6Rank: 6
来 自:衡阳市
等 级:贵宾
威 望:22
帖 子:177
专家分:387
注 册:2019-6-17
收藏
得分:0 
清除直接用delete[] arrow
2020-04-05 17:47
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
收藏
得分:0 
我基础知识太薄弱了,我还是想一个不用递归的解法吧

把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2020-04-05 18:18
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:10 
主要是归并问题,修改后代码如下(有注释):
程序代码:
#include <iostream>
#include<vector>
#include<algorithm>
#include <iterator>
void mergesort(std::vector<int>&myarray, size_t l, size_t r);
void msort(std::vector<int>&myarray, size_t l, size_t m, size_t r)
{//归并算法有误,这样写可以完成归并。也可以原地归并,用插入方法,这样做速度很慢,等同于O(n^2)的排序速度,我试验过。
    size_t i, j;
    std::vector<int> a;
    for (i = l, j = m + 1; i <= m && j <= r; )
    {
        if (myarray[i] < myarray[j])a.push_back(myarray[i++]);
        else a.push_back(myarray[j++]);
    }
    for(;i<=m;i++)a.push_back(myarray[i]);
    for(;j<=r;j++)a.push_back(myarray[j]);   //这三个for将原向量有序分段先归并到向量a中
    for (i = 0; i <a.size (); i++)myarray[i + l] = a[i];  //再从向量a中还原到原向量中
}
void mergesort(std::vector<int>&myarray, size_t l, size_t r)
{
    size_t m;
    if (r > l)  //这里判断条件是r>l执行递归,否则不执行
    {
        m = (l + r) / 2;
        mergesort(myarray, l, m);//递归这是跟着算法导论的伪代码敲的,一层递归我还是能理解的,双层递归现在理解起来有点难
        mergesort(myarray, m + 1, r);
        msort(myarray, l, m, r);
    }
}
int main()
{
    std::vector<int>myarray{ 1,3,5,7,9,2,4,6,8 };
    // msort(myarray,0,(myarray.size()/2),myarray.size());
    mergesort(myarray, 0, myarray.size()-1);   //这里传入的r是长度-1
    for (std::vector<int>::size_type i = 0; i < myarray.size(); ++i)
    {
        std::cout << myarray.at(i) << std::endl;
    }
}


[此贴子已经被作者于2020-4-5 23:08编辑过]


能编个毛线衣吗?
2020-04-05 22:36
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
收藏
得分:0 
谢谢大佬们的解答,确实是我归并那和执行条件那错了,大部分是根据算法书上的伪代码进行分析的,细节上不到位,感谢2楼和7楼的补充,

把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2020-04-06 11:17
快速回复:想了很久很久,分治排序总是排不了序,请教
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.041924 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved