现在的位置: 首页 > 综合 > 正文

数据结构—-线性表—-双向链表

2019年01月10日 ⁄ 综合 ⁄ 共 4886字 ⁄ 字号 评论关闭

 

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表

 

下边的代码实现数据结构的双向链表,可以作为基本的数据结构使用。同时由于实现了一些队列和栈的操作,也可以作为栈和队列使用。

 

#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;
}

 

 

抱歉!评论已关闭.