单链表模板类

单链表模板类

  • List.h 接口类
  • LinkList.h 单链表类

在单链表中必然需要定义一个头节点来指向链表的第一个元素,

struct Node :public Object
{
     T value;
     Node* next;
 };
mutable Node m_header;

这样直接定义会有一个问题,头节点的构造会调用T类的构造函数,这显然时不需要的,解决方案如下:

 mutable struct : public Object
 {
      char reserved[sizeof (T)];
      Node* next;
  }m_header;

//List.h
template <typename  T>
    class List 
    {
    protected:
        List(const List& );                             //链表不允许进行拷贝构造
        List& operator = (const List&);                 //链表不允许进行复制操作
    public:
        List(){}

        virtual  bool insert(const T& e)=0;
        virtual  bool insert(int i, const T& e)=0;
        virtual  bool remove(int i)=0;
        virtual  bool set(int i, const T& e)=0;
        virtual  bool get(int i, T& e)const =0;
        virtual  int find(const T& e) const =0;
        virtual  int length()const =0;
        virtual  void clear()=0;
    };
    template <typename T>
    class LinkList : public List<T>
    {
    protected:
        struct Node :public Object
        {
            T value;
            Node* next;
        };

        mutable struct : public Object
        {
            char reserved[sizeof (T)];
            Node* next;
        }m_header;

        // Node m_header;

        int m_length;
        int m_step;
        Node* m_current;

        Node* position(int i) const
        {
            Node* ret = reinterpret_cast<Node*>(&m_header);

            for(int p = 0; p < i; ++p)
            {
                ret = ret->next;
            }

            return ret;
        }

        virtual Node* create()
        {
            return new Node();
        }

        virtual void destroy(Node* pn)
        {
            delete pn;
        }

    public:
        LinkList()
        {
            m_header.next = NULL;
            m_length = 0;
            m_current = NULL;
            m_step = 0;
        }

        void push_back(const T& e)
        {
            insert(e);
        }

        void push_front(const T& e)
        {
            insert(0,e);
        }

        void pop_back()
        {
            remove(m_length - 1);
        }

        void pop_front()
        {
            remove(0);
        }

        T back() const
        {
            return get(m_length - 1);
        }

        T front() const
        {
            return get(0);
        }

        bool insert(const T& e)
        {
            return insert(m_length,e);
        }

        bool insert(int i, const T& e)
        {
            bool ret = (i >= 0) && (i <= m_length);
            if(ret)
            {
                Node* node = create();

                if(node != NULL)
                {
                    Node* currect = position(i);

                    node->value = e;
                    node->next = currect->next;
                    currect->next = node;
                    m_length++;
                }
                else
                {
                    THROW_EXCEPTION(NoEnoughtMemoryException,"No memory to insert new element ...");
                }
            }
            return ret;
        }

        bool remove(int i)
        {
            bool ret = (i < m_length) && (i >= 0);
            if(ret)
            {
                Node* currect = position(i);
                Node* toDel = currect->next;

                if(m_current == toDel)
                {
                    m_current = toDel->next;
                }

                currect->next = toDel->next;

                m_length--;
                destroy(toDel);
            }
            return ret;
        }

        bool set(int i, const T& e)
        {
            bool ret = (i < m_length) && (i >= 0);
            if(ret)
            {
                position(i)->next->value = e;
            }
            return ret;
        }

        virtual  T get(int i) const
        {
            T ret;
            if(get(i,ret))
            {
                return ret;
            }
            else
            {
                THROW_EXCEPTION(IndexOutOfBoundsException,"Invalid parameter i to get element ...");
            }
        }

        bool get(int i, T& e)const
        {
            bool ret = (i < m_length) && (i >= 0);
            if(ret)
            {
                e = position(i)->next->value;
            }
            return ret;
        }

        int find(const T& e) const
        {
            int ret = -1;
            int i = 0;
            Node * node = m_header.next;

            while(node)
            {
                if(node->value == e)
                {
                    ret = i;
                    break;
                }
                else
                {
                    node = node->next;
                    i++;
                }
            }
            return ret;
        }

        int length()const
        {
            return m_length;
        }

        void clear()
        {
            while(m_header.next)
            {
                Node* toDel = m_header.next;
                m_header.next = toDel->next;
                m_length--;
                destroy(toDel);
            }
        }

        virtual bool move(int i, int step = 1)
        {
            bool ret = (i >= 0) && (i < m_length) && (step > 0);
            if(ret)
            {
                m_current = position(i)->next;
                m_step = step;
            }

            return ret;
        }

        virtual bool next()
        {
            int i = 0;
            while ((i < m_step) && (!end()))
            {
                m_current = m_current->next;
                i++;
            }
            return (i == m_step);
        }

        virtual T current()
        {
            if( !end() )
            {
                return m_current->value;
            }
            else
            {
                THROW_EXCEPTION(InvalidParameterException,"No value at current position ...");
            }
        }

        virtual bool end()
        {
            return (m_current == NULL);
        }


        ~LinkList()
        {
            clear();
        }
    };
面向对象程序设计课程作业 1. 请创建一个数据类型为T的链表类模板List,实现以下成员函数: 1) 默认构造函数List(),将该链表初始化为一个空链表(10分) 2) 拷贝构造函数List(const List& list),根据一个给定的链表构造当前链表(10分) 3) 析构函数~List(),释放链表中的所有节点(10分) 4) Push_back(T e)函数,往链表最末尾插入一个元素为e的节点(10分) 5) operator<<()友元函数,将链表的所有元素按顺序输出(10分) 6) operator=()函数,实现两个链表的赋值操作(10分) 7) operator+()函数,实现两个链表的连接,A=B+C(10分) 2. 请编写main函数,测试该类模板的正确性: 1) 用List模板定义一个List类型的模板类对象int_listB,从键盘读入m个整数,调用Push_back函数将这m个整数依次插入到该链表中;(4分) 2) 用List模板定义一个List类型的模板类对象int_listC,从键盘读入n个整数,调用Push_back函数将这n个整数依次插入到该链表中;(4分) 3) 用List模板定义一个List类型的模板类对象int_listA,调用List的成员函数实现A = B + C;(4分) 4) 用cout直接输出int_listA的所有元素(3分) 5) 用List模板定义List类型的模板类对象double_listA, double_listB, double_listC,重复上述操作。(15分) 3. 输入输出样例: 1) 输入样例 4 12 23 34 45 3 56 67 78 3 1.2 2.3 3.4 4 4.5 5.6 6.7 7.8 2) 输出样例 12 23 34 45 56 67 78 1.2 2.3 3.4 4.5 5.6 6.7 7.8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值