数据结构(C达到)------- 双链表

时间:2023-01-02 08:56:38

双链表中的每个节点包含两个指针域,指针域包含其后继节点的内存地址,还有一个指针所存储的存储器地址其领域前驱节点。

双向链表结点的类型描写叙述:

//双向链表的类型描写叙述
typedef int ElemType;
typedef struct node{
ElemType data;
struct node *prior,*next;
}DuLNode,*DuLinkList;

当中。prior域存放的是其前驱结点的存储地址,next域存放的是其后继结点的存储地址。

双向链表有两个特点:一是能够从两个方向搜索某个结点,这使得链表的某些操作(如插入和删除)变得比較简单; 二是不管利用前链还是后链都能够遍历整个双向链表。

双向链表的操作基本和单链表的操作同样。

1. 头插法创建带头结点的双向链表Create_DLinkListF(int n)

//头插法创建带头结点的双向链表
DuLinkList Create_DLinkListF(int n){
DuLinkList L,p;
int i = n - 1;
ElemType x;
//新建头结点
L = (DuLinkList)malloc(sizeof(DuLNode));
L->prior = NULL;
L->next = NULL; //加入第一个结点
scanf("%d",&x);
p = (DuLinkList)malloc(sizeof(DuLNode));
p->data = x;
L->next = p;
p->prior = L;
p->next = NULL; //加入其它结点
while(i > 0){
scanf("%d",&x);
p = (DuLinkList)malloc(sizeof(DuLNode));
p->data = x; p->next = L->next;
L->next->prior = p;
p->prior = L;
L->next = p; i--;
}
return L;
}

2. 尾插法创建带头结点的双向链表Create_DLinkListR(int n)

//尾插法创建带头结点的双向链表
DuLinkList Create_DLinkListR(int n){
DuLinkList L,p,lastNode;
int i = n - 1;
ElemType x;
//新建头结点
L = (DuLinkList)malloc(sizeof(DuLNode));
L->prior = NULL;
L->next = NULL; //加入第一个结点
scanf("%d",&x);
p = (DuLinkList)malloc(sizeof(DuLNode));
p->data = x;
L->next = p;
p->prior = L;
p->next = NULL; lastNode = p;
//加入其它结点
while(i > 0){
scanf("%d",&x);
p = (DuLinkList)malloc(sizeof(DuLNode));
p->data = x; lastNode->next = p;
p->prior = lastNode;
p->next = NULL; lastNode = p;
i--; }
return L; }

3. 在指定结点之前插入新结点Insert_DLinkListBefore(DuLinkList p,ElemType x)

//在指定结点之前插入新结点
void Insert_DLinkListBefore(DuLinkList p,ElemType x){
DuLinkList newNode;
//推断结点p之前的结点的合法性:
if(p->prior == NULL)
printf("结点不合法。不能在该结点之前插入结点\n");
else{
newNode = (DuLinkList)malloc(sizeof(DuLNode));
newNode->data = x; newNode->next = p;
p->prior->next = newNode;
newNode->prior = p->prior;
p->prior = newNode;
}
}

4. 在指定结点之后插入新结点Insert_DLinkListAfter(DuLinkList p,ElemType x)

//在指定结点之后插入新结点
void Insert_DLinkListAfter(DuLinkList p,ElemType x){ DuLinkList newNode;
newNode = (DuLinkList)malloc(sizeof(DuLNode));
newNode->data = x; //当插入位置是最后一个结点之后时
if(p->next == NULL){
p->next = newNode;
newNode->prior = p;
newNode->next = NULL;
}
else{
newNode->next = p->next;
p->next->prior = newNode;
p->next = newNode;
newNode->prior = p;
}
}

5. 删除指定结点Delete_DLinkList(DuLinkList p)

//删除指定结点
void Delete_DLinkList(DuLinkList p){
//假设删除的是最后一个元素
if(p->next == NULL)
p->prior->next = NULL; else{
p->prior->next = p->next;
p->next->prior = p->prior; }
free(p);
}

6. 后链输出双向链表Print_DLinkListN(DuLinkList L)

//后链输出双向链表
void Print_DLinkListN(DuLinkList p){ while(p != NULL){
printf("%d\t",p->data);
p = p->next;
}
printf("\n"); }

7.前链输出双向链表Print_DLinkListP(DuLinkList p)

//前链输出双向链表
void Print_DLinkListP(DuLinkList p){ while(p != NULL){
printf("%d\t",p->data);
p = p-prior;
}
printf("\n");
}

至于双向链表的其它操作。如定位。和单链表的操作类同,不再赘述。

版权声明:本文博主原创文章,博客,未经同意不得转载。