数据结构——双向链表的实现

双向链表主要为了解决单链表找前驱的问题。除了插入、删除操作之外,其他操作与单链表都相同。因此这里只是比较简单的写了双向链表的插入和删除操作。画出结点结构图的话,思路会很清晰,线性表这块还算是比较简单的能够实现。

  1 /*
  2     在单链表中,求后继的方法NextElem执行的时间为O(1),求前驱的方法PriorElem执行的时间为O(n),
  3     引入双向链表就是为了克服单链表这种单向性的缺点。
  4 */
  5 
  6 #include<stdio.h>
  7 #include<stdlib.h>
  8 
  9 //定义存储类型
 10 typedef int ElemType;
 11 
 12 //双向链表的存储结构
 13 typedef struct DuLNode{
 14     ElemType data;
 15     DuLNode *next;
 16     DuLNode *prior;
 17 }DuLNode, *DuLinkList;
 18 
 19 //声明,指针函数
 20 void(*visit)(DuLNode *node);
 21 
 22 //声明,辅助函数
 23 void visitData(DuLNode *node);
 24 
 25 //对双向链表的基本操作
 26 bool InitDuLinkList(DuLinkList &L);    //    初始化一个空表
 27 DuLinkList GetLNode(DuLinkList L, int i);    //返回第i个结点
 28 void ListTraverse(DuLinkList L, void(visit(DuLNode *node)));    //遍历双向链表
 29 void ListInsert(DuLinkList &L, int i, ElemType e);    //在第i个结点之前插入,数据域是e的结点
 30 void AppendLast(DuLinkList &L, ElemType e);    //在最后一个结点之后插入,数据域是e的结点
 31 void ListDelete(DuLinkList &L, int i, DuLinkList &rNode);    //删除第i个结点并返回
 32 
 33 //测试模块
 34 int main(){
 35 
 36     DuLinkList L;
 37     InitDuLinkList(L);
 38     for (int i = 1; i <= 6; i++)
 39         AppendLast(L, i);
 40     ListTraverse(L, visitData);
 41     printf("\n");
 42 
 43     printf("第一个元素的后继是:%d\n", GetLNode(L, 1)->next->data);
 44     printf("第一个元素的前驱是:%d\n", GetLNode(L, 1)->prior->data);
 45     printf("最后一个元素的前驱是:%d\n", GetLNode(L, 6)->prior->data);
 46     printf("\n");
 47 
 48     ListInsert(L, 1, 7);
 49     ListTraverse(L, visitData);
 50     printf("第一个元素的后继是:%d\n", GetLNode(L, 1)->next->data);
 51     printf("第一个元素的前驱是:%d\n\n", GetLNode(L, 1)->prior->data);
 52 
 53     DuLNode *rNode;
 54     ListDelete(L, 7, rNode);
 55     ListTraverse(L, visitData);
 56     printf("最后一个元素的前驱是:%d\n", GetLNode(L, 6)->prior->data);
 57     ListDelete(L, 1, rNode);
 58     ListTraverse(L, visitData);
 59     printf("第一个元素的后继是:%d\n", GetLNode(L, 1)->next->data);
 60     printf("第一个元素的前驱是:%d\n\n", GetLNode(L, 1)->prior->data);
 61     
 62     system("pause");
 63     return 0;
 64 }
 65 
 66 //各函数定义模块
 67 void visitData(DuLNode *node){
 68     printf("%4d", node->data);
 69 }
 70 
 71 bool InitDuLinkList(DuLinkList &L){    //    初始化一个空表
 72     L = (DuLinkList)malloc(sizeof(DuLNode));
 73     if (!L)
 74         return false;
 75     L->prior = NULL;
 76     L->next = NULL;
 77     return true;
 78 }
 79 
 80 DuLinkList GetLNode(DuLinkList L, int i){    //返回第i个结点的值
 81     int j = 1;
 82     DuLNode *p = L->next;
 83 
 84     //找第i个结点
 85     while (p && j != i){
 86         p = p->next;
 87         j++;
 88     }
 89 
 90     if (j > i || !p){
 91         printf("\n不存在该结点!\n");
 92         return L;
 93     }
 94 
 95     return p;
 96 }
 97 
 98 void ListTraverse(DuLinkList L, void(visit(DuLNode *node))){    //遍历单链表
 99     DuLNode *p = L->next;
100     while (p){
101         visit(p);
102         p = p->next;
103     }
104     printf("\n");
105 }
106 
107 void ListInsert(DuLinkList &L, int i, ElemType e){    //在第i个结点之前插入,数据域是e的结点
108     DuLNode *p = GetLNode(L, i);
109     if (!p){
110         printf("没找到该元素,不能进行插入!\n");
111         return;
112     }
113 
114     DuLNode *s = (DuLinkList)malloc(sizeof(DuLNode));
115     if (!s)
116         return;
117     s->data = e;
118     s->next = p;
119     p->prior->next = s;
120     s->prior = p->prior;
121     p->prior = s;
122 }
123 
124 void AppendLast(DuLinkList &L, ElemType e){    //在最后一个结点之后插入,数据域是e的结点
125     //找到最后一个结点
126     DuLNode *p = L;
127     while (p->next){
128         p = p->next;
129     }
130     //新建一个结点
131     DuLNode *newNode = (DuLinkList)malloc(sizeof(DuLNode));
132     if (!newNode)
133         return;
134     newNode->data = e;
135     //插入
136     newNode->next = p->next;
137     p->next = newNode;
138     newNode->prior = p;
139 }
140 
141 void ListDelete(DuLinkList &L, int i, DuLinkList &rNode){    //删除第i个结点并返回
142     DuLNode *p = GetLNode(L, i);
143     if (!p){
144         printf("没找到该元素,不能进行删除!\n");
145         return;
146     }
147 
148     p->prior->next = p->next;
149     if (p->next){
150         p->next->prior = p->prior;
151         p->next = NULL;
152         p->prior = NULL;
153     }
154 
155     rNode = p;
156     free(p);
157 }

 

转载于:https://www.cnblogs.com/yangxiaohe/p/6280208.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值