关于插入排序的bug记录

应用场景:

使用插入排序对10个元素的一维数组进行升序排序。


问题描述

出现了元素丢失和排序不正确的情况
具体代码如下:

  int main(void)
  {
     int a[10] = {1,24,3,47,5,6,7,89,12,45};
     int i;
    for(i = 1 ; i < 10;++i)
     {
          if(a[i] < a[i - 1])
         {
            int t = a[i];
              int j = i - 1;
                  for(j = i - 1;a[j] > a[i] && j > 0;--j)
                 {
                     a[j] = a[j - 1];
                 }
                     a[j +1] = t;
          }       
      }
     for(int i = 0;i < 10;++i)
     {
         printf("%d ",a[i]);
     }
     printf("\n");
 }

 输出结果

1 3 3 5 5 6 7 12 12 45 

原因分析:

首先我们先看一个正确的选择插入的代码示例:

#include<stdio.h>
int main(void)
{
    int i = 0;
    int k = 0;
    int n = 0;
    int a[10] = {1,24,3,47,5,6,7,89,12,45};
    int len = sizeof(a)/sizeof(a[0]);
    for(i = 1;i < len;++i)
    {
         int temp = a[i];
         k = i - 1;
         while(k >=0 && a[k]>temp)
         {
             a[k + 1]=a[k];
             --k;
         }
         a[k + 1] = temp;    
    }
    for(n = 0;n < len;++n)
    {
        printf("%d ",a[n]);
    }
    printf("\n");
    return 0;
}

 输出结果为:

1 3 5 6 7 12 24 45 47 89

语句冗余

  int main(void)
  {
     int a[10] = {1,24,3,47,5,6,7,89,12,45};
     int i;
    for(i = 1 ; i < 10;++i)
     {
 7         if(a[i] < a[i - 1])//判断a[i] 和 a[i -1]大小
         {
            int t = a[i];
            int j = i - 1;//将 j 赋值为i - 1;
11            for(j = i - 1;a[j] > a[i] && j > 0;--j)//循环条件判断a[i] 和 a[j]
            {
                a[j] = a[j - 1];
            }
                a[j + 1] = t;
          }       
      }
     for(int i = 0;i < 10;++i)
     {
         printf("%d ",a[i]);
     }
     printf("\n");
 }

阅读代码可知,j = i - 1,那么11行代码a[i]与a[j]的比较可以等价为a[i] 和 a[i - 1]的比较,与4行的语句作用重复。因为插入排序要求进行a[i] 和 a [i - 1]多次比较,所以应该删除4行语句。

修改为:

  int main(void)
  {
     int a[10] = {1,24,3,47,5,6,7,89,12,45};
     int i;
    for(i = 1 ; i < 10;++i)
    {
          
       int t = a[i];
       int j = i - 1;
       for(j = i - 1;a[j] > a[i] && j > 0;--j)
       {
             a[j] = a[j - 1];
       }
             a[j +1] = t;
               
    }
    for(int i = 0;i < 10;++i)
    {
         printf("%d ",a[i]);
    }
    printf("\n");
 }

改变的对象错误

  int main(void)
  {
     int a[10] = {1,24,3,47,5,6,7,89,12,45};
     int i;
    for(i = 1 ; i < 10;++i)
    {
          
       int t = a[i];
       int j = i - 1;
       for(j = i - 1;a[j] > a[i] && j > 0;--j)//循环条件判断a[i] 和 a[j]
       {
             a[j] = a[j - 1];   //如果a[j] > a[i],将 a[j - 1]赋值给a[j]
       }
             a[j + 1] = t;
               
    }
    for(int i = 0;i < 10;++i)
    {
         printf("%d ",a[i]);
    }
    printf("\n");
 }

这里是一个明显的逻辑错误,对 a[i] 与 a[j] 进行比较,最后却将 a[j - 1] 的值赋值给 a[j]。

相当于比较a[i] 和a[i - 1],a[i - 1]赋值为a[ i - 2]。插入排序要求我们两个数值进行比较,将大值赋值给位号大的那一个。根据判断条件来看,我们对于a[ i -2]的情况是未知的(不清楚a[i -2] 和 a[ i -1]的大小关系),因此这种赋值是不恰当的。

修改为

  int main(void)
  {
     int a[10] = {1,24,3,47,5,6,7,89,12,45};
     int i;
    for(i = 1 ; i < 10;++i)
    {
          
       int t = a[i];
       int j = i - 1;
       for(j = i - 1;a[j] > a[i] && j > 0;--j)//循环条件判断a[i] 和 a[j]
       {
             a[j + 1] = a[j];   //如果a[j] > a[i],将 a[j]赋值给a[j + 1]
                                //  即赋值给a[i]
       }
             a[j + 1] = t;
               
    }
    for(int i = 0;i < 10;++i)
    {
         printf("%d ",a[i]);
    }
    printf("\n");
 }

比较的对象错误

  int main(void)
  {
     int a[10] = {1,24,3,47,5,6,7,89,12,45};
     int i;
    for(i = 1 ; i < 10;++i)
    {
          
       int t = a[i];
       int j = i - 1;
       for(j = i - 1;a[j] > a[i] && j > 0;--j)//循环条件判断a[i] 和 a[j]
       {
             a[j + 1] = a[j];   //如果a[j] > a[i],将 a[j]赋值给a[j + 1]
                                //  即赋值给a[i]
       }
             a[j + 1] = t;
               
    }
    for(int i = 0;i < 10;++i)
    {
         printf("%d ",a[i]);
    }
    printf("\n");
 }

再上一轮修改后,可以发现,a[i] 的值被改变。在第一轮循环后,循环条件变成了a[ j ]和被改变后的a[i]的比较。然而选择插入的思想是将希望被排序的元素temp与a[i]之前的元素作比较,为temp选择一个适合的位置将其插入。第一次循环后,a[i] 的值为 temp和a[j]二者比较中的较大值,因此我们无法保障始终进行的是temp和a[i]前面的元素比较。

  int main(void)
  {
     int a[10] = {1,24,3,47,5,6,7,89,12,45};
     int i;
    for(i = 1 ; i < 10;++i)
    {
          
       int t = a[i];
       int j = i - 1;
       for(j = i - 1;a[j] > temp && j > 0;--j)//循环条件判断 temp 和 a[j]
       {
             a[j + 1] = a[j];   //如果a[j] > a[i],将 a[j]赋值给a[j + 1]
                                //  即赋值给a[i]
       }
             a[j + 1] = t;
               
    }
    for(int i = 0;i < 10;++i)
    {
         printf("%d ",a[i]);
    }
    printf("\n");
 }

 阅读代码没有其他错误,进行编译检验。


解决方案:

修改后的代码:

  int main(void)
  {
     int a[10] = {1,24,3,47,5,6,7,89,12,45};
     int i;
    for(i = 1 ; i < 10;++i)
     {
            int t = a[i];
            int j = i - 1;
            for(j = i - 1;a[j] > t && j > 0;--j)
            {
                 a[j + 1] = a[j ];
            }
             a[j +1] = t;    
      }
     for(int i = 0;i < 10;++i)
     {
         printf("%d ",a[i]);
     }
     printf("\n");
 }

运行结果

1 3 5 6 7 12 24 45 47 89

结果正确。

  • 29
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
bug 记录是一种软件开发中常用的方法,用来记录程序中出现的错误或者异常情况。它是软件测试的重要环节,有助于开发人员更好地追踪和解决bug,同时也方便团队间的沟通和协作。 在Word末班的情况下,bug记录可以被用来记录Word应用程序中出现的各种错误和问题。这些问题可能是功能缺陷、用户界面问题、性能问题等。通过记录这些bug,可以帮助开发人员准确定位问题,并提供修复的指导和参考。 一个有效的bug记录通常包括以下几个主要方面: 1. 问题描述:详细描述bug的具体表现和出现的环境条件,以便开发人员能够复现该问题。 2. 问题重现步骤:提供重现该bug的详细步骤,让开发人员可以按照这些步骤来定位和修复问题。 3. 优先级和严重程度:对bug进行分类,分别给出优先级和严重程度,以帮助开发人员优先解决重要且影响较大的问题。 4. 日志和截图:提供相关的日志记录和截图,以便开发人员更好地理解问题和进行调试。 5. 解决方案或修复建议:如果可以,尽量提供对该bug的解决方案或修复建议,这样可以帮助开发人员更快地解决问题。 此外,一个好的bug记录系统对于跟踪和管理bug也非常重要。团队成员可以通过该系统中的与bug相关的字段,例如状态、指派人等,了解bug的当前状态和处理进度。这样团队内部可以更加高效地分工合作,从而提高整体的开发效率。 综上所述,bug记录在软件开发中是十分重要的一环,它对于发现、修复和追踪问题起到了关键的作用。在Word末班中,通过良好的bug记录和有效的协作,可以帮助开发团队更好地完善和提升Word应用的质量和用户体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值