1 //双向链表又称双链表。使用双链表的目的是为了解决在链表中访问直接前趋和直接后继的问题。因为在双链表中每个结点都有两个链指针,
2 //一个指向结点的直接前趋一个指向结点的直接后继,此时不论是向前趋方向查找还是向后继方向查找,其时间复杂度都只有O(l)
3
4 //双向链表带头结点的循环链表方式,头结点由first指示,它的data域或者不放指针,或者放一个特殊要求的指针,它的lLink指向双链表的
5 //尾结点,rLink指向双链表的首元结点
6 //假设指针p指向双向循环链表的某一结点,那么,p->lLink指示p所指结点的前趋结点,p->lLink->rLink中存放的是p所指结点的前趋结点的
7 //后继结点的地址,即p结点本身;p->rLink指示p所指结点的后继结点,p->rLink->lLink中存放的是p所指结点的后继结点的前趋地址即p本身
8
9
10 //双链表结构体的定义
11
12 typedef int DataTYpe;
13 typedef struct node//双向链表定义
14 {
15 DataType data;//结点数据
16 struct node *lLink, *rLink;//前趋与后继结点指针
17 }DblNode, *DblList;
18
19 //双链表初始化
20 void initDblList(DblList& first, DataType val)
21 {//创建双链表的头结点,它包含了一个用于某些特定情况的val
22 first = new Double;
23 if(!first){cerr<<"存储分配失败!\n"; exit(1);}
24 first->data = val;
25 first->rLink = first->lLink = first;
26 }
27 //双向链表的查找
28 DblNode *Search(DblList& first, DataType x, int d)
29 {//查找操作:在带头结点的双向链表中寻找其值等于x结点,若找到,则返回该结点的地址,否则返回NULL。
30 //参数d = 0,按前趋方向查找;d不等于0,按后继方向查找
31 DblNode *p = (d == 0)? first->lLink : first->rLink;
32 while(p != first && p->data != x)
33 {
34 p =(d==0)? p->lLink : p->rLink;
35 }
36 return (p != first)? p : NULL;//返回查找地址,返回NULL则失败
37 }
38 //双向链表的定位操作
39 DblNode *Locate(DblList& first, int i, int d)//d=0前趋定位,d不等于0后继定位
40 {//在带头结点的双向链表中按d所指方向寻找第i个结点的地址。若d=0,在前趋方向,寻找第i个结点;若d不等于0,在后继方向寻找第i各结点
41 if(first->rLink == first || i==0)//空表或i不合理返回NULL
42 return NULL;
43 DblNode *p= (d==0)? p->lLink :p->rLink;
44 for(int j=1; j<i; j++)//逐个结点检测
45 {
46 if(p == first)//链太短,推出搜索
47 break;
48 else
49 p = (d == 0) ? p->lLink : p->rLink;
50 }
51 return (p != first) ? p : NULL; //返回查找地址,返回NULL则失败
52 }
53
54 //双向链表的插入和删除,必须在参数表中指定是按前趋方向还是后继方向进行操作
55 //d = 0前插,d不等于0后插
56 int Insert(DblList& first, int i, DataType x, int d)
57 {//建立一个包含有值x的新结点,并将其按d指定的方向插入到第i个结点的位置
58 DblNode *p = Locate(first, i-1, d);//定位到第i-1的位置
59 if(p == NULL)//i不合理,插入失败
60 return 0;
61 DblNode *s = new DblNode;//创建新结点
62 if(!s){cerr<<"存储分配失败!\n"; exit(1);}
63 s->data = x;
64 if(d == 0)//在前趋方向插入
65 {
66 s->lLink = p->lLink;
67 p->lLink = s;
68 s->lLink->rLink = s;
69 s->rLink = p;
70 }
71 else//在后继方向插入
72 {
73 s->rLink = p->rLink;
74 p->rLink = s;
75 s->rLink->lLink = s;
76 s->lLink = p;
77 }
78 return 1;//插入成功
79 }
80
81 //双向链表删除算法Remove是按照d所指方向删除第i各结点,d=0,定位于前趋防线嗯上的第i各结点,d不等于0定位于后继方向上的第i个结点;
82 //把第i各结点从中分离出来,摘下被删结点,修改前趋结点的后继指针和后继结点的前趋指针;释放被删结点。
83 int Remove(DblList& first, int i, DataType& x, int d)
84 {//在带头结点的双向链表中按照d所指方向删除第i个结点,被删元素的值通过引用型参数x返回,若删除成功返回1,否则函数返回0
85 DblNode *p = Locate(first, i, d);//按d所指方向定位与第i个结点
86 if(p == NULL)//空表或i不合理,删除失败
87 return 0;//
88 p->rLink->lLink = p->lLink;
89 p->lLink->rLink = p->rLink;
90 x = p->data;
91 delete p;
92 return 1;
93 }
96 //静态链表每个结点由两个域构成:data域存储数据,link域存放链接指针。
97 //静态链表的结构定义
98 #define defaultSize 128 //默认数组大小
99 typedef int DatType;
100 typedef struct node //静态链表结点定义
101 {
102 DataType data; //结点数据
103 int link; //后继结点指针
104 }SLinkNode;
105 typedef struct staticList //静态链表结构定义
106 {
107 SLinkNode *elem; //结点数组
108 int maxSize, n; //链表最大容量和当前个数(长度)
109 }