【指针】基于双向链表的list

Description:

请实现以下基于双向链表的list类

enum Error_code

{

         success,

         underflow,

         overflow

};

 

template <class List_entry>

struct Node

{

         List_entry entry;

         Node<List_entry> *next;

         Node<List_entry> *back;

};

 

template <class List_entry>

class MyList

{

public:

         MyList();

         ~MyList();

         // 拷贝构造函数和赋值运算符重载,注意深拷贝与浅拷贝的差异

         MyList(const MyList<List_entry> &copy);

         void operator =(const MyList<List_entry> &copy);

 

         // 清空list

         void clear();

         // 判断list是否为空

         bool empty() const;

         // 判断list是否已满

         bool full() const;

         // 获取list的元素数量

         int size() const;

         // 在第position个位置插入值为entry的元素,如果position为0则插入在链表头,依次类推

         // 若position < 0 或者 position > count,则返回underflow

         Error_code insert(int position, const List_entry &entry);

         // 删除第position个位置的元素,并将该元素的值保存在entry中

         // 若position < 0 或者 position >= count,则返回underflow

         Error_code remove(int position, List_entry &entry);

         // 获取第position个位置的元素,保存在entry中

         // 若position < 0 或者 position >= count,则返回underflow

         Error_code retrieve(int position, List_entry &entry) const;

         // 将第position个位置的元素替换为entry

         // 若position < 0 或者 position >= count,则返回underflow

         Error_code replace(int position, const List_entry &entry);

         // 用visit函数遍历list内所有的元素

         void traverse(void (*visit)(List_entry &));

 

protected:

         int count;                                                                          // 记录list内元素数量

         mutable int curPosition;                                   // current指针的位置编号

         mutable Node<List_entry> *current;                 // current指针

 

         // 设置current指针的位置,指向第position个位置

         void setPosition(int position) const;

};
View Code

 


 

解题思路:

上一篇http://www.cnblogs.com/zengyh-1900/p/4067679.html讲到,

在处理基于单向链表的list时,在list中始终保持空队头的方法来避免出现非法访问内存地址的问题。

这里,我们探讨更为复杂的双向链表,原本,在队尾队头插入时都需要特殊判断,

但如果在队列中始终有一个空队头和空队尾,那么在队列中增加元素永远只有一种情况:

那么你就可以放心地,直接更新前节点的next,后节点的back以及新节点的这两个指针;

删除也类似:

 

(注意!curPosition的初始值为-1哦!)

实现代码:

 

enum Error_code
{
    success,
    underflow,
    overflow
};

template<class List_entry>
struct Node
{
    List_entry entry;
    Node<List_entry>* next;
    Node<List_entry>* back;
};

template<class List_entry>
class MyList
{
public:
    MyList() {
      curPosition= -1;
      count = 0;
      current = new Node<List_entry>;
      current->next = new Node<List_entry>;
      current->back = 0;
      current->next->next = 0;
      current->next->back = current;
    }

    ~MyList() {
      clear();
      Node<List_entry>* tmp = current->next;
      delete tmp;
      delete current;
      count = curPosition  = 0;
      current = 0;
    }

    MyList(const MyList<List_entry> &copy){
      curPosition= -1;
      count = 0;
      current = new Node<List_entry>;
      current->next = new Node<List_entry>;
      current->back = 0;
      current->next->next = 0;
      current->next->back = current;
      *this = copy;
    }

    void operator=(const MyList<List_entry>& copy){
      clear();
      List_entry entry;
      while (count < copy.size()) {
        copy.retrieve(count, entry);
        insert(count, entry);
      }
      setPosition(copy.curPosition);
    }

    void clear() {
      List_entry entry;
      while (size()) {
        remove(count-1, entry); 
      }
    }

    bool empty() const {
      if (count) return false;
      else return true;
    }

    bool full() const {
      return false;
    }

    int size() const {
      return count;
    }

    Error_code insert(int position, const List_entry &entry) {
      if (position < 0 || position > count) return underflow;
      else
       {
         Node<List_entry>* tmp = new Node<List_entry>;
         tmp->entry = entry;
         setPosition(position-1);
         tmp->back = current;
         tmp->next = current->next;
         current->next = tmp;
         tmp->next->back = tmp;
         current = tmp;
         curPosition++;
         count++;
         return success;
       }
    }

    Error_code remove(int position, List_entry &entry) {
      if (position < 0 || position >= count) return underflow;
      else 
        {
          setPosition(position);
          Node<List_entry>* tmp = current;
          entry = current->entry;
          current->back->next = current->next;
          current->next->back = current->back;
          current = current->next;
          delete tmp;
          count--;
          return success;
        }
    }

    Error_code retrieve(int position, List_entry &entry) const {
      if (position < 0 ||  position >= count)
        return underflow;
      else
         {
        setPosition(position);
        entry = current->entry;
        return success;
         }
    }

    Error_code replace(int position, const List_entry &entry) {
      if (position < 0 || position >= count) return underflow;
      else 
        {
          setPosition(position);
          current->entry = entry;
          return success;
        }

    }

    void traverse(void(*visit)(List_entry&)) {
      for (int i = 0; i < size(); i++) {
          setPosition(i);
          (*visit)(current->entry);
      }
    }
protected:
    int count;
    mutable int curPosition;
    mutable Node<List_entry>* current;
    void setPosition(int position) const {
       if (position >= curPosition) {
        for (; curPosition < position; curPosition++)
             current = current->next;
        } else {
        for (; curPosition > position; curPosition--)
             current = current->back;
        }
        
        
    }
};

    
View Code

 

转载于:https://www.cnblogs.com/zengyh-1900/p/4067711.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值