C++实现双链表的基本功能
来源:互联网 发布:淘宝中如何发布宝贝 编辑:程序博客网 时间:2024/05/29 16:09
双链表:在单链表的每个结点中,再设置一个指向其前驱结点的指针域
线性表的双向链表存储结构:
typedef struct Node{ DataType _data; struct Node *_next; struct Node *_front;}Node;
通过双链表的存储结构我们发现双链表可以反向查找结点优于单链表 ,实质上双链表就是以空间换取时间,虽然双链表具有可以反向查找数据的优点但是它也存在缺点:在插入和删除一个结点时需要维护两个指针变量,特别是在双链表的插入中指针的指向顺序是不可修改的。
双链表的插入过程:
双链表的删除过程:
C++实现双链表的基本功能:
typedef int DataType;class LinkList;class Node{friend LinkList;friend ostream &operator<<(ostream &os,Node &n);friend ostream& operator<<(ostream &os,LinkList &list);public:Node(DataType x):_data(x),_next(NULL),_front(NULL){}private:DataType _data;Node *_next;Node *_front;};ostream &operator<<(ostream &os,Node &n){os<<n._data;return os;}class LinkList{friend ostream& operator<<(ostream &os,LinkList &list);public:LinkList():_head(NULL),_tail(NULL){}LinkList(const LinkList &list):_head(NULL),_tail(NULL){Node *cur=list._head;while(cur){Node *tmp=new Node(cur->_data);if(_tail){_tail->_next=tmp;tmp->_front=_tail;_tail=tmp;}else //空链表{_head=tmp;_tail=tmp;}cur=cur->_next;}}~LinkList(){Node *cur=_head;while(cur){Node *del=cur;cur=cur->_next;delete del;del=NULL;}}public:void PushBack(DataType x){Node *NewNode=new Node(x);if(_tail){_tail->_next=NewNode;NewNode->_front=_tail;_tail=NewNode;}else{_head=NewNode;_tail=NewNode;}}void PopBack(){if(!_head && !_tail) //空链表{cout<<"链表已空不可尾删"<<endl;return ;}else if(_head == _tail) //只有一个节点{delete _tail;_head=NULL;_tail=NULL;}else //至少存在两个节点{Node *tmp=_tail;_tail=tmp->_front;_tail->_next=NULL;delete tmp;tmp=NULL;}}void PushFront(DataType x){Node *NewNode=new Node(x);if(_head){Node *tmp=_head;NewNode->_next=tmp;tmp->_front=NewNode;}else{_tail=NewNode;}_head=NewNode; //更新头}void PopFront(){if(!_head && !_tail) //空链表{cout<<"链表已空不可头删"<<endl;return ;}else if(_head == _tail) //只有一个节点{delete _head;_head=NULL;_tail=NULL;}else //至少存在两个节点{Node *del=_head;_head=del->_next;_head->_front=NULL;delete del;del=NULL;}}Node *FindNum(DataType x){Node *cur=_head;while(cur){if(cur->_data == x)return cur;cur=cur->_next;}return NULL;}void Insert(Node *pos,DataType x) //在指定位置后插{Node *NewNode=new Node(x);if(pos->_next){NewNode->_front=pos;NewNode->_next=pos->_next;pos->_next->_front=NewNode;pos->_next=NewNode;}else //在最后一个结点后插,类似PushBack{pos->_next=NewNode;NewNode->_front=pos;_tail=NewNode; //更新尾}}void Insert(int,Node *pos,DataType x) //在指定位置前插{Node *NewNode=new Node(x);if(pos->_front){NewNode->_next=pos;pos->_front->_next=NewNode;NewNode->_front=pos->_front;pos->_front=NewNode;}else //在第一个结点的前插,类似PushFront{NewNode->_next=pos;pos->_front=NewNode;_head=NewNode; //更新头}}void Remove(DataType &x){Node *pos=this->FindNum(x);if(pos != NULL){if((!(pos->_front)) && pos->_next) //删除第一个结点{Node *tmp=pos->_next; tmp->_front=NULL; _head=tmp;}else if(pos->_front && (!(pos->_next))) //删除最后一个结点{Node *tmp=pos->_front;tmp->_next=NULL;_tail=tmp;}else //删除中间节点{Node *front=pos->_front;Node *next=pos->_next;next->_front=front;front->_next=next;}delete pos;pos=NULL;}}void RemoveAll(DataType &x){Node *cur=_head;Node *ret=this->FindNum(x);if(ret != _head) //可删除第一个结点不是要删除的元素{while(cur){Remove(x);cur=cur->_next;}}}void Sort(){int flag=1;Node *cur=_head;Node *tail=NULL;while(cur != tail){while(cur->_next != tail){if(cur->_data > cur->_next->_data){DataType tmp=cur->_data;cur->_data=cur->_next->_data;cur->_next->_data=tmp;flag=0;}cur=cur->_next;}if(flag == 1)break;tail=cur;cur=_head;}}void Erase(Node *pos){if((!(pos->_front)) && pos->_next) //删除第一个结点{Node *tmp=pos->_next;tmp->_front=NULL;_head=tmp;}else if(pos->_front && (!(pos->_next))) //删除最后一个结点{Node *tmp=pos->_front;tmp->_next=NULL;_tail=tmp;}else //删除中间节点{Node *front=pos->_front;Node *next=pos->_next;next->_front=front;front->_next=next;}delete pos;pos=NULL;}private:Node *_head;Node *_tail;};ostream& operator<<(ostream &os,LinkList &list){Node *cur=list._head;while(cur){os<<(*cur)<<" ";cur=cur->_next;}return os;}
在C++实现中如果遇到结点结构最好定义为struct,否则就会像上述情况一样需要声明多次友元,反而破坏了类的封装性
测试代码:
void menu(){cout<<"************1.尾插************2.尾删**************"<<endl;cout<<"************3.头插************4.头删**************"<<endl;cout<<"************5.指定位置后插****6.指定位置前插******"<<endl;cout<<"************7.删除指定元素****8.删除所有指定元素**"<<endl;cout<<"************9.排序************0.退出*************"<<endl;cout<<"************11.Erase**********0.退出*************"<<endl;}void test(){LinkList list;Node *ret=NULL;int input=1;DataType x,num;while(input){menu();cout<<"请输入您的选择>";cin>>input;switch(input){case 1:cout<<"请输入您要插入的数据>";cin>>x;list.PushBack(x);break;case 2:list.PopBack();break;case 3:cout<<"请输入您要插入的数据>";cin>>x;list.PushFront(x);break;case 4:list.PopFront();break;case 5:cout<<"请输入您要查找的数据>";cin>>x;ret=list.FindNum(x);if(ret != NULL){cout<<"请输入您要插入的数据>"; cin>>num; list.Insert(ret,num);}else{cout<<"您所查找的数据不存在"<<endl;}break;case 6:cout<<"请输入您要查找的数据>";cin>>x;ret=list.FindNum(x);if(ret != NULL){cout<<"请输入您要插入的数据>"; cin>>num; list.Insert(0,ret,num); //0用于占位,构成重载}else{cout<<"您所查找的数据不存在"<<endl;}break;case 7:cout<<"请输入您要删除的数据>";cin>>x;list.Remove(x);break;case 8:cout<<"请输入您要删除的数据>";cin>>x;list.RemoveAll(x);break;case 9:list.Sort();break;case 10:cout<<list<<endl;break;case 11:cout<<"请输入您要擦除的数据>";cin>>x;ret=list.FindNum(x);if(ret != NULL){list.Erase(ret);}else{cout<<"您所查找的数据不存在"<<endl;}break;case 0:break;default:cout<<"您的输入错误"<<endl;break;}}}
OVER
1 0
- C实现数组的基本功能
- C++实现双链表的基本功能
- 二叉树的基本功能实现(c++)
- 线性表基本功能的c语言实现
- 数据结构C语言版--单链表的基本功能实现
- 栈的基本功能实现(C语言)
- 双链表一些基本功能的简单实现
- WINCE实现的基本功能
- wince实现的基本功能
- 串的基本功能实现
- Animation基本功能的实现
- ls基本功能的实现
- 【C语言】实现Linux下的cp命令的基本功能
- 【C语言】实现Linux下的last命令的基本功能
- c语言单向链表的基本功能的实现
- 数据结构C 语言描述——实现栈的基本功能
- c语言实现单链表的及各项基本功能
- 小游戏:扫雷 (C语言实现扫雷的基本功能)
- 关于软件盘弹出,界面上下移动问题
- if continue在循环遍历中的使用
- React-Native 入门指导系列教程目录
- 监听按钮的点击事件
- Python中的函数修饰符
- C++实现双链表的基本功能
- 计算给定多项式 在给定点 x = 1.1 处的值 f(1.1)
- 根据分类id,获取该分类下的商品数据(商品名,价格,路径,缩略图)
- 安卓WebView中全屏播放网页视频
- FFMPEG视音频编解码零基础学习方法
- HTML li如何垂直居中
- 几个之前不清楚的正则
- 后台执行Jquery代码
- Mac 在命令行中获得Root权限