数据结构--顺序存储结构及抽象实现

顺序存储的定义:

线性表的顺序存储结构指的是用一段地址连续的存储单元依次存储线性表中的数据元素,例如原生数组。

设计思路:

利用一维数组来实现顺序存储结构。

存储空间:T* m_array;

当前长度:int m_length;

它继承自线性表抽象类List(见上一篇)。

下面分析线性表的增删改查等功能。

一、插入元素

1、判断目标位置是否合法

2、将目标位置及其之后的所有元素都挨个向后移动一个位置,因为数据是插入到当前位置上,原先的当然得挪开。

3、将新元素插入到目标位置

4、线性表长度加1

代码如下:

        bool insert(int i,const T& e)
        {
            bool ret = false;

            ret = (i >= 0) && (i <= m_length);//注意范围,可以等于m_length,因为可以头插和尾插。
            ret = ret && (m_length + 1 <= capacity());

            if(ret)
            {

                for(int j = m_length - 1; j >= i; j--)//元素移动
                {
                    m_array[j+1] = m_array[j];
                }
                m_array[i] = e;//插入

                m_length++;//长度加1
            }
            return ret;
        }


二、删除元素

1、判断目标位置是否合法

2、将目标位置后的所有元素前移一个位置

3、线性表长度减1

代码如下:

        bool remove(int i)
        {
            bool ret = (i >= 0) && (i < m_length);//检查范围

            if(ret)
            {
                for(int j = i; j < m_length - 1; j++)//向前移动
                {
                    m_array[j] = m_array[j+1];
                }

                m_length--;//长度减1
            }

            return ret;
        }

三、获取元素

1、判断目标位置是否合法

2、将目标位置作为数组下标获取元素

        bool get(int i, T& e) const  
        {
            bool ret = (i >= 0) && (i <= m_length);

            if(ret)
            {
                e = m_array[i];
            }

            return ret;
        }
程序有两个要点, 使用引用参数和const,函数返回类型是bool返回的是函数执行状态,所以不直接返回获取的元素值而利用引用返回获取的元素。用const的原因就是由于const成员函数的特性,不能修改普通成员变量的值,防止成员被意外修改。

四、设置元素

1、判断目标位置是否合法

2、设置目标位置元素的值

        bool set(int i, const T& e)//使用引用是防止无限制的拷贝构造下去
        {
            bool ret = (i >= 0) && (i < m_length);

            if(ret)
            {
                m_array[i] = e;//
            }

            return ret;

五、获取长度

程序实现中只需返回m_length即可。

六、清空线性表

程序实现只需将m_length置零即可。

七、获取最大容量

由于m_array可以指向不同区域的空间,并且长度也无法直接指定,所以我们将最大容量的获取设置在SeqList的子类中具体实现,由于SeqList并没有完全实现线性表的功能我们将其作为一个抽象类。

virtual int capacity() const = 0;

八、数组操作符重载

由于是泛型编程,所以T可能会是类类型,为了适应所有类型我们需要对数组访问操作符进行重载,我们将重载两个原型,const对象使用的和非const对象使用。

 T& operator[](int i)
        {
            if((i >= 0) && (i < m_length))
            {
                return m_array[i];
            }
            else
            {
               //抛出异常
            }
        }

        T  operator[](int i) const
        {
            return (const_cast<SeqList<T>&>(*this))[i];

        }

以上就是利用线性表的顺序存储结构实现的一个抽象类,我们可以实现静态线性表和动态线性表,而 两者又是同一级别,所以SeqList必须是抽象类供子类继承。

下面见完整类声明:

 template <typename T>
    class SeqList : public List<T>//类模板在外部使用都要带上类型
    {
    protected:
        T* m_array;//顺序存储空间
        int m_length;//当前表长

    public:
        bool insert(int i,const T& e);
        bool remove(int i);      
        bool set(int i, const T& e);     
        bool get(int i, T& e) const;     
        int length() const;       
        void clear();
        T& operator[](int i);
        T  operator[](int i) const;
        virtual int capacity() const = 0;
    };


下一篇开始就分别实现StaticList类和DynamicList类真正实现线性表并使用起来。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值