链表大概分为有无头指针,有无尾指针,是否循环,单向还是双向,
这些都很简单,前提是你要把指针和单链表理解透彻。这些都是基于单链表
的变形,要根据实际问题,选择链表的类型。
头指针的指针域储存着储存头节点的地址,其数据域我们不使用。
尾指针同理。
循环链表的最后一个节点指向头节点(如果有头指针,则是指向头指针),
非循环链表的最后一个节点指向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 }