新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 研友的交流园地,讨论关于计算机考研的方方面面。
    [返回] 计算机科学论坛计算机理论与工程『 计算机考研交流 』 → 数据结构教材第七章内排序的错误与改进 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 4196 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 数据结构教材第七章内排序的错误与改进 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     computerlover 帅哥哟,离线,有人找我吗?
      
      
      等级:大二期末(C++考了100分!)
      文章:59
      积分:330
      门派:XML.ORG.CN
      注册:2006/9/23

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给computerlover发送一个短消息 把computerlover加入好友 查看computerlover的个人资料 搜索computerlover在『 计算机考研交流 』 的所有贴子 引用回复这个贴子 回复这个贴子 查看computerlover的博客楼主
    发贴心情 数据结构教材第七章内排序的错误与改进

    关于对教材第七章算法7.15的改进

    关于第七章归并排序一节中的优化归并排序(算法7.15)
      我对这个算法有几个问题?

    1. 为什么不把DoSort( )函数的代码直接放到Sort( )函数里,而是在Sort( )函数外
    定义DoSort( )函数?在类 Class ImprovedTwoWayMergeSorter:public……里也没定义成员函数DoSort( )啊。我觉得把函数DoSort( )放在函数Sort( )的外面定义对理解递归显得不太清晰。

    2.  优化后的算法是不用像算法7.10(我认为此处应该是算法7.14)那样需要检查子序列是否结束. 但它增加了比较的次数. 算法7.14中当一个子序列的元素插入完后,另一个子序列中的元素直接插入到Array[]中,而不需要比较.
    例如 原序列为: 12 37 49 41 30 71 58 19 65 15
             先分为2个子序列
               (12  37  49  41  30)    (71  58  19  65  15)
              对 这两个子序列分别再分解,然后分别归并,
              归并后的序列为:
                (12 30 37 41 49)    (71 65 58 19 15)(颠倒过来后)
    在插入元素49后Array[] 为:12 15 19 30 37 41 49, 此时index1移动到元素71下, index2在元素58下,然后还得分别比较 71>58 和 71>65 和71>=71 (比较三次)来插入元素58  65  71, 在算法7.14中,此时左边子序列已空了,右边子序列的三个元素无需比较直接插入Array[]中就行了
    而且在数组大于16时才进行这种归并,当数据量很大时,这种额外的比较开销对算法的时间性能没有影响吗?   

    1. 为什么不把DoSort( )函数的代码直接放到Sort( )函数里

    答:这个早就勘误了的。不知道出版社为什么翻来覆去总搞错。


    2.  算法7.14与7.15的代价比较。

    答:

    比较算法7.14和7.15,首先,二者的赋值运算都是一样的,对于长度为n的待排序序列,merge一次则赋值2n次(一轮倒入临时数组为n次赋值,一轮每个值都从临时数组归并到位为n次赋值)

    不同的是比较次数;

    (1)在处理完一个子串之前

    算法7.14每次合并操作都有三个比较运算:

    while ((index1 <= middle)&&

                (index2 <= right))  

    和if (Compare::le(TempArray[index1], TempArray[index2]))

    而7.15在处理完一个子串之前,每次合并操作都只有一个比较运算if (Compare::le(TempArray[index1], TempArray[index2]))

    这里的运算代价显然7.14高于7.15

    (2)某一个子串处理完之后,
    算法7.14对每次合并操作都有一个比较运算,“while (index1 <= middle)”或“while (index2 <= right)”(二者取一)

    算法7.15对每次合并操作也有一个比较运算,if (Compare::le(TempArray[index1], TempArray[index2]))

    这里的运算代价7.14与7.15相同


    数排序算法中,P240的算法7.20有几处错误


    1. 在Sort()函数中的第一个for循环中,i从0到i<n,
    为什么先用for循环使Array[n-1]=i+1;
    再在下面加语句 Array[n-1]=-1; 为什么不把for循环中的循环
    条件改为i<n-1呢?


    1. 在Sort()函数中的第一个for循环中

    答:这里没有问题,不是错误!效果是等价的。赋初值的习惯不同而已,教材算法多赋一次初值。


    2. 学习指导的对习题7.2的解答也有问题.在解法一中:图解中对直接插入排序算法的交换次数没错,但二分插入排序(算法7.7)没有交换啊,只有TempRecord = Array[];和Arrat[] = TempRecord;两次赋值操作,而且是在每次外循环时都各执行一次,当然最后的for循环里移动的次数每次可能不同.但在解答中确也分比较和交换来分析就不对了吧,我感到在二分插入法中没有交换,只有移动,直接插入是交换(swap), 一次交换为三次赋值(移动).应该分为比较和移动来分析较合理. 解法二是正确的,而且与解法一是矛盾的.


    今年上网看到张老师对这些问题进行了回答,所以又重新编辑了此贴


    [此贴子已经被作者于2006-11-5 18:56:00编辑过]

       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    很爱计算机,但无人交流。苦恼…… 很爱写代码,但盗版软件不好用,代码正确但编译或连接通不过。恼火……

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/11/4 23:40:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 计算机考研交流 』 的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/21 14:35:00

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    3,187.500ms