【C++】双向链表

来源:互联网 发布:广播电视台和广电网络 编辑:程序博客网 时间:2024/06/08 04:14

     博客介绍了C语言,以及C++的单向链表。那么我们今天介绍的双向链表,顾名思义,就是数据本身具备了左边和右边的双向指针。双向链表相比较单向链表,主要有下面几个特点:

    (1)在数据结构中具有双向指针

    (2)插入数据的时候需要考虑前后的方向的操作

    (3)同样,删除数据的是有也需要考虑前后方向的操作

    那么,一个非循环的双向链表操作应该是怎么样的呢?我们可以自己尝试一下:


源代码:

#include <iostream>using namespace std;typedef int DataType;class LinkNode{friend class List;public:LinkNode(const DataType& x):_data(x),_next(NULL),_prev(NULL){}~LinkNode(){}protected:DataType _data;// 数据private:LinkNode* _prev;// 前驱LinkNode* _next;// 后继};class List{public:List():_head(NULL),_tail(NULL){}~List(){}List(const List& l){}List& operator=(const List& l);public:void Print(){LinkNode *begin=_head;while (begin){cout<<begin->_data<<"->";begin=begin->_next;}cout<<"NULL"<<endl;}void PushBack(const DataType& x){// 1.空链表// 2.一个或以上节点if(_head == NULL){_head=new LinkNode(x);_tail=_head;}else{_tail->_next=new LinkNode(x);_tail->_next->_prev=_tail;_tail=_tail->_next;}}void PopBack(){// 1.空链表// 2.一个节点// 3.两个及以上节点if (_head ==NULL){return ;}if (_head == _tail){delete _head;_head = NULL;_tail = NULL;}else{LinkNode* del=_tail;_tail=_tail->_prev;_tail->_next=NULL;//_tail->_prev=_tail->_prev;此句功能包含在_tail=_tail->_prev;中!!delete del;/*tail=_tail->_prev;delete _tail->_next;_tail->_next=NULL;*/}}void PushFront(const DataType& x){//1.空链表//2.非空链表if(_head == NULL){_head=new LinkNode(x);_tail=_head;}else{LinkNode *tmp = new LinkNode(x);tmp->_next=_head;_head->_prev=tmp;tmp->_prev = NULL;_head=tmp;}}void PopFront(){// 1.空链表// 2.一个节点// 3.两个及以上节点if (_head == NULL){return ;}if (_head == _tail){delete _head;_head = NULL;_tail = NULL;}if(_head != _tail)//链表清空之后的判断,否则出现内存访问冲突{LinkNode *del =(_head);_head=_head->_next;_head->_prev=NULL;delete del;}}//插入void Insert(LinkNode* pos, const DataType& x){// 1.空链表// 2.尾部插入// 3.中间插入if (_head == NULL){_head=new LinkNode(x);_tail=_head;}if(pos == _tail){PushBack(x);}else{LinkNode *tmp=new LinkNode(x);pos->_prev->_next=tmp;pos->_next->_prev=tmp;tmp->_prev=pos->_prev;tmp->_next=pos->_next;}}//查找LinkNode* Find(const DataType& x){if (_head == NULL){return NULL;}LinkNode* begin = _head;while(begin != NULL){if(begin->_data == x){return begin;}else{begin = begin->_next ;}}return NULL;cout<<"没有找到该节点"<<endl;}//删除void Erase(LinkNode* del){//1.空链表if(_head == NULL){return ;}else {//2.一个节点且是删除节点if ((_head == _tail) && (_head == del)){delete _head;_head=NULL;_tail=NULL;}else {//3.多个节点//del为头if (_head == del){PopFront();/*_head=_head->_next;_head->_prev=NULL;delete _head->_prev;*/}else{//del在尾if(del == _tail){PopBack();/*del->_prev->_next=NULL;_tail=del->_prev;delete del;*/}//del在中else{del->_prev->_next=del->_next;del->_next->_prev=del->_prev;delete del;}}}}}void remove(DataType * x){LinkNode *ret=Find(*x);Erase(ret);}//逆置void Reverse(){LinkNode* tmp1 = _head;LinkNode* tmp2 = _tail;while(tmp1 != tmp2 && tmp2->_next != tmp1) {DataType a = tmp1->_data ;tmp1->_data = tmp2->_data ;tmp2->_data = a;tmp1 = tmp1->_next ;tmp2 = tmp2->_prev ;}}private:LinkNode* _head;LinkNode* _tail;};void Test1(){List l1;l1.PushBack(1);l1.PushBack(2);l1.PushBack(3);l1.PushBack(4);l1.Print();LinkNode* ret = l1.Find(4);//cout<<"ret:"<<ret->_data<<endl;//测试失败“LinkNode::_data”: 无法访问 protected 成员(在“LinkNode”类中声明)//l1.PopBack();//l1.PopBack();//l1.PopBack();//l1.PopBack();//l1.PopBack();//l1.Insert(s,3);//l1.PopFront();//l1.PopFront();//l1.PopFront();//l1.PopFront();//l1.PopFront();/*l1.PushFront(0);l1.Print();*///l1.Erase(ret);//l1.Reverse();/*DataType x=3;l1.remove(&x);*/l1.Print();}void Test2(){List l1;l1.PushFront(1);l1.PushFront(2);l1.PushFront(3);l1.PushFront(4);l1.Print();l1.PopFront();l1.PopFront();l1.PopFront();l1.PopFront();l1.PopFront();l1.Print();}int main(){Test1();//Test2();getchar();return 0;}


0 0
原创粉丝点击