顺序表中删除方法中的疑问

 

最近在看数据结构的时候发现顺序表的Delete()方法与我想的不一样所以就测试了一下,貌似是编程人员的疏忽导致了错误。

在网上又查找了一些资料,大部分都是同样的错。

 

 

 

public interface IListDS<T>
    {
        int GetLength();                //求长度
        void Clear();                   //清空操作
        bool IsEmpty();                 //判断线性表是否为空
        void Append(T item);            //附加操作
        void Insert(T item, int i);     //插入操作
        T Delete(int i);                //删除操作
        T GetElem(int i);               //取表元
        int Locate(T value);            //按值查找
    }


    public class SeqList<T> : IListDS<T>
    {
        private int maxsize;            //顺序表的容量
        private T[] data;               //数组,用于存储顺序表中的数据元素
        private int last;               //指示顺序表最后一个元素的位置

        //索引器
        public T this[int index]
        {
            get
            {
                return data[index];
            }
            set
            {
                data[index] = value;
            }
        }

        //最后一个元素位置位置属性
        public int Last
        {
            get
            {
                return last;
            }
        }

        //容量属性
        public int Maxsize
        {
            get
            {
                return maxsize;
            }
            set
            {
                maxsize = value;
            }
        }

        //构造器
        public SeqList(int size)
        {
            data = new T[size];
            maxsize = size;
            last = -1;
        }

        //求顺序表的长度
        public int GetLength()
        {
            return last + 1;
        }

        //清空顺序表
        public void Clear()
        {
            last = -1;
        }

        //判断顺序表是否为空
        public bool IsEmpty()
        {
            if (last == -1)
            {
                return true;
            }
            return false;
          
        }
       
        //判断顺序表是否已经满了
        public bool IsFull()
        {
            if (last == maxsize - 1)
            {
                return true;
            }

            return false;
        }

        //在顺序表的末尾添加新元素
        public void Append(T item)
        {
            if (IsFull())
            {
                Console.WriteLine("List is full");
                return;
            }
            data[++last] = item;
        }

        //在顺序表的第i个数据元素位置插入一个数据元素
        public void Insert(T item, int i)
        {
            if (IsFull())
            {
                Console.WriteLine("List is full");
                return;
            }
            else if(i<1||i>last+2)
            {
                Console.WriteLine("Position is erro");
                return;
            }
            else if (i == last + 2)
            {
                data[++last] = item;
            }
            else
            {
                for (int j = last; j >= i-1; j--)
                {
                    data[j + 1] = data[j];
                }
                data[i - 1] = item;
            }
            last++;
        }
       
        //删除顺序表的第i个元素   ———问题所在
        public T Delete(int i)
        {
            T temp = default(T);
            if (IsEmpty())
            {
                Console.WriteLine("List is empty");
                return temp;
            }
            if (i < 1 || i > last + 1)
            {
                Console.WriteLine("Positions is error");
                return temp;
            }
            if (i == last + 1)
            {
                temp = data[last--];                   //错误1
            }
            else
            {
                temp = data[i - 1];
                for (int j = i; j <= last; ++j)        //错误2
                {
                    data[j] = data[j + 1];
                }
            }

            --last;
            return temp;
        }

        //获取顺序表的第i个数据元素;
        public T GetElem(int i)
        {
            T temp = default(T);
            if (IsEmpty()||i<1||i>last+1)
            {
                Console.WriteLine("List is empty or Position is erro!");
                return temp;
            }
            return data[i - 1];
        }

        //在顺序表中查找值为value的数据元素
        public int Locate(T value)
        {
            if (IsEmpty())
            {
                Console.WriteLine("List is empty!");
                return -1;
            }

            int i = 0;
            for (i = 0; i <= last; i++)
            {
                if (value.Equals(data[i]))
                {
                    break;
                }
            }
            if (i > last)
            {
                return -1;
            }

            return i;
        }

    }

 

 

这里看Delete()函数

//删除顺序表的第i个元素   ———问题所在
        public T Delete(int i)
        {
            T temp = default(T);
            if (IsEmpty())
            {
                Console.WriteLine("List is empty");
                return temp;
            }
            if (i < 1 || i > last + 1)
            {
                Console.WriteLine("Positions is error");
                return temp;
            }
            if (i == last + 1)
            {
                temp = data[last--];                   //错误1
            }
            else
            {
                temp = data[i - 1];
                for (int j = i; j <= last; ++j)        //错误2
                {
                    data[j] = data[j + 1];
                }
            }

            --last;
            return temp;
        }

 

错误1:

在错误1处在返回值以后last已经自减 1 了(last--)

但是在倒数第二行代码中我们看到last又自减了一次 (--last)因为这次的自减不包含在任何条件语句中,所以当删除的是最后一个元素时,程序的流程是:

先进入

            if (i == last + 1)
            {
                temp = data[last--];                   
            }
然后跳过最后一个else语句直接执行最后两行代码

            --last;
            return temp;
这样就使得last 自减了两次。所以,但删除的是最后的一个元素时,返回的顺序表会比原始的少两个。

 

错误2:

            else
            {
                temp = data[i - 1];
                for (int j = i; j <= last; ++j)        //错误2
                {
                    data[j] = data[j + 1];
                }
            }

 

由 temp=date[i-1] 可以看出他返回的是data中坐标为i-1的元素,即data的第i个元素(因为data的坐标是从0开始的),这里是没有错的。

但是我们再看看接下来的代码

 

                for (int j = i; j <= last; ++j)        //错误2
                {
                    data[j] = data[j + 1];
                }
他只是把data的从第i个坐标后面的元素超前移了一个位子,这里是删除的data中坐标为i的元素, 而不是坐标为i-1的元素。显然,是编程人员在此处把data的第i个元素和坐标为i 的元素混淆了 。data的第i个元素是data坐标为i-1 的那个元素,因为data的坐标是从0开始。 坐标为i的data的元素,是data的第i+1个元素。

 

这个方法的正确形式应该是(修改方法有很多种这里只给出了其中的一种):

 

 //删除顺序表的第i个元素   

        public T Delete(int i)
        {
            T temp = default(T);
            if (IsEmpty())
            {
                Console.WriteLine("List is empty");
                return temp;
            }
            if (i < 1 || i > last + 1)
            {
                Console.WriteLine("Positions is error");
                return temp;
            }
            if (i == last + 1)
            {
                temp = data[i-1];
            }
            else
            {
                temp = data[i - 1];
                for (int j = i-1; j <= last; ++j)
                {
                    data[j] = data[j + 1];
                }
            }

            --last;
            return temp;
        }

 

 

测试用例(可以用以下代码测试两个Delete()方法):

 SeqList<int> testIlist = new SeqList<int>(5);
            for (int i = 1; i < 6; i++)
            {
                testIlist.Append(i);
            }
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("data第 i {0} 个元素为{1}", i + 1, testIlist[i]);
            }
            int temp=testIlist.Delete(5);

          //测试错误1 处的错误

            Console.WriteLine("删除最后一个元素后 testIlist中剩的元素个数{0},删除的元素为{1}", testIlist.GetLength(),temp);

            temp=testIlist.Delete(2);

          //测试错误2 处的错误
            Console.WriteLine("删除第2个元素, 删除的元素的值为 {0}",temp);
            Console.WriteLine("删除第2个元素后testIlist中的元素");
            for (int i = 0; i < testIlist.GetLength(); i++)
            {
                Console.WriteLine("di {0} ge yuan su wei {1}", i + 1, testIlist[i]);
            }

 

 

用以上代码可以很容易测试出他们的错误:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值