问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

java关于插入排序的问题,我写出来了,输出结果是对的,但是我写注释的时候分析了下应该结果是错的。。。

发布网友 发布时间:2022-05-15 10:04

我来回答

3个回答

热心网友 时间:2023-10-19 15:14

  首先从逻辑上看,楼主的插入排序跟原始的插入排序算法不太一样,但是达到了同样的目的。虽然计算次数没有像原始的插入优化的那么好。但是没有错误。


  先说,楼主如果写成for(int j=i;j<i+1;j++) 这样铁定是错的。

  你这样无论i为多少,这个循环只能运行一次。可以等价为for(int j=i;j<=i;j++) 。如果楼主希望j的初值是i的话,那么就写成for(int j=i;j>=0;j--)


  第二,楼主说到第0个元素没有被比较,是错误的。

  楼主的if中,判断的是array[i]与array[j-1]做比较。而外面for中j的范围是[1,i],而if中是j-1,那么array[j-1]的范围就是[0,i-1]。所以0是被做了比较的。同样的道理,楼主注释中说“只和相邻的元素进行了比较”,也可以用上面的思路解释了。


  随后说说算法优化问题。

  这个似乎不属于楼主提问的范围,没兴趣的话请无视

  常见的插入排序是这样的(摘自百度百科,词条:插入排序)

for(int i=1;i<arr.length;i++){
    for(int j=i;j>0;j--){
        if(arr[j]<arr[j-1]){
            //TODO:
            int temp=arr[j];
            arr[j]=arr[j-1];
            arr[j-1]=temp;
        }else{
            //接下来是无用功
            break;
        }
    }
}

  这里与楼主最大的不同就是它的j是倒叙,另外if之后有else和break

  具体我们用{1,2,3,5,6,7,4}这个数组来看下。

  当i<6时,楼主的代码,需要进行15次判断,而常见的只要进行5次。而在i=6时。原始的代码需要进行4次排序就可以完成任务,而楼主的需要进行6次。总数是21:9。

  至于break减少的判断的作用我就不提了。问题在于j的正序与倒序。对于4这个数,实际上没有意义去比较3之前的数字了,但若是正序,则需要从头开始寻找,所以有无用功的比较次数存在。

  如果这个数组比较特别,那我们换一个{4,5,1,8,2,9,3},结果是21:14。看到运算次数的差距了么



说了半天,废话比较多,希望对楼主有帮助

追问小数据来说,冒泡排序和选择排序,哪个效率高,我刚才测试了一个小数据,冒泡,选择次数都是22,插入是7.两个相同的是巧合吗?从效率上来看,冒泡是比较每一个相邻位置,找出最大的放在最后面,并且越到后面,比较的次数越少,选择排序是选择最小的位置,其他每一个都与其比较,小的放进去,也是越往后越少,二者的区别在哪里?

追答  http://blog.jobbole.com/68774/
  这个是之前在CSDN上转载的一篇写得很好的排序算法效率的测试评估报告。这个网页我找了好久(毕竟时间有点长),推荐去看下。有一点需要注意的是,报告中的运行测试环境是php不是java。php本身属于服务器解释型语言,他本身有一个sort函数,采用服务器本身的硬件来完成排序,这个个效率是逻辑性排序算法不能比拟的;像java这种编译型的语言不具备类似sort这种函数。除此之外,对于逻辑型排序算法的运行效率java和php是没有什么区别的

  先说小数据
  就报告中,小数据(1000以内)下冒泡排序以及其变种,效率都非常的低。而相对于冒泡,选择的效率则要高很多。

  其次是楼主做的那个测试。
  有巧合出现相同情况的几率。还以我之前用那个{4,5,1,8,2,9,3}为例,选择排序,循环运算次数21次,交换5次。冒泡排序,循环18次,交换9次。对于计算机运算来讲,比较要比交换要来的快得多,所以相比较之下,选择的速度要快

最后说说区别

冒泡只能和相邻的数字进行比较,虽然规则比较简单易懂,但是盲目性比较高。如果最小值处于最后一位,那么第一次循环,就要进行数组长度-1次交换和判断。而选择似乎比冒泡的代码要复杂些,但是在刚才那个条件中,只需要进行数组长度-1次的判断和1次的交换。目的性比冒泡要强的多,虽然比较次数不会少于冒泡。

热心网友 时间:2023-10-19 15:14

你说的是不是这个意思
for(int i=1;i<array.length;i++){
for(int j=1;j<i+1;j++){
if(array[j]<array[j-1]){
int temp=array[j];
array[j]=array[j-1];
array[j-1]=temp;
}
}
}
和之前比较不是for的问题, 是后面判断的问题, 你写的是if(array[i]<array[j-1]), 这个是不会一次性和之前的比较完的。 但如果if(array[j]<array[j-1])这样写, 不就是每次都比较了吗?
不知道我理解错你的意思没有追问用IF是不能完场插入排序的,后面要用while,插入排序还是很有意思的

追答我明白你的意思了 , while可能死掉, 还是用for 。 但嵌套3层循环有点那个啥了, 程序可以改进 ..... 后续跟进

热心网友 时间:2023-10-19 15:15

第二个条件改成for(int j=i;(j>0)&&(array[j]<array[j-1]);j--);
你写得这个方法像冒泡排序却又不是冒泡排序
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 LG最新款手机多少钱,比苹果还好,是真的吗 LG手机新款有哪些? LG最新款手机是??? 请用he、she、they、are各造一个一般疑问句,并且要回答和翻译,回答不用翻译,要快!谢谢 当今京剧小生泰斗叶少兰的亲爹是谁? what造疑问句 京剧名家叶盛兰之子叶少兰原名是叫叶鑫吗 京剧小宴叶少兰年龄 LG最新款手机是哪个? 叶少兰的介绍 叶少兰的介绍? 用am is are造句各造一个 再改为一般疑问句做出肯否回答 用have,has,分别造1个特殊疑问句,1个一般疑问句,1个肯定句,1个否定句! 怎么造一个设问句? 用this+baseball+your造一个疑问句? 西北农林科技大学义务支教心得 造个一般疑问句 组织结构的英文怎么写? 论文组织结构怎么写 104J63Vcbb电容坏了,可以用什么电容代替 关于戏曲名家叶盛兰的资料有哪些? LG手机最新款怎么样,好用吗 京剧资料卡名称发源地代表人物行当分类 叶盛兰是谁呢? LG又出新款手机了呢? 著名京剧表演名人故事 LG的最新款G2手机好用吗? 叶盛兰是京剧四大名旦之一吗? 怎么用a new friend造一个疑问句 LG是新出了一款智能手机? 朱福的人物档案 扬州有几家造纸厂?都在哪里?有没有联系方式? 河北省 衡水市附近有哪些造纸厂 具体在什么位置? 广安造纸厂的地址 南阳的卫生纸厂在哪里比较集中 联想yoga14s ARE是什么意思? 湖北十堰哪里有卫生纸厂(详细地址)? 丰谷酒王52度A20价格表 52度南阜酒王多少钱一箱? 千丰酒王48度白酒多少钱一瓶