【C++】模板实现带头节点的双向循环链表

来源:互联网 发布:matlab编程第二版.pdf 编辑:程序博客网 时间:2024/04/28 10:20

链表分为带头节点和不带头节点,单链表和双向循环链表。

带头节点的链表虽然有头结点,但是并不存储数据,双向循环链有指向前一个数的指针和指向后一个数的指针。

如下图:

先来实现一些主要的函数:

List的构造函数和析构函数:

        List(){_head = new Node;_head->_next = _head;_head->_prev = _head;}~List(){clear();delete _head;_head = NULL;}

List在任意一个位置插入一个数和删除一个数

 

//任意一个位置插入一个数,在pos的前面插入一个数据void Insert(Node* pos, const T& x){assert(pos);Node* tmp = new Node(x);Node* cur = pos;Node* prev = cur->_prev;prev->_next = tmp;tmp->_prev = prev;tmp->_next = cur;cur->_prev = tmp;}//删除任意一个位置的数void Erase(Node* pos){assert(pos && pos != _head);Node* prev = pos->_prev;Node* next = pos->_next;prev->_next = next;next->_prev = prev;delete pos;}

有了插入和删除函数之后,其他的函数都可以用Erase和Insert来复用:

尾部插入和删除函数:

//尾部插入一个数void PushBack(const T& x){Insert(_head, x);}//尾部删除一个数void PopBack(const T& x){Erase(_head->_prev);}

头部插入和删除数据:

//头部插入一个数void PushFront(const T& x){Insert(_head->_next,x);}//头部删除一个数void PopFront(const T& x){Erase(_head->_next);}

构造函数和赋值运算符重载:

//拷贝构造函数List(const List<T> & l){_head = new Node();_head->_next = _head;_head->_prev = _head;Node* cur = (l._head)->_next;while (cur != l._head){this->PushBack(cur->_data);cur = cur->_next;}}//赋值运算符重载List<T>& operator=(const List<T>& l){if (this != &l){this->clear();Node* cur = l._head->_next;while (cur != l._head){this->PushBack(cur->_data);cur = cur->_next;}}return *this;}

在插入和删除数据的时候要考虑双向链表里面会出现的各种情况!

以下是完整的代码:

ListNode.h#pragma once#include<assert.h>template<class T>struct ListNode{T _data;ListNode<T>* _next;ListNode<T>* _prev;ListNode(const T& x = T()):_data(x), _next(NULL), _prev(NULL){}};template<class T>class List{typedef ListNode<T> Node;public:List(){_head = new Node;_head->_next = _head;_head->_prev = _head;}~List(){clear();delete _head;_head = NULL;}//删除任意一个位置的数void Erase(Node* pos){assert(pos && pos != _head);Node* prev = pos->_prev;Node* next = pos->_next;prev->_next = next;next->_prev = prev;delete pos;}//任意一个位置插入一个数,在pos的前面插入一个数据void Insert(Node* pos, const T& x){assert(pos);Node* tmp = new Node(x);Node* cur = pos;Node* prev = cur->_prev;prev->_next = tmp;tmp->_prev = prev;tmp->_next = cur;cur->_prev = tmp;}//尾部插入一个数void PushBack(const T& x){Insert(_head, x);}//尾部删除一个数void PopBack(const T& x){Erase(_head->_prev);}//头部插入一个数void PushFront(const T& x){Insert(_head->_next,x);}//头部删除一个数void PopFront(const T& x){Erase(_head->_next);}//查找一个数void Find(const T& x){Node* cur = _head->_next;while (cur != _head){if (cur->_data == x){return cur;}return NULL;}}//清除void clear(){Node* cur = _head->_next;while (cur != _head){Node* next = cur->_next;delete cur;cur = next;}_head->_next = _head;_head->_prev = _head;}//打印void Print(){Node* cur = _head->_next;while (cur!=_head){cout << cur->_data << "";cur = cur->_next;}cout << endl;}//拷贝构造函数List(const List<T> & l){_head = new Node();_head->_next = _head;_head->_prev = _head;Node* cur = (l._head)->_next;while (cur != l._head){this->PushBack(cur->_data);cur = cur->_next;}}//赋值运算符重载List<T>& operator=(const List<T>& l){if (this != &l){this->clear();Node* cur = l._head->_next;while (cur != l._head){this->PushBack(cur->_data);cur = cur->_next;}}return *this;}protected:Node* _head;};void Test1()//尾部插入和删除{//插入List<int> l;l.PushBack(1);l.Print();l.PushBack(2);l.Print();l.PushBack(3);l.Print();l.PushBack(4);l.Print();//删除l.PopBack(1);l.Print();l.PopBack(1);l.Print();l.PopBack(1);l.Print();}void Test2()//头部插入和删除{//插入List<int> l;l.PushFront(1);l.Print();l.PushFront(2);l.Print();l.PushFront(3);l.Print();//删除l.PopFront(1);l.Print();l.PopFront(1);l.Print(); l.PopFront(1);l.Print(); }测试函数Test.cpp#include<iostream>using namespace std;#include"ListNode.h"int main(){Test1();Test2();system("pause");return 0;}

 

 


0 0
原创粉丝点击