双向循环链表涉及双向指针的基本操作,C语言

  链表大概分为有无头指针,有无尾指针,是否循环,单向还是双向,

这些都很简单,前提是你要把指针和单链表理解透彻。这些都是基于单链表

的变形,要根据实际问题,选择链表的类型。

  头指针的指针域储存着储存头节点的地址,其数据域我们不使用。

尾指针同理。

  循环链表的最后一个节点指向头节点(如果有头指针,则是指向头指针),

非循环链表的最后一个节点指向NUll。

  单向链表只有一个指针域,且指向下一个节点地址,

而双向链表有两个指针域,一个指向该节点的上一个节点地址,

另一个指向该节点的下一个节点地址。  

  构建链表节点:

1 #define ElemType int //链表元素类型
2 
3 //线性表的双向链表储存结构
4 typedef struct DuLNode {
5     ElemType data;    //数据域
6     struct DuLNode *prior; //前驱指针域
7     struct DuLNode *next;  //后继指针域
8        
9 }DuLNode;

  如果d为指向链表中某一个节点的指针 则显然满足

d->next->prior=d->prior->next=d
//d->next 表示d的上一个节点
//d->next->prior  表示d的上一个节点的下一个节点  即d本身
//-_-!有点绕啊

  双向循环链表中有一些操作只需要一个方向的指针,比如计算链表长度(这里全局变量iCount即为长度),

查找元素,返回元素位置等等(这些我都不想写 请原谅我的懒-_-) ,当然涉及两个方向的指针我都会贴出来的。

  

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define OK 1
 4 #define ERROR 0
 5 #define ElemType int //链表元素类型
 6 int iCount;             // 定义全局变量 表示链表长度
 7 //线性表的双向链表储存结构
 8 typedef struct DuLNode {
 9     ElemType data;    //数据域
10     struct DuLNode *prior; //前驱指针域
11     struct DuLNode *next;  //后继指针域
12        
13 }DuLNode;
14 //创建链表
15 DuLNode *CreateDuLNode() {
16     DuLNode *pHead , *pEnd, *pNew;
17     //头指针的初始化
18     pHead=(DuLNode*)malloc(sizeof(DuLNode));
19     pHead->prior = NULL;
20     pHead->next = NULL;
21     if (!pHead) exit(0);
22     
23     pNew = pEnd = (DuLNode*)malloc(sizeof(DuLNode));
24     if (!pNew) exit(0);
25     scanf("%d", &pNew->data);
26     while (pNew->data != 0 )  //读取到0结束
27     {
28         iCount++;
29         if (iCount == 1)
30         {
31             pNew->prior= pHead;
32             pNew->next = NULL;
33             pHead->next = pNew;
34             pEnd = pNew;
35             
36         }
37         else
38         {
39             pNew->prior = pEnd;
40             pNew->next = NULL;
41             pEnd->next = pNew;
42             pEnd = pNew;
43         }
44         pNew = (DuLNode*)malloc(sizeof(DuLNode));
45         if (!pNew) exit(0);
46         scanf("%d", &pNew->data);
47         
48     }
49     free(pNew);                //释放多余的空间
50     pHead->prior = pEnd;    //形成  
51     pEnd->next = pHead;        // 双循环
52     return pHead;
53 }
54 //插入节点
55 int DuLInsert(DuLNode *p, int i, DuLNode *s) {
56     /*在带头指针的的双链循环线性表p中的第i个位置
57 之前插入节点s,i的合法值为1<=i<=表长(头指针不算长度)+1 
58 i取最小值头插,i取最大值尾插*/
59     DuLNode *q;
60     if (i<1 || i>iCount + 1)  //i的值不合法
61         return ERROR;
62     
63     if (i == iCount + 1)  //在p中确定第i个元素的位置  指针q
64         q = p; 
65     else
66     for (q = p; i > 0; i--) 
67         q = q->next;  
68     //先插入 后修改  防止断链
69     q->prior->next = s;
70     s->prior = q->prior;
71     q->prior = s;
72     s->next = q;
73        
74     return OK;
75 }
76 //删除第i个节点,并用e返回删除值
77 int DuLDelete(DuLNode *p, int i, ElemType *e) {
78     /*在带头指针的的双链循环线性表p中的第i个位置
79 之前插入节点s,i的合法值为1<=i<=表长(头指针不算长度)+1 
80 i取最小值头删,i取最大值尾删*/
81     DuLNode *q;
82     if (i<1 || i>iCount + 1)  //i的值不合法
83         return ERROR;
84 
85      //在p中确定第i个元素的位置  指针q
86     for (q = p; i > 0; i--)
87             q = q->next;
88 
89                                                                                  
90     *e = q->data;
91     q->prior->next = q->next;
92     q->next->prior = q->prior;
93     free(q);
94     
95 
96     return OK;
97 }