双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
下边的代码实现数据结构的双向链表,可以作为基本的数据结构使用。同时由于实现了一些队列和栈的操作,也可以作为栈和队列使用。
#pragma once class Twowayslinklist { public: Twowayslinklist(void); Twowayslinklist(int value); Twowayslinklist(int value[], int length); Twowayslinklist(Twowayslinklist* linklist); ~Twowayslinklist(void); public: int m_value; Twowayslinklist* m_pnext; Twowayslinklist* m_pprior; public: void insertattail(int value); void insertathead(int value); void insertorder(int value); bool remove(int value); bool find(int value, Twowayslinklist** node); void positiveoutput(); void negtiveoutput(); void destroy(); int getnodenumber(); }; #include "stdafx.h" #include "Twowayslinklist.h" //构造一个单节点,一般用于构造链表头 Twowayslinklist::Twowayslinklist(void) { m_value = 0xFFFFFFFF; m_pnext = NULL; m_pprior = NULL; } //构造一个单节点,一般用于构造链表元素节点 Twowayslinklist::Twowayslinklist(int value) { m_value = value; m_pnext = NULL; m_pprior = NULL; } //用数组构造一个双向链表 Twowayslinklist::Twowayslinklist(int value[], int length) { m_pnext = NULL; m_pprior = NULL; m_value = 0xFFFFFFFF; for(int i=0; i<length; i++) { insertorder(value[i]); } } //克隆一个双向链表 Twowayslinklist::Twowayslinklist(Twowayslinklist* linklist) { m_pnext = NULL; m_pprior = NULL; m_value = 0xFFFFFFFF; Twowayslinklist* pafter = linklist; while(pafter->m_pnext != NULL) { insertorder(pafter->m_pnext->m_value); pafter = pafter->m_pnext; } } //析构函数 Twowayslinklist::~Twowayslinklist(void) { printf("destroy value=%d\n", m_value); } //正向遍历 void Twowayslinklist::positiveoutput() { Twowayslinklist* pafter = this; while(pafter->m_pnext != NULL) { printf("value=%d self=%08x prior=%08x next=%08x\n", pafter->m_value,pafter, pafter->m_pprior, pafter->m_pnext); pafter = pafter->m_pnext; } printf("value=%d self=%08x prior=%08x next=%08x\n", pafter->m_value, pafter, pafter->m_pprior, pafter->m_pnext); } //反向遍历 void Twowayslinklist::negtiveoutput() { Twowayslinklist* pafter = this; while(pafter->m_pnext != NULL) { pafter = pafter->m_pnext; } while(pafter->m_pprior != NULL) { printf("value=%d self=%08x prior=%08x next=%08x\n", pafter->m_value, pafter, pafter->m_pprior, pafter->m_pnext); pafter = pafter->m_pprior; } printf("value=%d self=%08x prior=%08x next=%08x\n", pafter->m_value, pafter, pafter->m_pprior, pafter->m_pnext); } //按照顺序插入元素 void Twowayslinklist::insertorder(int value) { Twowayslinklist* node = new Twowayslinklist(value); Twowayslinklist* pafter = this; while(pafter->m_pnext != NULL) { if(pafter->m_pnext->m_value >= value) { break; } else { pafter = pafter->m_pnext; } } Twowayslinklist* temp = pafter->m_pnext; pafter->m_pnext = node; node->m_pnext = temp; node->m_pprior = pafter; if (temp != NULL) { temp->m_pprior = node; } } //在双向链表的头部插入元素,可以用于栈操作 void Twowayslinklist::insertathead(int value) { Twowayslinklist* node = new Twowayslinklist(value); if (m_pnext == NULL) { this->m_pnext = node; node->m_pprior = this; } else { Twowayslinklist* temp = this->m_pnext; this->m_pnext = node; node->m_pnext = temp; node->m_pprior = this; temp->m_pprior = node; } } //在双向链表的尾部插入元素,可以用于队列操作 void Twowayslinklist::insertattail(int value) { Twowayslinklist* node = new Twowayslinklist(value); Twowayslinklist* pafter = this; while(pafter->m_pnext != NULL) { pafter = pafter->m_pnext; } pafter->m_pnext = node; node->m_pprior = pafter; } //删除一个特点节点 bool Twowayslinklist::remove(int value) { bool find = false; Twowayslinklist* pafter = this; while(pafter->m_pnext != NULL) { if (pafter->m_pnext->m_value == value) { find = true; break; } pafter = pafter->m_pnext; } if (find) { Twowayslinklist* temp = pafter->m_pnext; pafter->m_pnext = temp->m_pnext; if (pafter->m_pnext != NULL) { pafter->m_pnext->m_pprior = pafter; } } return find; } //查找一个特点节点 bool Twowayslinklist::find(int value, Twowayslinklist** node) { bool find = false; Twowayslinklist* pafter = this; while(pafter->m_pnext != NULL) { if (pafter->m_pnext->m_value == value) { find = true; break; } pafter = pafter->m_pnext; } if (find) { *node = pafter->m_pnext; } return find; } //销毁一个双向链表 void Twowayslinklist::destroy() { Twowayslinklist* pafter = this; while(pafter->m_pnext != NULL) { Twowayslinklist* temp = pafter->m_pnext; pafter->m_pnext = temp->m_pnext; delete temp; temp = NULL; } } int Twowayslinklist::getnodenumber() { int count = 0; Twowayslinklist* pafter = this; while(pafter->m_pnext != NULL) { count++; pafter = pafter->m_pnext; } return count; }
下边的内容为主函数进行测试:
// linklist.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Twowayslinklist.h" int _tmain(int argc, _TCHAR* argv[]) { int intarr[10]; //在双向链表的尾部插入 for(int i=0; i<10; i++) { intarr[i] = i * 10; } Twowayslinklist list(intarr, 10); list.positiveoutput(); printf("------------------------------\n"); list.negtiveoutput(); printf("size=%d\n", list.getnodenumber()); //在双向链表中有顺序的插入 /*list.insertorder(17); list.insertorder(15); list.insertorder(16); list.insertorder(1); list.insertorder(3); list.insertorder(9); list.insertorder(8); list.insertorder(2); //在双向链表的头部插入 for(int i=0; i<10; i++) { list.insertathead(i*10); }*/ /*list.output(); printf("-------------------------------------\n"); list.remove(0); list.remove(5); list.remove(9); list.output(); Twowayslinklist *node; bool result = list.find(9, &node); if(result) { printf("find = true value=%d\n", node->m_value); } else { printf("find = false\n"); }*/ //list.destroy(); //list.output(); getchar(); return 0; }