c++数据结构:线性表实现之双链表
2017-10-06 21:59
316 查看
原型:单链表;
与单链表节点结构差异:单链表仅有一个指针域指向下一个节点,双链表有两个指针域分别指向其上一个和下一个节点;
实现操作差异:主要是上链(插入)与脱链(删除)操作,其中双链表上链时的指针重导向需注意相对顺序(不能颠倒)
节点结构:
双链表类模板实现:
函数调用测试:
合法数据调用结果:
部分非法数据调用结果:
Get(i)传入的参数非法时:
Delete(i)传入的参数非法时:
在准备选择双链表时,应先看看单链表是否能够满足需求,因为双链表多了一个指针域,数据量大时可能会浪费存储空间,而且双链表操作比单链表繁琐一点。
额。。。
暂时只能挤这么多。。
Bye
与单链表节点结构差异:单链表仅有一个指针域指向下一个节点,双链表有两个指针域分别指向其上一个和下一个节点;
实现操作差异:主要是上链(插入)与脱链(删除)操作,其中双链表上链时的指针重导向需注意相对顺序(不能颠倒)
节点结构:
#pragma once template< typename T> class Node { public: T data; Node *next; //向后指针 Node *prior; //向前指针 相对单链表新增的指针域 };
双链表类模板实现:
#pragma once #include"Node.h" #include<iostream> #include<string> using namespace std; template <typename T> class doubleLink { public: doubleLink(T a[],int n); ~doubleLink(); int Length(); //返回单链表的长度 T Get(int i); //按位查找,查找第i个节点的元素 int Locate(T x); //按值查找,查找链表中第一个值为x的元素,并返回序号 bool Insert(int i, T x); //插入元素,在第i个位置插入值x bool Delete(int i); //删除节点,删除第i个节点 bool InsertHead(T x); //头插法插入节点 bool InsertTail(T x); //尾插法插入节点 void ListTraverse(); //遍历节点 T priorOne(int i); //返回节点的上一个节点 T nextOne(int i); //返回节点的下一个节点 private: Node<T> *first; //设置头指针 int m_Length; //设置链的长度计数器 }; template<typename T> doubleLink<T>::doubleLink(T a[], int n) { m_Length = 0; first = new Node<T>; first->next = NULL; first->prior = NULL; for (int i = 0; i < n; i++) //头插法插入元素 { Node<T> *s = new Node<T>; s->data = a[i]; if (first->prior == NULL) { s -> next = first; s->prior = first; first->next = s; first->prior = s; m_Length++; } else { s->next = first->next; first->next->prior = s; s -> prior = first; first->next = s; m_Length++; } } //尾插法插入元素 /*for (var i = 0; i < n;i++) { Node<T> *s = new Node<T>; s->data = a[i]; if (first->prior == NULL) { s->next = first; s->prior = first; first->next = s; first->prior = s; Length++; } else { s->prior = first->prior; s->next = first; first->prior->next = s; first->prior = s; m_Length++; } }*/ } template<typename T> doubleLink<T>::~doubleLink() { while (first->next!=first->prior) { //临时指针,存储即将释放的节点的指针 Node<T> *temp = first; //脱链 first->prior->next = first->next; first->next -> prior = first->prior; //头指针后移 first = first->next; //释放内存 delete temp; } delete first; } template<typename T> int doubleLink<T>::Length() { return m_Length; } template<typename T> T doubleLink<T>::Get(int i) { if (i > m_Length || i <= 0) { throw string("调用函数Get()时位置出错!"); } else { Node<T> *p = first; for (int j = 0; j < i;j++) { p = p->next; } return p->data; } } template<typename T> int doubleLink<T>::Locate(T x) { Node<T> *p = first->next; int count = 1; for (int i = 0; i < m_Length; i++) { if (p->data == x) { return count; } p = p->next; count++; } if (p->next == first) { return -1; /*个人认为此处不应该抛出错误,所以并没有throw*/ } } template<typename T> bool doubleLink<T>::Insert(int i, T x) { if (i > m_Length || i <= 0) { //判断要插入的位置是否在合理范围 throw string("调用函数Insert()时位置出错"); } Node<T> *p = first; Node<T> *s = new Node<T>; if (s == NULL) { return false; } s->data = x; int count = 0; while (p->next!=first&&count < i) { p = p->next; count++; } s->next = p; s->prior = p->prior; p->prior->next = s; p->prior = s; m_Length++; return true; } template<typename T> bool doubleLink<T>::Delete(int i) { if (i > m_Length || i < 0) { throw string("调用函数Delete()时位置出错"); } int count = 0; Node<T> *p = first; while (p->next != first&&count < i) { p = p->next; count++; } p->prior->next = p->next; p->next->prior = p->prior; delete p; m_Length--; return true; } template<typename T> bool doubleLink<T>::InsertHead(T x) { Node<T> *s = new Node<T>; if (s == NULL) { return false; //内存申请失败要不要throw出来?em......母鸡 } s->data = x; s->next = first->next; s->prior = first; first->next->prior = s; first->next = s; m_Length++; return true; } template<typename T> bool doubleLink<T>::InsertTail(T x) { Node<T> *s = new Node<T>; if (s == NULL) { return false; } s->data = x; s->next = first; s->prior = first->prior; first->prior->next = s; first->prior = s; m_Length++; return true; } template<typename T> void doubleLink<T>::ListTraverse() { Node<T> *p = first->next; cout << endl; for (int i = 0; i < m_Length;i++) { cout << p->data << ","; p = p->next; } } template<typename T> T doubleLink<T>::priorOne(int i) { if (i > m_Length || i <= 0) { throw string("调用函数prior时位置出错"); } else { Node<T> *p = first; for (int j = 0; j < i; j++) { p = p->next; } if (i == 1) { return p->prior->prior->data; } else { return p->prior->data; } } } template<typename T> T doubleLink<T>::nextOne(int i) { if (i > m_Length || i <= 0) { throw string("调用函数nextone时位置出错"); } else { Node<T> *p = first; for (int j = 0; j < i; j++) { p = p->next; } if (i==m_Length) { return p->next->next->data; } else { return p->next->data; } } }
函数调用测试:
#include<iostream> #include"doubleLink.h" #include<string> using namespace std; int main() { int a[5] = { 1,2,3,4,5 }; try{ doubleLink<int> MyList(a, 5); MyList.ListTraverse(); //测试遍历函数是否成功 cout << endl << "链表长度为:" << MyList.Length() << endl; //测试返回长度函数是否成功 cout << "第1个节点的元素为:" << MyList.Get(1); //测试查找位置元素的函数是否成功 MyList.Delete(1); cout << endl << "删除第一个节点后:"; MyList.ListTraverse(); MyList.Insert(1, 5); cout <<endl<< "插入元素5到第一个节点后:" ; MyList.ListTraverse(); MyList.InsertHead(2); cout << endl << "头插法插入元素2:"; MyList.ListTraverse(); MyList.InsertTail(8); cout << endl << "尾插法插入元素8"; MyList.ListTraverse(); cout << endl << "元素8所在的位置为:" << MyList.Locate(8); cout << endl << "第二个节点的后一个节点元素为:" << MyList.nextOne(2); cout << endl << "第二个节点的前一个节点元素为:" << MyList.priorOne(2); } catch (string &aval) { cout << aval << endl; } return 0; }
合法数据调用结果:
部分非法数据调用结果:
Get(i)传入的参数非法时:
Delete(i)传入的参数非法时:
在准备选择双链表时,应先看看单链表是否能够满足需求,因为双链表多了一个指针域,数据量大时可能会浪费存储空间,而且双链表操作比单链表繁琐一点。
额。。。
暂时只能挤这么多。。
Bye
相关文章推荐
- 数据结构和算法 C/C++ Java 和 C# 版 - (2)线性表 精准表述 实现
- 数据结构学习----线性表的链式表示之循环双链表(Java实现)
- 数据结构 线性表 线性实现 c++ 源代码
- 【c++版数据结构】之循环双链表的实现(带头结点以及尾节点)
- 顺序存储线性表的C++实现——严蔚敏版《数据结构》
- 【数据结构】双向循环线性表的基本操作--C++/C实现
- 数据结构(7)线性表之链表C++实现差集
- 数据结构(12)线性表之C++实现一元多项式相加
- 数据结构(14)线性表之C++实现一元多项式相乘
- c/c++ 数据结构-线性表(单链表基本操作的实现)
- 【c++版数据结构】之双链表的实现(带头结点以及尾节点)
- 【数据结构】用C++实现双链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- 数据结构(6)线性表之链表C++实现交集
- 【数据结构】双向循环线性表的基本操作--C++/C实现
- 【数据结构】双向循环线性表的基本操作--C++/C实现
- 【源代码】C++实现严蔚敏数据结构所有算法(一)线性表-顺序表
- 【算法和数据结构】线性表(一)线性表(C++实现)
- C++实现线性表的操作
- 数据结构之C++实现链式队列(LinkQueue)(无主函数)
- 数据结构学习之循环队列的另一种c++实现