双向链表
双向链表,也叫双链表,它的每个节点中都有两个指针,一个指向它的直接前驱,一个指向它的直接后继。
对于文章中介绍的双向链表,它的头只有直接后继,没有前驱;它的尾只有直接前驱,没有后继,从双向链表的任何一个节点,都可以直接访问它的前驱和后继。
储存结构描述
typedef struct Node
{
int data;//数据
struct Node* precursor;//前驱
struct Node* next;//后继
}dList, * DListLink;
双向链表的初始化
令头结点的后继和前驱都指向NULL;
//初始化双向链表;
DListLink InitDList(DListLink L)
{
L = (DListLink)malloc(sizeof(dList));
L->next = NULL;
L->precursor = NULL;
return L;
}
插入数据
先循环链表L1,直到L1->next = NULL;
此时定义一个指针p储存数据,让p的后继指向L1的后继,p的前驱指向L1,L1的后继指向p
//插入数据;
DListLink InsertDList(DListLink L, int data)
{
DListLink p = (DListLink)malloc(sizeof(dList));
DListLink L1 = L;
while (L1->next != NULL)
{
L1 = L1->next;
}
p->data = data;
p->next = L1->next;
p->precursor = L1;
L1->next = p;
return L;
}
删除链表中的数据
循环链表L,直到L->next= NULL,
如果L->next->data = data,就定义一个指针q 指向此时的L->next,
如果q的后继为空,也就是说循环到了最后一个数,让q的前驱的后继等于q的后
继,以实现删除最后一个数的目的;
如果q的后继不为空,就进行正常操作,q的后继的前驱指向q的前驱,
q的前驱的后继指向q的后继,这两条语句不可颠倒;
//删除链表数据
DListLink DeletedList(DListLink L, int data)
{
DListLink p = L;
DListLink q = (DListLink)malloc(sizeof(dList));
while (L->next)
{
if (L->next->data == data)
{
q = L->next;
if (q->next == NULL)
{
q->precursor->next= q->next;
break;
}
q->next->precursor = q->precursor;
q->precursor->next = q->next;
}
L = L->next;
}
return p;
}
求一个数值的前驱和后继
//求前驱和后继
void printPre_next(DListLink p, int data)
{
DListLink q = p->next;
while (q)
{
if (q->data == data)
{
if (q->next == NULL)
{
printf("后继:NULL");
}
else
{
printf("后继:%d\n", q->next->data);
}
if (q->precursor == NULL)
{
printf("前驱:NULL");
}
else
{
printf("前驱:%d\n", q->precursor->data);
}
break;
}
q = q->next;
}
}
完整代码
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct Node
{
int data;
struct Node* precursor;
struct Node* next;
}dList, * DListLink;
//初始化双向链表;
DListLink InitDList(DListLink L)
{
L = (DListLink)malloc(sizeof(dList));
L->next = NULL;
L->precursor = NULL;
return L;
}
//插入数据;
DListLink InsertDList(DListLink L, int data)
{
DListLink p = (DListLink)malloc(sizeof(dList));
DListLink L1 = L;
while (L1->next != NULL)
{
L1 = L1->next;
}
p->data = data;
p->next = L1->next;
p->precursor = L1;
L1->next = p;
return L;
}
//删除链表数据
DListLink DeletedList(DListLink L, int data)
{
DListLink p = L;
DListLink q = (DListLink)malloc(sizeof(dList));
while (L->next)
{
if (L->next->data == data)
{
q = L->next;
if (q->next == NULL)
{
q->precursor->next= q->next;
break;
}
q->next->precursor = q->precursor;
q->precursor->next = q->next;
}
L = L->next;
}
return p;
}
//求前驱和后继
void printPre_next(DListLink p, int data)
{
DListLink q = p->next;
while (q)
{
if (q->data == data)
{
if (q->next == NULL)
{
printf("后继:NULL");
}
else
{
printf("后继:%d\n", q->next->data);
}
if (q->precursor == NULL)
{
printf("前驱:NULL");
}
else
{
printf("前驱:%d\n", q->precursor->data);
}
break;
}
q = q->next;
}
}
//打印数据
void printList(DListLink L)
{
DListLink p = L->next;
while (p->next)
{
printf("%d ", p->data);
p = p->next;
}
printf("%d ", p->data);
printf("\n");
while (p->precursor)
{
printf("%d ", p->data);
p = p->precursor;
}
}
int main()
{
/*DListLink L = (DListLink)malloc(sizeof(dList));
L = InitDList(L);
int i = 0;
int n;
scanf("%d", &n);
if (n == 0)
return 0;
for (int i = 0; i < n; i++)
{
int data;
scanf("%d", &data);
L = InsertDList(L, data);
}
L = DeletedList(L, 5);
printPre_next(L, 3);
printList(L);
*/
}