双向链表与双向循环链表

10 阅读2分钟

双向链表

代码

// 定义双向链表的结点类型
struct Node {
  Node(int data=0)
       : data_(data), 
       next_(nullptr), 
       pre_(nullptr) 
  {}
  
  int data_;    // 数据域
  Node* next_;  // 指向下一个结点
  Node* pre_;   // 指向前一个结点
};

// 双向链表
class DoubleLink {
  public:
    DoubleLink() {
      head_ = new Node();
    }

    ~DoubleLink() {
      Node *p = head_;
      while (p != nullptr)
      {
        head_ = head_->next_;
        delete p;
        p = head_;
      }
      
    }
  public:
    // 头插法
    void InsertHead(int val) {
      Node* node = new Node(val);

      node->next_ = head_->next_;

      node->pre_ = head_;

      if (head_->next_ != nullptr) {
        // 不是空链表
        head_->next_->pre_ = node;
      }

      head_->next_ = node;
    }

    // 尾插法
    void InsertTail(int val) {
      Node* node = new Node(val);

      Node* p = head_;

      // 通过while循环,让p指向尾结点
      while (p->next_ != nullptr)
      {
        p = p->next_;
      }

      p->next_ = node;
      node->pre_ = p;
      
    }

    // 结点删除
    void Remove(int val) {
      Node* p = head_->next_;

      while (p != nullptr)
      {
        if (p->data_ == val) {
          // 删除p指向的结点
          if (p->next_ != nullptr) {
            p->next_->pre_ = p->pre_;
          }
          p->pre_->next_ = p->next_;
          // 删除所有的值为val的数据
          Node* next = p->next_;
          delete p;
          p = next;
        } else {
            p = p->next_;
          }
      }
      
    }

    // 结点搜索
    bool Find(int val) {
      Node* p = head_->next_;
      while (p != nullptr) 
      {
        if (p->data_ == val) {
          return true;
        }
        p = p->next_;
      }
      
      return false;

    }

    // 链表结点输出函数
    void Show() {
      Node* p = head_->next_;

      while (p != nullptr)
      {
        cout << p->data_ << " ";
        p = p->next_;
      }

      cout << endl;
      
    }

  private:
    Node* head_;  // 指向头节点
};

测试

int main() {
  DoubleLink dlink;
  dlink.InsertTail(22);
  dlink.InsertTail(12);
  dlink.InsertTail(45);
  dlink.InsertTail(45);
  dlink.InsertTail(67);
  dlink.InsertTail(67);
  
  dlink.Show();

  dlink.InsertHead(34);
  dlink.InsertHead(367);

  dlink.Show();

  dlink.Remove(45);
  dlink.Show();

  cout << dlink.Find(367) << endl;

  return 0;
}

测试输出结果

➜  build git:(main) ✗ ./doubleLink   
22 12 45 45 67 67 
367 34 22 12 45 45 67 67 
367 34 22 12 67 67 
1

双向循环链表

代码

// 定义双向链表的结点类型
struct Node {
  Node(int data=0)
       : data_(data), 
       next_(nullptr), 
       pre_(nullptr) 
  {}
  
  int data_;    // 数据域
  Node* next_;  // 指向下一个结点
  Node* pre_;   // 指向前一个结点
};

// 双向循环链表
class DoubleCircleLink {
  public:
    DoubleCircleLink() {
      // 初始化时候head_的pre_和next_指向自己
      head_ = new Node();
      head_->pre_ = head_;
      head_->next_ = head_;
    }

    ~DoubleCircleLink() {
      Node *p = head_->next_;
      while (p != head_)
      {
        // 一直删除第一个结点
        head_->next_ = p->next_;
        p->next_->pre_ = head_;
        delete p;
        p = head_->next_;
      }

      delete head_;
      head_ = nullptr;
      
    }
  public:
    // 头插法
    void InsertHead(int val) {
      Node* node = new Node(val);

      node->next_ = head_->next_;

      node->pre_ = head_;

      head_->next_->pre_ = node;

      head_->next_ = node;
    }

    // 尾插法
    void InsertTail(int val) {
      Node* node = new Node(val);

      // 尾结点
      Node* p = head_->pre_;


      node->pre_ = p;

      p->next_ = node;
      node->next_ = head_;
      head_->pre_ = node;
      
      
    }

    // 结点删除
    void Remove(int val) {
      Node* p = head_->next_;

      while (p != head_)
      {
        if (p->data_ == val) {
          // 删除p指向的结点
          p->pre_->next_ = p->next_;
          p->next_->pre_ = p->pre_;
          // 删除所有的值为val的数据
          Node* next = p->next_;
          delete p;
          p = next;
        } else {
            p = p->next_;
          }
      }
      
    }

    // 结点搜索
    bool Find(int val) {
      Node* p = head_->next_;
      while (p != head_) 
      {
        if (p->data_ == val) {
          return true;
        }
        p = p->next_;
      }
      
      return false;

    }

    // 链表结点输出函数
    void Show() {
      Node* p = head_->next_;

      while (p != head_)
      {
        cout << p->data_ << " ";
        p = p->next_;
      }

      cout << endl;
      
    }

  private:
    Node* head_;  // 指向头节点
};

测试

int main() {
  DoubleCircleLink dlink;
  dlink.InsertTail(22);
  dlink.InsertTail(12);
  dlink.InsertTail(45);
  dlink.InsertTail(45);
  dlink.InsertTail(67);
  dlink.InsertTail(67);
  
  dlink.Show();

  dlink.InsertHead(34);
  dlink.InsertHead(367);

  dlink.Show();

  dlink.Remove(45);
  dlink.Show();

  cout << dlink.Find(367) << endl;

  return 0;
}

测试输出结果

➜  build git:(main) ✗ ./DoubleCircleLink 
22 12 45 45 67 67 
367 34 22 12 45 45 67 67 
367 34 22 12 67 67 
1