数据结构与算法之数据结构 链表 单链表 / 双向链表 实现与对比

数据结构与算法阿木 发布于 4 天前 3 次阅读


摘要:链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。本文将详细介绍单链表和双向链表的实现方法,并对比它们的优缺点,以帮助读者更好地理解这两种链表数据结构。

一、

链表是一种重要的数据结构,广泛应用于计算机科学和软件工程领域。它具有灵活的插入和删除操作,能够有效地处理动态数据。本文将围绕单链表和双向链表进行探讨,包括它们的定义、实现以及对比。

二、单链表

1. 定义

单链表是一种线性表,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。单链表的特点是每个节点只有一个指针,指向下一个节点。

2. 实现方法

(1)定义节点结构体

c

typedef struct Node {


int data; // 数据域


struct Node next; // 指针域


} Node;


(2)创建链表

c

Node createList() {


Node head = (Node)malloc(sizeof(Node)); // 创建头节点


if (head == NULL) {


return NULL;


}


head->next = NULL; // 初始化头节点指针域


return head;


}


(3)插入节点

c

void insertNode(Node head, int data, int position) {


Node newNode = (Node)malloc(sizeof(Node)); // 创建新节点


if (newNode == NULL) {


return;


}


newNode->data = data; // 设置数据域


newNode->next = NULL; // 初始化指针域

if (position == 0) { // 插入到链表头部


newNode->next = head->next;


head->next = newNode;


} else { // 插入到链表中间或尾部


Node temp = head;


for (int i = 0; i < position - 1; i++) {


temp = temp->next;


if (temp == NULL) {


return;


}


}


newNode->next = temp->next;


temp->next = newNode;


}


}


(4)删除节点

c

void deleteNode(Node head, int position) {


if (head == NULL || head->next == NULL) {


return;


}

Node temp = head;


if (position == 0) { // 删除链表头部节点


head = head->next;


free(temp);


} else { // 删除链表中间或尾部节点


for (int i = 0; i < position - 1; i++) {


temp = temp->next;


if (temp == NULL) {


return;


}


}


Node toDelete = temp->next;


temp->next = toDelete->next;


free(toDelete);


}


}


三、双向链表

1. 定义

双向链表是一种线性表,由一系列节点组成,每个节点包含数据和指向前一个节点以及指向下一个节点的指针。双向链表的特点是每个节点有两个指针,分别指向前一个节点和后一个节点。

2. 实现方法

(1)定义节点结构体

c

typedef struct Node {


int data; // 数据域


struct Node prev; // 指向前一个节点的指针域


struct Node next; // 指向下一个节点的指针域


} Node;


(2)创建链表

c

Node createList() {


Node head = (Node)malloc(sizeof(Node)); // 创建头节点


if (head == NULL) {


return NULL;


}


head->prev = NULL; // 初始化头节点指针域


head->next = NULL; // 初始化指针域


return head;


}


(3)插入节点

c

void insertNode(Node head, int data, int position) {


Node newNode = (Node)malloc(sizeof(Node)); // 创建新节点


if (newNode == NULL) {


return;


}


newNode->data = data; // 设置数据域


newNode->prev = NULL; // 初始化指针域


newNode->next = NULL;

if (position == 0) { // 插入到链表头部


newNode->next = head->next;


if (head->next != NULL) {


head->next->prev = newNode;


}


head->next = newNode;


newNode->prev = head;


} else { // 插入到链表中间或尾部


Node temp = head;


for (int i = 0; i < position - 1; i++) {


temp = temp->next;


if (temp == NULL) {


return;


}


}


newNode->next = temp->next;


newNode->prev = temp;


if (temp->next != NULL) {


temp->next->prev = newNode;


}


temp->next = newNode;


}


}


(4)删除节点

c

void deleteNode(Node head, int position) {


if (head == NULL || head->next == NULL) {


return;


}

Node temp = head;


if (position == 0) { // 删除链表头部节点


head = head->next;


if (head != NULL) {


head->prev = NULL;


}


free(temp);


} else { // 删除链表中间或尾部节点


for (int i = 0; i < position - 1; i++) {


temp = temp->next;


if (temp == NULL) {


return;


}


}


Node toDelete = temp->next;


if (toDelete != NULL) {


toDelete->prev = temp;


}


temp->next = toDelete->next;


if (toDelete->next != NULL) {


toDelete->next->prev = temp;


}


free(toDelete);


}


}


四、单链表与双向链表的对比

1. 结构

单链表由节点组成,每个节点包含数据和指向下一个节点的指针;双向链表由节点组成,每个节点包含数据和指向前一个节点以及指向下一个节点的指针。

2. 优点

单链表结构简单,易于实现;双向链表在删除节点时,可以同时修改前一个节点的指针,提高删除效率。

3. 缺点

单链表在删除节点时,需要遍历到前一个节点,效率较低;双向链表结构复杂,占用空间较大。

4. 应用场景

单链表适用于插入和删除操作频繁的场景;双向链表适用于需要频繁查找前一个节点的场景。

五、总结

本文详细介绍了单链表和双向链表的实现方法,并对比了它们的优缺点。在实际应用中,根据具体需求选择合适的数据结构,可以提高程序的性能和效率。