双向链表的C++实现
来源:互联网 发布:手机缩小图片尺寸软件 编辑:程序博客网 时间:2024/04/28 08:45
双向链表的C++实现
双向链表与单向链表相比,各个结点多了一个指向前一个结点的指针。结构如图所示:
双向链表的结点定义如下:
#ifndef SIMPLENODE_HPP#define SIMPLENODE_HPPtemplate<typename T> //再定义一个模板 写双链表 class DoubleNode{public:T element;DoubleNode* prev;DoubleNode* next;DoubleNode(const T& theElement,DoubleNode* thePrev=NULL,DoubleNode* theNext=NULL) :element(theElement),prev(thePrev),next(theNext) {}//这里已经创建了一个双链表 }; #endif
在组成一个双向链表后,还需要补充一些功能,以便后续实现,模仿之前的单向链表:
1.定义这个双向链表类的构造函数及析构函数
2.清空链表内所有元素
3.给出元素位置再返回对应结点
4.返回链表内部元素个数
5.判断这个链表是否为空
6.返回链表首尾的元素值
7.查找元素是否在此链表内,如果在则返回所在位置
8.从首端到尾端输出链表上的各元素,以及反序输出链表上各元素
9.对链表插入元素以及删除元素
给出这个双向链表类框架,就像这样:
#ifndef DOUBLELINKLIST_HPP#define DOUBLELINKLIST_HPP#include<iostream>#include"simplenode.hpp"template<typename T>class DoubleLinkList{private:DoubleNode<T>* head;DoubleNode<T>* tail;int size;DoubleNode<T>* GetPointAt(int pos){...} //给出元素位置再返回其对应结点public:DoubleLinkList():head(),tail(),size(0) {}~DoubleLinkList() {Clear();}void Clear(){...}int Size() {...} //返回元素个数bool isempty() {... }T GetHeadVal() {...} T GetTailVal(){...}int Find(T val){...}void ShowAllVal(){...}void ReverseShowAllVal(){...}void AddBack(T val){...}void AddFront(T val){...}bool AddAt(T val,int pos){DoubleNode<T>* pNode=NULL;if (pos<=0 || pos>size){...}if (pos==size)AddBack(size);else if (pos==1)AddFront(1);else{...}size++;return true;}bool RemoveBack(){return RemoveAt(size);}bool RemoveFront(){return RemoveAt(1);}bool RemoveAt(int pos){DoubleNode<T>* pNode=NULL;if (isempty()){...}if (pos<=0 || pos>size){...}if (size==1){Clear();}if (pos==1){...}else{DoubleNode<T>* pPreNode=GetPointAt(pos-1);pNode=pPreNode->next;if (pos==size){ ...} else{...}delete pNode;}size--;return true;}};#endif
双向链表具体实现如下:
1.构造函数和析构函数:
DoubleLinkList():head(),tail(),size(0) {}~DoubleLinkList() {Clear();}
2.清空链表内所有元素:
void Clear(){//从链表头到链表尾的方式逐个删除 const int nums=Size();if (!isempty()){for (int k=1;k<=nums;++k){DoubleNode<T>* temp=head->next;delete head;head=temp;size--;}}//如果链表本来就为空,就没必要再进for循环了 }
3.给出元素位置再返回对应结点:
DoubleNode<T>* GetPointAt(int pos){DoubleNode<T>* pNode=NULL;if (pos<=0 || pos>size)std::cout<<"out of range"<<std::endl;else{pNode=head;for (int i=1;i<=pos-1;++i)pNode=pNode->next;}return pNode;}
要注意的是,遍历元素位置时避免pNode所获得的值越界,队首元素进不了for循环,改变不了pNode;队尾元素如果设置成i=1;i<=pos;++i,pNode会读取队尾的下一个值,那个值越界。最后就会返回一个未定义的元素。
4.返回首尾端元素、查找元素、正序反序输出链表所有元素、返回元素个数、判断链表是否为空:
T GetHeadVal() {if (isempty()){std::cout<<"the link list is empty"<<std::endl;return NULL;}return head->element;} T GetTailVal(){if (isempty()){std::cout<<"the link list is empty"<<std::endl;return NULL;}return tail->element;}
int Find(T val){int pos=1; //从1号位,也就是链表首开始DoubleNode<T>* findNode=head;while (findNode!=NULL){if (findNode->element==val)return pos;findNode=findNode->next;pos++;} std::cout<<"we can't find it.return -1"<<std::endl;return -1;}
void ShowAllVal(){DoubleNode<T>* findNode=head;while (findNode!=NULL){std::cout<<findNode->element<<" ";findNode=findNode->next;}std::cout<<std::endl;}void ReverseShowAllVal(){DoubleNode<T>* findNode=tail;while (findNode!=NULL){std::cout<<findNode->element<<" ";findNode=findNode->prev; }std::cout<<std::endl;}
int Size() {return size;} //返回元素个数bool isempty() {return size==0?true:false; }
5.链表中加入元素:
这里分四种情况讨论:
①插入元素位置越界
②在尾部插入元素
③在头部插入元素
④在其他位置插入元素
若插入元素成功,记得元素个数+1。这里用图示例非空链表尾部插入元素,其他情况读者们可以自己试着画图:
代码如下:
void AddBack(T val){DoubleNode<T>* pNode=new DoubleNode<T>(val);if (isempty()){head=pNode;tail=pNode;}else{tail->next=pNode;pNode->prev=tail;tail=pNode;}size++;}void AddFront(T val){DoubleNode<T>* pNode=new DoubleNode<T>(val);if (isempty()){head=pNode;tail=pNode;}else{head->prev=pNode;pNode->next=head;head=pNode;}size++;}bool AddAt(T val,int pos){DoubleNode<T>* pNode=NULL;if (pos<=0 || pos>size){std::cout<<"out of range"<<std::endl;return false;}if (pos==size)AddBack(size);else if (pos==1)AddFront(1);else{DoubleNode<T>* pPreNode=GetPointAt(pos-1);pNode=new DoubleNode<T>(val);pNode->next=pPreNode->next;pNode->prev=pPreNode;pPreNode->next->prev=pNode; pPreNode->next=pNode;}size++;return true;}
6.链表中删除元素:
这里分五种情况讨论:
①链表为空
②删除元素位置越界
③在尾部删除元素
④在头部删除元素
⑤在其他位置删除元素
若删除元素成功,记得元素个数-1。这里用图示例非空链表其他位置删除元素,其他情况读者们可以自己试着画图:
代码如下:
bool RemoveBack(){return RemoveAt(size);}bool RemoveFront(){return RemoveAt(1);}bool RemoveAt(int pos){DoubleNode<T>* pNode=NULL;if (isempty()){std::cout<<"the link list is empty"<<std::endl;return false;}if (pos<=0 || pos>size){std::cout<<"out of range"<<std::endl;return false;}if (size==1){Clear();}if (pos==1){pNode=head;head=head->next;head->prev=NULL;delete pNode;}else{DoubleNode<T>* pPreNode=GetPointAt(pos-1);pNode=pPreNode->next;if (pos==size){ pPreNode->next=NULL;tail=pPreNode;} else{pPreNode->next=pNode->next;pNode->next->prev=pPreNode;}delete pNode;}size--;return true;}
最后将上述实现放入之前的框架中,就完成了最后双向链表的C++实现。
参考文献及链接:
4.http://blog.csdn.net/weiwenhp/article/details/8634984
5.http://blog.csdn.net/mourinho_my_idol/article/details/12570609
- 双向链表的实现 c
- c语言双向链表的实现
- 双向链表的C实现
- 双向链表的C实现
- c双向链表的实现
- 双向链表的C语言实现
- 双向链表的C实现
- 双向链表的C实现
- 【C++】双向链表的实现
- 【C语言】双向链表的实现
- c语言:双向链表的实现
- C 双向链表的实现
- 双向链表的实现与操作(C语言实现)
- 实现通用的双向链表(c语言实现)
- C/C++/JAVA 双向链表实现
- 通用双向链表的C语言实现
- C语言实现双向链表的基本操作
- 双向链表、队列与栈的C/C++实现
- java字符串池和字符串堆内存分配
- SVI接口 (交换机虚拟接口)
- HDU 1205 吃糖果
- 指出一些常见的谎言与谬误
- android开发The method setOnClickListener(View.OnClickListener) in the type View is not错误
- 双向链表的C++实现
- ORA-06550, PLS-00302错误处理
- 可以设置屏幕不再是全屏
- PAT Advanced 1065
- 黑马程序员----JAVASE之多线程
- NSSet 札记
- vim更详细文档
- HTTP&&Fiddler教程
- Unity3D 游戏引擎之将场景导出XML或JSON或二进制并且解析还原场景