版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40411915/article/details/82718654
学习参考: 严蔚敏: 《数据结构-C语言版》
-----和单链表类似,双链表一般也是由头指针唯一确定的,增加头指针也能使双链表上的某些运算变得方便,将头结点和尾结点链接起来也能构成循环链表,并称之为双向链表。
双向链表的基本操作
- 双向链表的建立
- 双向链表添加结点(头插法)
- 双向链表添加结点(尾插法)
- 双向链表的输出
- 双向链表的插入
- 双向链表的删除
- 双向链表按序号查找
- 双向链表按值查找
- 双向链表销毁
- 双向链表的长度
基本操作代码实现
双向链表的结点定义
typedef struct node
{
struct node* next;
struct node* prior;
int data;
}* pNode, Node;
双向链表的结构定义
typedef struct
{
pNode node;
int len;
}DoubleList,* pDList;
双向链表的建立
int initDoubleList(pDList list)
{
if(!list)
return 0;
list->len = 0;
list->node = NULL;
return 1;
}
双向链表添加结点(头插法)
int addDataHead(pDList list, int data)
{
pNode q = NULL, p = NULL;
if(!list)
return 0;
p = list->node;
q = (pNode)malloc(sizeof(Node));
if(!q)
return 0;
q->data = data;
if(!p)
{
q->next = NULL;
list->node = q;
q->prior = NULL;
}
else
{
list->node = q;
q->next = p;
p->prior = q;
q->prior = NULL;
}
list->len++;
return 1;
}
双向链表添加结点(尾插法)
int addDataTail(pDList list, int data)
{
pNode pre = NULL, p = NULL;
if(!list)
return 0;
p = list->node;
while(p)
{
pre = p;
p=p->next;
}
p = (pNode)malloc(sizeof(Node));
if(!p)
return 0;
p->next = NULL;
p->data = data;
if(!pre)
{
list->node = p;
p->prior = NULL;
}
else
{
p->prior = pre;
pre->next = p;
}
list->len ++;
return 1;
}
双向链表的输出
int display(pDList list)
{
pNode p = NULL;
if(!list->node)
return 0;
p = list->node;
while(p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return 1;
}
双向链表的插入
int insertData(pDList list, int pos, int data)
{
pNode LacNode = NULL, p = NULL;
int count = 1;
if(!list || pos<1 || pos>list->len+1)
return 0;
LacNode = list->node;
while( count<pos)
{
count++;
LacNode = LacNode->next;
}
if(!LacNode)
{
addDataTail(list, data);
return 1;
}
p = (pNode)malloc(sizeof(Node));
p->data = data;
p->prior = LacNode->prior;
LacNode->prior->next = p;
LacNode->prior = p;
p->next = LacNode;
list->len++;
return 1;
}
双向链表的删除
int deleteData(pDList list, int pos, int* data)
{
pNode LacNode = NULL, p = NULL;
int count = 1;
if(!list || !list->node || pos<1 || pos>list->len+1)
return 0;
LacNode = list->node;
while(count<pos)
{
count++;
LacNode = LacNode->next;
}
if(count==1)
{
*data = LacNode->data;
free(LacNode);
LacNode = NULL;
list->node = NULL;
}
else if(count==list->len)
{
LacNode->prior->next = NULL;
*data = LacNode->data;
free(LacNode);
LacNode = NULL;
}else
{
LacNode->next->prior = LacNode->prior;
LacNode->prior->next = LacNode->next;
*data = LacNode->data;
free(LacNode);
LacNode = NULL;
}
list->len --;
return 1;
}
双向链表按序号查找
int getData(pDList list, int pos, int* data)
{
pNode p = NULL;
int count = 1;
if(!list || pos<1 || pos >list->len || !list->node)
{
*data = -1;
return 0;
}
p = list->node;
while( count<pos)
{
count++;
p = p->next;
}
*data = p->data;
return 1;
}
双向链表按值查找
int getLacate(pDList list, int data, int* index)
{
pNode p = NULL;
int count = 0;
if(!list || !list->node)
{
*index = -1;
return 0;
}
p = list->node;
while(p)
{
count++;
if(p->data == data)
break;
p = p->next;
}
if(!p)
{
*index = -1;
return 0;
}
*index = count;
return 1;
}
双向链表销毁
int destroyData(pDList list)
{
pNode pre = NULL, p = NULL;
if(!list || !list->node)
return 0;
p = list->node;
while(p)
{
pre = p;
p = pre->next;
free(pre);
pre = NULL;
}
list->len =0;
list->node =NULL;
return 1;
}
双向链表的长度
int getLength(pDList list, int* len)
{
if(!list)
return 0;
*len = list->len;
return 1;
}
测试代码
#include <stdio.h>
#include "DoubleList.h"
int main()
{
DoubleList list;
int val = -1;
int i = 1;
initDoubleList(&list);
for(i; i<6; ++i)
addDataHead(&list, i);
display(&list);
for(i=11; i<16; ++i)
addDataTail(&list, i);
for(i; i<6; ++i)
insertData(&list, i, i);
display(&list);
deleteData(&list, 2, &val);
printf("%d...\n", val);
display(&list);
getData(&list, 5, &val);
printf("第5个位置上的数字: %d...\n", val);
getLacate(&list, 11, &val);
printf("11号位置为: %d...\n", val);
display(&list);
destroyData(&list);
display(&list);
return 0;
}
写在最后
文章记录本人学习所得, 如有所错误, 欢迎留言指出交流, 大神请键盘下留人 ! ! !