C++ 数据结构与算法(三)线性表之双向链表
前面两篇是关于顺序表和单链表的,下面这个是双向链表,具体实现代码如下:
结点类文件(ListNode.h):
template<typename T> class DoubleList; template<typename T> class ListNode { private: ListNode():m_pprior(NULL),m_pnext(NULL) { } ListNode(const T item,ListNode<T>* pprior = NULL,ListNode<T>* pnext = NULL) { m_data = item; m_pprior = pprior; m_pnext = pnext; } ~ListNode() { m_pprior = NULL; m_pnext = NULL; } friend class DoubleList<T>; private: T m_data;//数据项 ListNode* m_pprior;//直接前驱指针 ListNode* m_pnext;//直接后继指针 };
双向链表类(DoubleList.h):
#include "ListNode.h" template<typename T> class DoubleList { public: DoubleList() {//使head指向它自己 head = new ListNode<T>(); head->m_pprior = head; head->m_pnext = head; } ~DoubleList() { EmptyList(); delete head; } public: void EmptyList();//清空链表 int Length() const;//链表长度 ListNode<T>* Find(T item);//查找与item相等的数据项 bool Insert(const T item,int n =0);//插入item到第n个数据项,即第n+1个开始都往后移 void Delete(int n);//删除第n个数据结点 T GetData(int n) const;//获得第n个数据结点 void Print();//遍历输出链表所有结点数据 private: ListNode<T>* head; }; template<typename T> void DoubleList<T>::EmptyList() {//清空链表 ListNode<T>* p = head->m_pnext; ListNode<T>* pdel; while(p!=head) { pdel = p; p = pdel->m_pnext; delete pdel; } p->m_pprior = head; p->m_pnext = head; } template<typename T> int DoubleList<T>::Length() const {//获取链表长度 int count = 0; ListNode<T>* p = head->m_pnext; while(p!= head) { count ++; p = p->m_pnext; } return count; } template<typename T> ListNode<T>* DoubleList<T>::Find(T item) {//双向查找 ListNode<T>* pprior = head->m_pprior; ListNode<T>* pnext = head->m_pnext; while(pprior->m_pnext != pnext && pprior != pnext) { if(pprior->m_data == item) return pprior; if(pnext->m_data == item) return pnext; pprior = pprior->m_pprior; pnext = pnext->m_pnext; } return NULL;//没有找到 } template<typename T> bool DoubleList<T>::Insert(const T item,int n) {//插入数据元素 if(n < 0) return false; ListNode<T>* pnewnode = new ListNode<T>(item); ListNode<T>* p = head; for(int i =0 ;i< n;i ++) {//让p指向要插入结点位置 p = p->m_pnext; if(p == head) return false; } //插入结点 pnewnode->m_pnext = p->m_pnext; pnewnode->m_pprior = p; p->m_pnext = pnewnode; p->m_pnext->m_pprior = pnewnode; return true; } template<typename T> void DoubleList<T>::Delete(int n) { if(n < 0) return; ListNode<T>* p = head; ListNode<T>* pdel; for(int i =0; i< n ;i++) {//找到第n个位置 p = p->m_pnext; if(p == head) { return; } } //删除结点 pdel = p; p->m_pprior->m_pnext = p->m_pnext; p->m_pnext->m_pprior = p->m_pprior; delete pdel; } template<typename T> T DoubleList<T>::GetData(int n) const { if(n < 0) return NULL; ListNode<T>* p = head; for(int i =0; i< n ;i++) {//找到第n个位置 p = p->m_pnext; if(p == head) { return NULL; } } T data = p->m_data; return data; } template<typename T> void DoubleList<T>::Print() { ListNode<T>* p = head->m_pnext;//p指向第一个结点 cout << "head" ; while(p != head) { cout << "-->" << p->m_data ; p = p->m_pnext; } cout <<"-->over" << endl ; }
测试类(Doublelist.cpp):
// Doublelist.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "DoubleList.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { DoubleList<int> doublelist; for(int i=0;i<10;i++){ doublelist.Insert(i*3,i); } int data = doublelist.GetData(3); doublelist.Print(); cout << doublelist.Length() << endl; cout << data <<endl; doublelist.Insert(88888,5); doublelist.Print(); cin.get(); return 0; }
测试截图: