C++实现的双链表通用模板



    双链表是在单链表的基础上提出来的另一种链表形式。顾名思义,单链表只有一个指针,而双链表有两个指针:一个前驱指针,一个后继指针。双链表的每一个节点仍然是一个结构体,与单链表唯一不同的是,节点额外多了一个指向前节点的指针,这是为了方便有时候需要倒序扫描链表。双链表有两种形式:一般的双链表和循环双链表。如图:

循环双链表只是把头节点与尾节点相互连接起来了,如图:

    下面我们基于单链表(见我的另一篇文章:http://blog.csdn.net/wonggonghong/article/details/21527577),首先实现一个一般的双链表。在下一篇文章里,我们再实现一个双向循环链表。事实上,代码的改动并不是很大。

    类似地,我们在<List.h>头文件里声明双链表结构:

#include "list.h"

//创建一个非循环的双链表结构,包含一些常见的操作
#ifndef _List_H_
#define _List_H_

#include <iostream>

struct Double_Node{
	int element;  //节点存储信息可以根据需要修改!
	Double_Node* previous;
	Double_Node* next;
};

Double_Node* CreateLists(int X); //创建一个值为X的双链表节点
void DeleteLists(Double_Node* head); //删除表头为head的该链表
bool IsFirst(Double_Node* P);
bool IsLast(Double_Node* P);
Double_Node* FindLeft(int X, Double_Node* P);  //从P开始向P的左边进行查找
Double_Node* FindRight(int X, Double_Node* P); //从P开始向P的右边进行查找
Double_Node* Find(int X, Double_Node* head);   //从整个双链表中查找
void Delete(int X, Double_Node* Lists);
void Insert(Double_Node* P, int X); //在节点P后面插入X
void OutputLists(Double_Node* head); //输出链表中所有元素的值

#endif

    然后,在<List.cpp>文件里实现双链表操作(注意与单链表略有些不同):

#include "list.cpp"

#include "list.h"
#include <assert.h>

Double_Node* CreateLists(int X)
{
	Double_Node* head = new Double_Node;
	head->previous = head->next = NULL;
	head->element = X;
	return head;
}

void DeleteLists(Double_Node* head)  
{  
      assert(!head->previous); //验证head为表头!  
      Double_Node* P = head, *temp;  
      while(P)  
      {  
         temp = P->next; 
         if(temp)
         {
               temp->previous = NULL;
               P->next = NULL;  
         }     
         delete P;  
         P = temp;  
      }  
}

bool IsFirst(Double_Node* P)
{
	return P->previous == NULL;
}

bool IsLast(Double_Node* P)
{
	return P->next == NULL;
}

Double_Node* FindLeft(int X, Double_Node* P)
{
	Double_Node* temp = P;
	while(temp && temp->element!=X)
		temp = temp->previous;
	return temp;
}

Double_Node* FindRight(int X, Double_Node* P)
{
	Double_Node* temp = P;
	while(temp && temp->element!=X)
		temp = temp->next;
	return temp;
}

Double_Node* Find(int X, Double_Node* P)
{
	Double_Node* temp = FindLeft(X,P);
	return temp?temp:FindRight(X,P);
}

void Delete(int X, Double_Node* Lists)
{
	Double_Node* temp = Find(X,Lists); //如果没找到X,则temp=NULL
	if(temp)
	{
		  if(temp->previous)
                        temp->previous->next = temp->next;
                  if(temp->next)
                        temp->next->previous = temp->previous;
		  temp->previous = temp->next = NULL;
		  delete temp;
	}
}

void Insert(Double_Node* P, int X)
{
	Double_Node* tempX = new Double_Node;
	tempX->element = X;
	tempX->previous = P;
	tempX->next = P->next;
	if(P->next)
	   P->next->previous = tempX;	   
	P->next = tempX;
}

void OutputLists(Double_Node* head)
{
	assert(!head->previous);
	Double_Node* P = head;
	while(P)
	{
		std::cout<<P->element<<"   ";
		P = P->next;
	}
	std::cout<<std::endl;
}

    最后,同样用一段main代码验证一下:

#include <iostream>
#include "list.h"

using namespace std;

int main()
{
	int Data[10] = {1,3,4,6,0,2,5,8,12,13};
	Double_Node* head = CreateLists(1);
	Double_Node* P = head;
	for(int i=1;i<10;i++)
	{
		Insert(P,Data[i]);
		P = P->next;
	}
	cout<<"打印出(非循环)双链表的所有元素:\n";
	OutputLists(head);
	if(IsFirst(head) && !IsFirst(P))
		cout<<"节点head是双链表的表头,节点值为:"<<head->element<<endl;
	else
		cout<<"IsFirst函数有错误!!!\n";
	if(!IsLast(head) && IsLast(P))
		cout<<"节点P是表尾,值为:"<<P->element<<endl;
	else
		cout<<"IsLast函数有错误!!!\n";
	P = P->previous->previous;
	if(FindLeft(12,P))
		cout<<"FindLeft函数错误!\n";
	else if(!FindRight(12,P))
		cout<<"FindRight函数错误!\n";
	else if(!Find(4,P) || !Find(13,P))
		cout<<"Find函数错误!\n";
	else
		cout<<"FindLeft、FindRight、Find函数都没有问题!\n";
	Delete(8,P);
	cout<<"删除节点8后,再打印出(非循环)双链表的所有元素:\n";
	OutputLists(head);
	return 0;
}

结果如下:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值