深入解析双向链表与单向链表的区别:示例详解
创作时间:
作者:
@小白创作中心
深入解析双向链表与单向链表的区别:示例详解
引用
CSDN
1.
https://blog.csdn.net/qq_35320456/article/details/140401203
链表是一种灵活的数据结构,它通过指针连接一系列节点,实现了动态数组的特性。在众多链表类型中,单向链表和双向链表是最为常见的两种。本文将重点探讨这两种链表的区别,并通过示例进行详细说明。
一、单向链表与双向链表的定义及结构
单向链表
定义:单向链表是链表的一种,每个节点包含数据域和一个指向下一个节点的指针。
结构示例:
节点Node {
int data; // 数据域
Node next; // 指针域,指向下一个节点
}
双向链表
定义:双向链表是链表的一种,每个节点包含数据域、一个指向前一个节点的指针和一个指向下一个节点的指针。
结构示例:
节点Node {
int data; // 数据域
Node prev; // 指针域,指向前一个节点
Node next; // 指针域,指向下一个节点
}
二、单向链表与双向链表的区别示例
插入操作
假设要在链表中的某个节点后插入一个新的节点,以下是单向链表和双向链表的插入操作示例。
单向链表插入操作:
// 假设要在节点p后插入新节点newNode
newNode.next = p.next;
p.next = newNode;
双向链表插入操作:
// 假设要在节点p后插入新节点newNode
newNode.prev = p;
newNode.next = p.next;
if (p.next != null) {
p.next.prev = newNode;
}
p.next = newNode;
从上述示例可以看出,双向链表在插入操作时需要同时维护前驱节点和后继节点的指针,而单向链表只需维护后继节点的指针。
删除操作
假设要删除链表中的某个节点,以下是单向链表和双向链表的删除操作示例。
单向链表删除操作:
// 假设要删除节点p
if (p.prev != null) {
p.prev.next = p.next;
}
双向链表删除操作:
// 假设要删除节点p
if (p.prev != null) {
p.prev.next = p.next;
} else {
// p是头节点,需要更新头节点
head = p.next;
}
if (p.next != null) {
p.next.prev = p.prev;
}
从上述示例可以看出,双向链表在删除操作时需要同时维护前驱节点和后继节点的指针,而单向链表只需维护前驱节点的指针。
三、完整示例
以下是双向链表的一个简单示例(C++):
#include <iostream>
struct Node {
int data;
Node* next;
Node* prev;
Node(int data) : data(data), next(nullptr), prev(nullptr) {}
};
class DoublyLinkedList {
public:
Node* head;
Node* tail;
DoublyLinkedList() : head(nullptr), tail(nullptr) {}
void insertAtHead(int data) {
Node* newNode = new Node(data);
if (head == nullptr) {
head = tail = newNode;
} else {
newNode->next = head;
head->prev = newNode;
head = newNode;
}
}
void printList() const {
Node* temp = head;
while (temp != nullptr) {
std::cout << temp->data << " <-> ";
temp = temp->next;
}
std::cout << "NULL" << std::endl;
}
~DoublyLinkedList() {
Node* current = head;
while (current != nullptr) {
Node* next = current->next;
delete current;
current = next;
}
}
};
int main() {
DoublyLinkedList list;
list.insertAtHead(3);
list.insertAtHead(2);
list.insertAtHead(1);
list.printList();
return 0;
}
在这个示例中,我们创建了一个双向链表,并在链表头部插入新结点。注意,插入操作中需要同时更新新结点的next和prev指针,以及前一个结点的prev指针和后一个结点的next指针。
以下是单向链表的一个简单示例(C++):
#include <iostream>
struct Node {
int data;
Node* next;
Node(int data) : data(data), next(nullptr) {}
};
class LinkedList {
public:
Node* head;
LinkedList() : head(nullptr) {}
void insertAtHead(int data) {
Node* newNode = new Node(data);
newNode->next = head;
head = newNode;
}
void printList() const {
Node* temp = head;
while (temp != nullptr) {
std::cout << temp->data << " -> ";
temp = temp->next;
}
std::cout << "NULL" << std::endl;
}
~LinkedList() {
Node* current = head;
while (current != nullptr) {
Node* next = current->next;
delete current;
current = next;
}
}
};
int main() {
LinkedList list;
list.insertAtHead(3);
ist.insertAtHead(2);
list.insertAtHead(1);
list.printList();
return 0;
}
四、总结
通过以上示例,我们可以总结出单向链表与双向链表以下几个主要区别:
- 结构差异:双向链表每个节点有两个指针域,分别指向前一个节点和后一个节点;单向链表只有一个指针域,指向下一个节点。
- 操作差异:双向链表在插入和删除操作时,需要同时维护前驱节点和后继节点的指针;单向链表只需维护一个方向的指针。
- 功能差异:双向链表可以快速访问前驱节点和后继节点,适用于需要双向遍历的场景;单向链表只能单向遍历,适用于只需单向访问的场景。
- 空间占用:双向链表由于每个节点有两个指针域,因此占用空间较大;单向链表占用空间较小。
- 实现复杂度:双向链表实现相对复杂,需要考虑前驱节点和后继节点的指针修改;单向链表实现简单。
在实际应用中,根据具体需求和场景选择合适的链表类型,可以提高程序的性能和效率。
热门推荐
关羽的“忠义”精神在四大名著中的传承与演变
西沙群岛环保行动:守护海洋奇观
西沙群岛的神秘海鸟:白鲣鸟的生态故事
滑雪取代奢华派对,许晋亨一家的另类圣诞
电压力锅的6个实用保养方法
被非法拘禁怎么办?从定义到辩护,一文读懂
中广核武安光伏项目:废弃矿山上的绿色能源革命
德佑光伏项目助力地方经济发展
口腔用药新选择:奥硝唑疗效优于甲硝唑
甲硝唑、奥硝唑治口腔病:谁更胜一筹?
亲情友情正义感,泰罗奥特曼49年情感演绎全解析
橘子洲头&岳麓山:长沙最浪漫的约会胜地
七夕打卡花田厝,情侣浪漫满分
国家邮政局:快递业将推进“三化”发展,打造多式联运体系
邮政快递收费新标准:首重5元,普通包裹加收3元挂号费
江津创新“易取保”平台,取保候审保证金缴退实现全程网办
新疆棉花节水灌溉技术再创佳绩
法术高强又善用兵,姜子牙是封神演义中的完美统帅
新疆棉花产业助力地方经济发展
巴楚县:棉花产业现代化的南疆样本
中西医结合,太原龙城中医医院推出肝纤维化饮食疗法
全球首个乙肝肝纤维化新药将上市,干细胞治疗同步推进
地铁临时停运,公交打车骑行三方案应对出行难题
萨摩亚早就独立了,为何还有个美属萨摩亚?
财务管理转型升级,会计信息化如何突破人才瓶颈
智能心理咨询、情绪监测与预警:AI在心理健康领域的三大应用
柴油机燃烧过程揭秘:高效节能新趋势
久保田柴油发动机维修秘籍大公开
丁酸梭菌:肠道健康的守护神
丁酸梭菌:养殖界的超级英雄