如何用C语言写双向链表
创作时间:
作者:
@小白创作中心
如何用C语言写双向链表
引用
1
来源
1.
https://docs.pingcode.com/baike/1019828
双向链表是一种灵活的数据结构,在C语言中尤其适用于需要频繁插入和删除操作的场景。本文将详细介绍双向链表的基本结构、初始化方法、节点插入与删除操作,以及遍历方式,并提供完整的代码示例。
一、双向链表的基本结构
双向链表的基本结构包括节点和链表本身。每个节点包含三个主要部分:数据、指向下一个节点的指针和指向前一个节点的指针。
// 定义节点结构
typedef struct Node {
int data; // 数据部分
struct Node* next; // 指向下一个节点的指针
struct Node* prev; // 指向前一个节点的指针
} Node;
// 定义双向链表结构
typedef struct {
Node* head; // 指向链表的头节点
Node* tail; // 指向链表的尾节点
} DoublyLinkedList;
二、初始化双向链表
初始化双向链表时,需要将链表的头节点和尾节点指针设置为NULL。
// 初始化双向链表
void initList(DoublyLinkedList* list) {
list->head = NULL;
list->tail = NULL;
}
三、插入节点
在双向链表中插入节点可以在头部、尾部或指定位置插入。这里以头部和尾部插入为例。
1、头部插入节点
头部插入节点时,需要更新新节点的next指针和现有头节点的prev指针。
// 头部插入节点
void insertAtHead(DoublyLinkedList* list, int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = list->head;
newNode->prev = NULL;
if (list->head != NULL) {
list->head->prev = newNode;
} else {
list->tail = newNode;
}
list->head = newNode;
}
2、尾部插入节点
尾部插入节点时,需要更新新节点的prev指针和现有尾节点的next指针。
// 尾部插入节点
void insertAtTail(DoublyLinkedList* list, int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
newNode->prev = list->tail;
if (list->tail != NULL) {
list->tail->next = newNode;
} else {
list->head = newNode;
}
list->tail = newNode;
}
四、删除节点
在双向链表中删除节点时,需要考虑更新前后节点的指针。
1、删除头节点
删除头节点时,需要更新新头节点的prev指针。
// 删除头节点
void deleteAtHead(DoublyLinkedList* list) {
if (list->head == NULL) {
return;
}
Node* temp = list->head;
list->head = list->head->next;
if (list->head != NULL) {
list->head->prev = NULL;
} else {
list->tail = NULL;
}
free(temp);
}
2、删除尾节点
删除尾节点时,需要更新新尾节点的next指针。
// 删除尾节点
void deleteAtTail(DoublyLinkedList* list) {
if (list->tail == NULL) {
return;
}
Node* temp = list->tail;
list->tail = list->tail->prev;
if (list->tail != NULL) {
list->tail->next = NULL;
} else {
list->head = NULL;
}
free(temp);
}
五、遍历双向链表
遍历双向链表可以从头到尾或从尾到头遍历。
1、从头到尾遍历
// 从头到尾遍历
void traverseFromHead(DoublyLinkedList* list) {
Node* current = list->head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
2、从尾到头遍历
// 从尾到头遍历
void traverseFromTail(DoublyLinkedList* list) {
Node* current = list->tail;
while (current != NULL) {
printf("%d ", current->data);
current = current->prev;
}
printf("\n");
}
六、总结
通过上述代码示例,我们实现了双向链表的基本操作,包括初始化、插入节点、删除节点和遍历。双向链表相比单向链表的优势在于可以双向遍历和更高效地进行插入和删除操作,特别是在需要频繁操作的场景中,如实现LRU缓存、处理文本编辑器的撤销和重做操作等。
在实际应用中,我们可以根据具体需求扩展双向链表的功能,如在指定位置插入和删除节点、查找节点、逆序链表等。同时,在进行内存操作时,要注意防止内存泄漏,确保每个分配的节点都能被正确释放。
热门推荐
警惕!不规律饮食致胃癌年轻化,专家详解预防要点
晨起头晕恶心的八大原因与科学应对方法
辛雨锡揭秦霄贤感情骗局:被要求打胎,豪车实为己有
麻辣、醇厚、酸辣:中国四大臭豆腐风味大不同
云南特色臭豆腐:两种地方风味与家庭制作法
深圳理工大学:一所新型研究型大学的崛起
南方科技大学怎么样?一个宿舍4个专业,书院制就是如此精彩!
QS世界大学最新排名:上海交大反超浙大,西北工大不敌深圳大学?
中国滑雪胜地巡礼:阿勒泰“粉雪”引领先,南方室内场崛起
上冰雪人数超4亿,2024冬季旅游迎来新热潮
设施完善、雪道齐全:阿勒泰三大滑雪度假区迎亲子游客
成都中医哮喘医院推出肺大泡治疗新技术:经皮穿刺减容术效果显著
肺大泡患者的生活方式改善指南
为什么老年人经常去医院看病,还需要做全面体检?
从横拍到直拍横打:乒乓球主流打法技术特点详解
新手必看:打好乒乓球的七大核心技巧详解
46岁胡静晒幸福:豪门婚姻里的实力演员
薛宝钗的选秀之路:清代选秀制度下的女性命运
薛宝钗的落选之谜:从《红楼梦》到清代选秀制度的解读
薛宝钗的进宫选秀之路:从原著细节看她的落选之谜
白内障预防小窍门,你知道几个?
酒桌上的智慧:如何优雅地说“不”
白内障手术新突破:让老年人重获“高清视界”
白内障超声乳化术:原理、效果与风险全解析
浙大&中大&复旦联手揭秘白内障手术黑科技
职场新人必学:商务宴会上的逃酒秘籍
米兰时装周:舒淇这套穿搭让她看起来比实际年龄年轻15岁
太原崇善寺:明代皇家寺院里的国宝级木构建筑
太原冬季旅游新选择:古建研学游带游客领略千年文化
崇善寺:太原现存最大明代寺院,藏3万卷古籍