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
- C++实现的双链表通用模板
- 【C++】通过模板实现一个通用的冒泡排序
- 一个C/C++通用的Makefile模板
- 模板实现的通用工厂方法模式
- C++实现的单链表通用模板
- 模板类 通用数组的实现
- C/C++ 通用 Makefile模板
- 通用的makefile模板
- makefile的通用模板
- 通用进度条的设计与实现【C#】
- 一个通用纯C队列的实现
- 代理模式通用模板实现
- C++模板来实现一个通用的内存池.
- PowerBuilder中通用组合条件查询模板的实现
- PowerBuilder中通用组合条件查询模板的实现
- C++模板实现的通用工厂方法模式
- C++模板实现的通用工厂方法模式
- C++模板实现的通用工厂方法模式
- 硬盘导入文件失败怎么恢复
- 十多个
- 为confluence编辑器增加设置字体和设置字号的选项
- FLEX页面(mxml)获取当前时间
- mysql允许外部IP访问
- C++实现的双链表通用模板
- nyoj 542 map vector使用
- wireshark解析流媒体中的AMR/H263/H264包的方法
- Linux下使用rsync最快速删除海量文件的方法
- 爱的一种解释
- Matlab信号处理工具箱函数
- C#调用WebService实现天气预报
- nyoj 306 搜索+二分
- jax-ws使用实例