C++实现双向链表

 更新时间:2020年05月25日 08:42:24   作者:adorable_  
这篇文章主要为大家详细介绍了C++实现双向链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++实现动态顺序表的具体代码,供大家参考,具体内容如下

List.h

#pragma once 
#include <stdio.h>
#include <iostream>
#include <assert.h>
using namespace std;

typedef int DataType;

struct ListNode
{
  ListNode* _next;   //存放下一个节点地址
  ListNode* _prev;     //存放上一个节点地址
  DataType _data;

  ListNode(DataType x)
    :_data(x)
    , _next(NULL)
    , _prev(NULL)
  {}
};

class List
{
  typedef ListNode Node;
public:
  List()
    :_head(new Node(DataType()))
  {
    _head->_next = _head;
    _head->_prev = _head;
  }

  List(const List& l)
    :_head(new Node(DataType()))
  {
    _head->_next = _head;
    _head->_prev = _head;
    Node* cur = l._head->_next;
    while (cur != l._head)
    {
      PushBack(cur->_data);
      cur = cur->_next;
    }
  }

  List& operator=(List& l)
  {
    if (this != &l)
    {
      swap(_head, l._head);
    }
    return *this;

  }

  ~List()
  {
    Node* cur = _head->_next;
    while (cur != _head)
    {
      Node* next = cur->_next;
      delete cur;
      cur = next;
    }
    delete _head;
    _head = NULL;
  }

  void Print() const
  {
    Node* cur = _head->_next;
    cout << "head->";
    while (cur != _head)
    {
      cout << cur->_data << "->";
      cur = cur->_next;
    }
    cout << endl;
    Node* tail = _head->_prev;
    while (tail != _head)
    {
      cout << tail->_data << "->";
      tail = tail->_prev;
    }
    cout << "head" << endl;
  }

  void PushBack(DataType x);
  void PushFront(DataType x);
  void PopBack();
  void PopFront();
  ListNode* Find(DataType x);
  void Insert(Node* pos, DataType x);
  void Erase(Node* pos);
private:
  Node* _head;
};


void List::PushBack(DataType x)
{
  Node* tail = _head->_prev;
  Node* new_node = new Node(x);
  tail->_next = new_node;
  new_node->_prev = tail;

  new_node->_next = _head;
  _head->_prev = new_node;
  //Insert(_head, x);
}

void List::PushFront(DataType x)
{
  Node* cur = _head->_next;
  Node* new_node = new Node(x);
  new_node->_next = cur;
  cur->_prev = new_node;

  new_node->_prev = _head;
  _head->_next = new_node;
  //Insert(_head->_next, x);
}

void List::PopBack()
{
  Node* to_delete = _head->_prev;
  Node* cur = to_delete->_prev;
  cur->_next = _head;
  _head->_prev = cur; 
  delete to_delete;
  //Erase(_head->_prev);
}

void List::PopFront()
{
  Node* to_delete = _head->_next;
  Node* cur = to_delete->_next;
  cur->_prev = _head;
  _head->_next = cur;
  delete to_delete;
  //Erase(_head->_next);
}

ListNode* List::Find(DataType x)
{
  Node* cur = _head->_next;
  while (cur != _head)
  {
    if (cur->_data == x)
    {
      return cur;
    }
    cur = cur->_next;
  }
  return NULL;
}

void List::Insert(Node* pos, DataType x)
{
  assert(pos);
  Node* prev = pos->_prev;
  Node* new_node = new Node(x);
  new_node->_next = pos;
  pos->_prev = new_node;

  prev->_next = new_node;
  new_node->_prev = prev;
}

void List::Erase(Node* pos)
{
  assert(pos);
  Node* prev = pos->_prev;
  Node* next = pos->_next;

  prev->_next = next;
  next->_prev = prev;
  delete pos;
}

void TestList()
{
  List l;
  l.PushBack(1);
  l.PushBack(2);
  l.PushBack(3);
  l.PushBack(4);
  l.PopBack();
  l.Print();
  ListNode* pos = l.Find(2);
  printf("pos->_data expext 2, actual %d:[%p]\n", pos->_data, pos);
  pos = l.Find(4);
  printf("pos->_data expext NULL, actual [%p]\n", pos);
  pos = l.Find(1);
  printf("pos->_data expext 1, actual %d:[%p]\n", pos->_data, pos);
  l.Insert(pos, 0);
  l.Print();
  l.Erase(pos);
  l.Print();

  List l1(l);
  l1.PushFront(8);
  l1.PushFront(7);
  l1.PushFront(6);
  l1.PushFront(5);
  l1.PopFront();
  l1.Print();

  List l2;
  l2 = l;
  l2.Print();
}

test.cpp

#include "List.h"

int main()
{
  cout << "双向链表:" << endl;
  TestList();
  return 0;
}

效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++ STL之list双向链表容器方式

    C++ STL之list双向链表容器方式

    这篇文章主要介绍了C++ STL之list双向链表容器方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • 浅析C++中boost.variant的几种访问方法

    浅析C++中boost.variant的几种访问方法

    variant类型在C++14并没有加入,若想在不支持C++17的编译器上使用variant类型,我们可以通过boost的variant类型,variant类型可以表示任意一种类型和any类型有些相似,但还是有些区别下面将浅谈variant的几种访问方法,感兴趣的朋友们下面来一起看看吧。
    2016-10-10
  • 一文秒懂C语言/C++内存管理(推荐)

    一文秒懂C语言/C++内存管理(推荐)

    在C++中,内存分为:栈、堆、自由存储区、全局/静态存储区、常量存储区。这篇文章主要介绍了一文秒懂C语言/C++内存管理,需要的朋友可以参考下
    2020-11-11
  • C++继承与菱形继承详细介绍

    C++继承与菱形继承详细介绍

    继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程
    2022-08-08
  • c++中string类成员函数c_str()的用法

    c++中string类成员函数c_str()的用法

    c_str()函数返回一个指向正规c字符串的指针,内容和string类的本身对象是一样的,通过string类的c_str()函数能够把string对象转换成c中的字符串的样式
    2013-09-09
  • C/C++实现发送与接收HTTP/S请求的示例代码

    C/C++实现发送与接收HTTP/S请求的示例代码

    HTTP(Hypertext Transfer Protocol)是一种用于传输超文本的协议,它是一种无状态的、应用层的协议,用于在计算机之间传输超文本文档,通常在 Web 浏览器和 Web 服务器之间进行数据通信,本文给大家介绍了C/C++发送与接收HTTP/S请求,需要的朋友可以参考下
    2023-11-11
  • c语言中&的用法示例代码

    c语言中&的用法示例代码

    这篇文章主要给大家介绍了关于c语言中&的用法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • C++类型转换和IO流操作处理教程

    C++类型转换和IO流操作处理教程

    这篇文章主要给大家介绍了关于C++类型转换和IO流操作处理的相关资料,标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符,文中给出了详细的代码示例,需要的朋友可以参考下
    2023-08-08
  • linux下C/C++学生信息管理系统

    linux下C/C++学生信息管理系统

    这篇文章主要为大家详细介绍了linux下c/c++学生信息管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C++实现读写文件的示例代码

    C++实现读写文件的示例代码

    这篇文章主要介绍了C++实现读写文件的示例代码,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-08-08

最新评论