双向链表
双向链表的结构
双向链表的结点包括三个部分:前驱指针域、数据域和后继指针域:
- 前驱指针域,又称为左链指针,用于存放一个指针,该指针指向上一个结点的开始存储地址;
- 数据域,用于存储该结点的数据元素,数据元素类型由应用问题决定。
- 后继指针域,又称为右链指针,用于存放一个指针,该指针指向下一个结点的开始存储地址。
双向链表的实现
结构体设计
typedef struct Node {
ElemType data;
struct Node *prior;
struct Node *next;
} Node;
typedef struct Node * LinkList;
双向链表的创建
Status CreateLinkList(LinkList *L) {
*L = (LinkList)malloc(sizeof(Node));
if (*L == NULL) return ERROR;
(*L)->prior = NULL;
(*L)->next = NULL;
(*L)->data = -1;
LinkList p = *L;
for (int i = 1; i <= 10; i++) {
LinkList temp = (LinkList)malloc(sizeof(Node));
if (temp == NULL) return ERROR;
temp->data = i;
temp->prior = NULL;
temp->next = NULL;
p->next = temp;
temp->prior = p;
p = p->next;
}
return OK;
}
双向链表的插入
Status LinkListInsert(LinkList *L, int place, int num) {
if (place < 1) return ERROR;
LinkList temp = (LinkList)malloc(sizeof(Node));
temp->prior = NULL;
temp->next = NULL;
temp->data = num;
LinkList p = *L;
for (int i = 1; i < place && p != NULL; i++) {
p = p->next;
}
if (p == NULL) return ERROR;
if (p->next == NULL) {
p->next = temp;
temp->prior = p;
} else {
temp->next = p->next;
p->next->prior = temp;
p->next = temp;
temp->prior = p;
}
return OK;
}
双向链表的删除
删除指定位置
Status LinkListDelete(LinkList *L, int place, ElemType *e) {
if (place < 1 || *L == NULL) return ERROR;
LinkList p = *L;
for (int i = 1; i < place && p != NULL; i++) {
p = p->next;
}
if (p == NULL) return ERROR;
LinkList deleteItem = p->next;
*e = deleteItem->data;
p->next = deleteItem->next;
if (deleteItem->next != NULL) {
deleteItem->next->prior = p;
}
free(deleteItem);
return OK;
}
删除指定元素
Status LinkListDeleteValue(LinkList *L, ElemType value) {
LinkList p = *L;
while (p) {
if (p->data == value) {
p->prior->next = p->next;
if (p->next != NULL) {
p->next->prior = p->prior;
}
free(p);
break;
}
p = p->next;
}
return OK;
}
双向链表的查找
int LocateElem(LinkList L, ElemType value) {
LinkList p = L->next;
int i = 1;
while (p) {
if (p->data == value) {
return i;
}
i++;
p = p->next;
}
return ERROR;
}
双向链表的遍历输出
void TraverseLinkList(LinkList L) {
LinkList temp = L->next;
if(temp == NULL){
printf("打印的双向链表为空!\n");
return;
}
while (temp) {
printf("%d_%d_%d ", temp->prior ? temp->prior->data : -1, temp->data, temp->next ? temp->next->data : -1);
temp = temp->next;
}
printf("\n");
}
双向循环链表
双向循环链表和双向链表的唯一区别在于循环,尾结点的next指针会指向头结点,头结点的prior指针会指向尾结点
双向循环链表的创建
Status CreateLinkList(LinkList *L) {
*L = (LinkList)malloc(sizeof(Node));
if (*L == NULL) return ERROR;
(*L)->next = *L;
(*L)->prior = *L;
(*L)->data = -1;
LinkList p = *L;
for (int i = 10; i < 15; i++) {
LinkList temp = (LinkList)malloc(sizeof(Node));
if (temp == NULL) return ERROR;
temp->data = i;
p->next = temp;
temp->prior = p;
temp->next = (*L);
p = p->next;
}
return OK;
}
双向循环链表插入
Status LinkListInsert(LinkList *L, int place, ElemType num) {
if (place < 1) return ERROR;
LinkList p = *L;
int i = 1;
while (i < place && p->next != *L) {
p = p->next;
i++;
}
if (i > place) return ERROR;
LinkList temp = (LinkList)malloc(sizeof(Node));
if (temp == NULL) return ERROR;
temp->data = num;
temp->next = p->next;
p->next = temp;
temp->prior = p;
if (p->next != *L) {
temp->next->prior = temp;
} else {
(*L)->prior = temp;
}
return OK;
}
双向循环链表的删除
Status LinkListDelete(LinkList *L, int place, ElemType *e) {
if (place < 1 || *L == NULL) return ERROR;
LinkList p = (*L)->next;
if (p->next == *L) {
free(*L);
*L = NULL;
return OK;
}
int i = 1;
while (i < place && p->next != *L) {
p = p->next;
i++;
}
if (i > place) return ERROR;
*e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return OK;
}
Demo:https://github.com/ShoukaiWang/DataStructuresAndAlgorithms