双向链表的实现
单链表是最基本最简单的结构了,用处也蛮多的吧,尤其是后面在层序结构的各种树与图结构的时候大量使用链表而且还很多是单链表形式的。学习双向链表还是由约瑟夫问题引入的呢,在单链表的删除操作时需要用并排的两个指针同步向后移动,为避免这个问题双向链表就派上用场了。双向链表顾名思义是每个结点有两个方向了,那么在结点里面不仅仅要保存一个后向指针还要保存一个前向指针了。[cpp]#pragma once#include<iostream>using namespace std;template<class T>class LinkNode //节点类{public: //全为公共的方便操作T data; //模板类型的一个数据LinkNode<T> *next; //该结点的一个指针,用于指向后继LinkNode<T> *prior;//用于指向前驱public:LinkNode(LinkNode<T> *ptr = NULL)//只初始化指针的构造函数,并使指针域为空{ next = ptr; prior = ptr; }LinkNode(const T& item,LinkNode<T> *ptr = NULL)//数据与指针一同初始化的构造函数,依旧指针域默认参数为空{ data = item; next = ptr; prior = ptr; }~LinkNode(){}};双向链表在插入的时候搭链是一个很有讲究的过程,某些步骤是有严格顺序的:[cpp]newNode->prior = current; //双向链表插入的关键四步,最后一句必须最后执行newNode->next = current->next;current->next->prior = newNode;current->next = newNode;大致上就是先搞定新结点的prior和next指针,然后是待插位置的后一个结点的prior和前一个结点的next了。双向链表的删除直接是先保存待删除结点指针然后覆盖就行了,其他的操作基本可以看作是单链表了。[cpp]#pragma once//#include"LinearList.h"#include"LinkNode.h"#include<iostream>using namespace std;template<class T>//继承的过程中,加上此句派生类依然为类模板class List{protected:LinkNode<T>* first;//封装public:List();//List(const T& x);//感觉没用到过List(List<T>& L);~List();void makeEmpty();//依次销毁每个结点的空间int Length() const;//搜索当前表节点数LinkNode<T>* getHead() const;//返回头指针LinkNode<T>* Search(T x) const;//搜索并返回指针LinkNode<T>* Locate(int i) const;//定位并返回指针bool GetData(int i,T& x) const;//返回第i个结点的元素值以引用的形式bool SetData(int i,T& x);//修改第i个结点的元素值bool Insert(int i,T& x);//在第i个节点后面插入新节点元素值LinkNode<T>* Remove(int i,T& x);//删除第i个结点bool isEmpty() const;//判表空void Sort(); //排序void input(T endTag);//建立表并输入void output();//输出表void operator = (List<T>& L);//复制重载};template<class T>List<T>::List(){first = new LinkNode<T>;//构造函数中开辟头结点}template<class T>List<T>::List(List<T>& L){LinkNode<T> *srcptr = L.getHead() ->next; //获取头指针 用于遍历LinkNode<T> *destptr = first = new LinkNode<T>;//建立头结点 初始化LinkNode<T> *newNode;T value;while(srcptr != NULL)//直到最后一个结点的尾指针为空结束{value = srcptr->data;newNode = new LinkNode<T>(value);newNode->prior = destptr;//往新链表的后面插入destptr->next = newNode;srcptr = srcptr->next;//后移destptr = destptr->next;}}template<class T>List<T>::~List(){}template<class T>void List<T>::makeEmpty() //全部销毁指针资源{LinkNode<T> *current = first->next;LinkNode<T> *del;while(current != NULL){del = current;current = current->next;delete del;}}template<class T>int List<T>::Length() const{int count = 0;LinkNode<T> *current = first;//头指针副本用于遍历while(current->next != NULL)//与单链表的遍历控制条件相同,当前结点后后继是否为空{current = current->next;count++ ;}return count;}template<class T>LinkNode<T>* List<T>::getHead() const{return first;}template<class T>LinkNode<T>* List<T>::Search(T x) const{LinkNode<T> *current = first->next;while(current != NULL)//此时的控制条件为某个结点的next知否为空{if(current->data == x)return current;//如果查询到直接函数返回,不用无用操作(如果链表中有多个x元素值,则以第一个为准返回)current = current->next;}return NULL;}template<class T>LinkNode<T>* List<T>::Locate(int i) const{if(i < 0) //定位可以是第0个,也就是头结点指针&nbs补充:软件开发 , C++ ,
上一个:boost线程使用带参数的类成员函数方法
下一个:disksim使用总结
- 更多C/C++疑问解答:
- 关于c++的cout输出的问题。
- 在学校里学过C和C++,不过学的很一般,现在自学C#,会不会很难?
- 全国计算机二级C语言笔试题
- 已知某树有2个2度结点,3个3度结点,4个4度结点,问有几个叶子结点?
- c++数据结构内部排序问题,整数排序
- 2012九月计算机二级C语言全国题库,,急求急求
- 如果assert只有一个字符串作为参数,是什么意思呢?
- C语言中,哪些运算符具有左结合性,哪些具有右结合性,帮忙总结下,谢谢了!
- 为什么用结构体编写的程序输入是,0输不出来啊~~~
- 将IEEE—754的十六进制转化为十进制浮点类型,用C或C++都行,多谢各位大侠啊,非常感谢!
- 为什么这个程序求不出公式?
- 这个链表倒置的算法请大家分析下
- c语言函数库调用
- C语言unsigned int纠错
- C语言快排求解啊