双向链表(双向链表java实现)

[img]

双向链表是一种链式数据结构,它可以在节点中同时保存前一个和后一个节点的引用。这种数据结构允许双向遍历,并且可以在 O(1) 时间复杂度下进行删除、添加和修改操作。

一级标题:双向链表的定义和特点

双向链表是由若干个节点组成的数据结构,每个节点包含两个部分:数据和两个指针。这两个指针分别指向前一个和后一个节点,因此双向链表也被称为双向列表。与单向链表不同的是,双向链表可以双向遍历,可以在任意位置进行删除、添加和修改操作。

二级标题:双向链表的节点结构和指针定义

在双向链表中,每个节点通常包含三个部分:前驱指针 prev,后继指针 next 和数据域 data。其中,prev 指向前驱节点的地址,next 指向后继节点的地址,data 存储该节点的数据。

```

struct Node

int data;

Node* prev;

Node* next;

};

```

三级标题:双向链表的操作

1. 添加操作

向双向链表中添加一个新节点,需要考虑两种情况:插入到链表头和插入到链表尾。

- 在链表头插入节点

在链表头插入一个新节点时,需要将新节点的 next 指向原来的头节点,将原来的头节点的 prev 指向新节点,并将链表头指针指向新节点的地址。

```

void insertAtHead(Node** head, int data)

Node* newNode = new Node();

newNode->data = data;

newNode->prev = nullptr;

newNode->next = *head;

if (*head != nullptr)

(*head)->prev = newNode;

*head = newNode;

```

- 在链表尾插入节点

在链表尾插入一个新节点时,需要将新节点的 prev 指向原来的尾节点,将原来的尾节点的 next 指向新节点,并将链表尾指针指向新节点的地址。

```

void insertAtTail(Node** tail, int data)

Node* newNode = new Node();

newNode->data = data;

newNode->prev = *tail;

newNode->next = nullptr;

if (*tail != nullptr)

(*tail)->next = newNode;

*tail = newNode;

```

2. 删除操作

删除双向链表中的节点时,需要考虑节点的位置:在链表头、链表尾和链表中间。

- 删除链表头节点

```

void deleteAtHead(Node** head)

if (*head == nullptr)

return;

Node* temp = *head;

*head = (*head)->next;

if (*head != nullptr)

(*head)->prev = nullptr;

delete temp;

```

- 删除链表尾节点

```

void deleteAtTail(Node** tail)

if (*tail == nullptr)

return;

Node* temp = *tail;

*tail = (*tail)->prev;

if (*tail != nullptr)

(*tail)->next = nullptr;

delete temp;

```

- 删除链表中的节点

```

void deleteNode(Node** head, Node** tail, int data)

if (*head == nullptr)

return;

if ((*head)->data == data)

{

deleteAtHead(head);

return;

}

if ((*tail)->data == data)

{

deleteAtTail(tail);

return;

}

Node* current = (*head)->next;

while (current != nullptr && current->data != data)

current = current->next;

if (current == nullptr)

return;

current->prev->next = current->next;

current->next->prev = current->prev;

delete current;

```

3. 遍历操作

双向链表可以从头节点或尾节点开始遍历,也可以反向遍历。

```

void printList(Node* head)

while (head != nullptr)

{

cout << head->data << " ";

head = head->next;

}

cout << endl;

void printListReverse(Node* tail)

while (tail != nullptr)

{

cout << tail->data << " ";

tail = tail->prev;

}

cout << endl;

```

四级标题:双向链表的优缺点

双向链表的主要优点是可以在任意位置 O(1) 时间内进行插入和删除操作,同时可以双向遍历链表。然而,与单向链表相比,双向链表需要额外的空间来存储指向前驱节点的指针,因此占用的内存空间更大。

五级标题:总结

双向链表是一种常用的链式数据结构,相对于单向链表具有更强的灵活性和更快的操作速度。在实际开发中,我们应根据实际情况选择不同的数据结构,以满足不同的需求。

标签列表