双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
下边的代码实现数据结构的双向链表,可以作为基本的数据结构使用。同时由于实现了一些队列和栈的操作,也可以作为栈和队列使用。
#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;
}