双向链表的C++实现
2013-10-21 18:13
351 查看
双向链表的C++实现
双向链表与单向链表相比,各个结点多了一个指向前一个结点的指针。结构如图所示:
双向链表的结点定义如下:
在组成一个双向链表后,还需要补充一些功能,以便后续实现,模仿之前的单向链表:
1.定义这个双向链表类的构造函数及析构函数
2.清空链表内所有元素
3.给出元素位置再返回对应结点
4.返回链表内部元素个数
5.判断这个链表是否为空
6.返回链表首尾的元素值
7.查找元素是否在此链表内,如果在则返回所在位置
8.从首端到尾端输出链表上的各元素,以及反序输出链表上各元素
9.对链表插入元素以及删除元素
给出这个双向链表类框架,就像这样:
双向链表具体实现如下:
1.构造函数和析构函数:
2.清空链表内所有元素:
3.给出元素位置再返回对应结点:
要注意的是,遍历元素位置时避免pNode所获得的值越界,队首元素进不了for循环,改变不了pNode;队尾元素如果设置成i=1;i<=pos;++i,pNode会读取队尾的下一个值,那个值越界。最后就会返回一个未定义的元素。
4.返回首尾端元素、查找元素、正序反序输出链表所有元素、返回元素个数、判断链表是否为空:
5.链表中加入元素:
这里分四种情况讨论:
①插入元素位置越界
②在尾部插入元素
③在头部插入元素
④在其他位置插入元素
若插入元素成功,记得元素个数+1。这里用图示例非空链表尾部插入元素,其他情况读者们可以自己试着画图:
代码如下:
6.链表中删除元素:
这里分五种情况讨论:
①链表为空
②删除元素位置越界
③在尾部删除元素
④在头部删除元素
⑤在其他位置删除元素
若删除元素成功,记得元素个数-1。这里用图示例非空链表其他位置删除元素,其他情况读者们可以自己试着画图:
代码如下:
最后将上述实现放入之前的框架中,就完成了最后双向链表的C++实现。
参考文献及链接:
1.《算法导论》2nd Thomas H.Cormen , Charles E.Leiserson , Ronald L.Rivest , Cliford Stein 著,潘金贵、顾铁成、李成法、叶懋译
2.《数据结构与算法分析 C++描述》 第3版 Mark Allen Weiss著,张怀勇等译
3.《C++标准模板库 -自修教程及参考手册-》 Nicolai M.Josuttis著,侯捷/孟岩译
4./article/8115604.html
5./article/10273253.html
双向链表与单向链表相比,各个结点多了一个指向前一个结点的指针。结构如图所示:
双向链表的结点定义如下:
#ifndef SIMPLENODE_HPP #define SIMPLENODE_HPP template<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++实现。
参考文献及链接:
1.《算法导论》2nd Thomas H.Cormen , Charles E.Leiserson , Ronald L.Rivest , Cliford Stein 著,潘金贵、顾铁成、李成法、叶懋译
2.《数据结构与算法分析 C++描述》 第3版 Mark Allen Weiss著,张怀勇等译
3.《C++标准模板库 -自修教程及参考手册-》 Nicolai M.Josuttis著,侯捷/孟岩译
4./article/8115604.html
5./article/10273253.html