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

来源:互联网 发布:java工程师的职业规划 编辑:程序博客网 时间:2024/06/06 00:03


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

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

    下面我们基于单链表(见我的另一篇文章: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后面插入Xvoid 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=NULLif(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;elsecout<<"IsFirst函数有错误!!!\n";if(!IsLast(head) && IsLast(P))cout<<"节点P是表尾,值为:"<<P->element<<endl;elsecout<<"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";elsecout<<"FindLeft、FindRight、Find函数都没有问题!\n";Delete(8,P);cout<<"删除节点8后,再打印出(非循环)双链表的所有元素:\n";OutputLists(head);return 0;}

结果如下:





0 0
原创粉丝点击