1.定义一个双链表
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef int ElemType;/* 定义一个单链表 */
typedef struct DNode {/*数据域*/ElemType data;/*前驱指针域*/struct LNode *prior;/*后驱指针域*/struct LNode *next;
} DNode, *DinkList; /*DNode处理单个节点 ; DinkList处理整个双链表*/int main() {return 0;
}
插入和删除双链表
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef int ElemType;/* 定义一个双链表节点 */
typedef struct DNode {ElemType data; /* 数据域 */struct DNode *prior; /* 前驱指针域 */struct DNode *next; /* 后驱指针域 */
} DNode, *DLinkList;/* 初始化双链表 */
DLinkList initDLinkList() {DLinkList L = (DLinkList ) malloc(sizeof(DNode));if (L == NULL) {printf("内存分配失败\n");exit(1);}L->next = NULL;L->prior = NULL;return L;
}/* 获取双链表长度 */
int length(DLinkList L) {int len = 0;DNode *p = L->next; // 假设L是一个头节点while (p != NULL) {len++;p = p->next;}return len;
}/* 按位查找,返回第i个位置的节点指针 */
DNode* getElemByPos(DLinkList L, int i) {int j = 0;DNode *p = L;while (p != NULL && j < i) {p = p->next;j++;}return p;
}/* 在双链表的第i个位置插入元素值为x的节点 */
void insertNode(DLinkList L, int i, ElemType x) {if (i < 1 || i > length(L) + 1) {printf("无效的位置\n");return;}DNode *p = getElemByPos(L, i - 1);/*定义一个要插入的节点指针*/DNode *s = (DNode *) malloc(sizeof(DNode));if (s == NULL) {printf("内存分配失败\n");exit(1);}/*修改s地址上的实际 的值*/s->data = x;/**/s->next = p->next;if (p->next != NULL) {/*当我们插入新节点 s 后,需要确保新节点 s 成为原来第 i 个节点的前驱节点,因此我们将 p->next->prior 设置为 s。更详细的解释:新节点 s 将插入到 p 之后,成为新的第 i 个节点。原来的第 i 个节点的前驱节点将更新为新节点 s。*/p->next->prior = s;/*p->next->prior = s;可以改写为:如下代码*///先获取原来i位置上的地址指针 (p->next)// 原来i位置上的地址指针 变为了 i+1 的位置/*所有 原来i位置上的地址指针的前驱指针域prior 变成了新插入的指针s 的地址*///(p->next)->prior=s;}s->prior = p;p->next = s;
}/* 删除双链表中第i个位置的节点 */
bool deleteNode(DLinkList L, int i, ElemType *e) {if (i < 1 || i > length(L)) {return false;}/*获取 i-1 位序上的节点地址 */DNode *p = getElemByPos(L, i - 1);/*获取要删除的节点的地址*/DNode *q = p->next;if (q == NULL) {return false;}/*更新 i-1 的后驱指针域 为 i+1的地址指针*/p->next = q->next;if (q->next != NULL) {q->next->prior = p;}*e = q->data;/*删除q指针*/free(q);return true;
}int main() {/* 初始化双链表L为一个带头节点的空链表 */DLinkList L = initDLinkList();/* 插入测试数据 */insertNode(L, 1, 10); // 在第1个位置插入10insertNode(L, 2, 20); // 在第2个位置插入20insertNode(L, 1, 5); // 在第1个位置插入5/* 打印链表 */DNode *p = L->next;while (p != NULL) {printf("%d -> ", p->data);p = p->next;}printf("NULL\n");/* 删除节点测试 */ElemType e;if (deleteNode(L, 2, &e)) {printf("已删除节点的值: %d\n", e);} else {printf("删除失败\n");}/* 再次打印链表 */p = L->next;while (p != NULL) {printf("%d -> ", p->data);p = p->next;}printf("NULL\n");/* 释放链表 */p = L;while (p != NULL) {DNode *temp = p;p = p->next;free(temp);}return 0;
}