赞
踩
双向链表(Doubly Linked List)是一种常见的数据结构,它与单向链表相似,但每个节点有两个指针,一个指向前一个节点(前驱节点),一个指向后一个节点(后继节点)。
双向链表中的每个节点包含三个基本部分:数据域(存储节点的数据)、前驱指针和后继指针。头节点和尾节点是特殊的节点,它们分别代表双向链表的起始和结束。
双向连接:每个节点都有两个指针,一个指向前驱节点,一个指向后继节点。这种双向连接的结构使得在链表中的节点之间可以进行双向遍历。
首尾节点:双向链表通常有头节点和尾节点,它们分别代表链表的起始和结束。头节点的前驱指针为空,尾节点的后继指针为空。
插入和删除的灵活性:相较于单向链表,双向链表可以更方便地在任意位置插入和删除节点。通过调整前驱和后继指针的指向,可以高效地完成这些操作,而无需遍历整个链表。
前向和后向遍历:由于每个节点都有前驱和后继指针,双向链表可以从头节点或尾节点开始,沿着不同的方向遍历整个链表。这种灵活性在某些情况下能提高效率。
多占用空间:相对于单向链表,双向链表需要额外存储每个节点的前驱指针,因此会占用更多的内存空间。
维护复杂性:因为每个节点有两个指针,所以在插入、删除或修改节点时,需要同时更新相关节点的前驱和后继指针,这增加了链表的维护复杂性。
节点:
- template<typename T>
- class Node {
- public:
- T val; // 数据域
- Node *pre; // 前驱节点指针
- Node *next; // 后继节点指针
-
- ~Node() {
- }
- };
链表属性:
- private:
- Node<T> *head; // 头指针
- Node<T> *tail; // 尾指针
- int siz = 0; // 元素个数
头尾指针使用同一个节点 ,不保存数据
1、void add(T t); // 从尾部添加元素
2、void add(int index, T t); //在索引index处添加元素t
3、add_first(T t); // 从头部添加元素
4、bool contains(T t) const // 判断元素t是否在list中
5、T get(int index); // 获取指定位置的元素
6、T get_first() ;//获取第一个元素
7、T get_last(); // 获取最后一个元素
8、int index_of(T t); 获取指定位置的索引
9、 void clear();清空list
- /**
- * 双向链表实现list
- */
- #include <iostream>
- #include <bits/functexcept.h>
-
- #ifndef LIST_LINK_LIST_H
- #define LIST_LINK_LIST_H
-
- template<typename T>
- class Node {
- public:
- T val;
- Node *pre;
- Node *next;
-
- ~Node() {
- }
- };
-
- template<typename T>
- class LinkList {
- public:
- // 从尾部添加元素
- void add(T t);
-
- // 在索引index处添加元素t
- void add(int index, T t);
-
- // 从头部添加元素
- void add_first(T t);
-
- // 清空list
- void clear() {
- Node<T> *t_h = head->next;
- while (t_h != tail) {
- Node<T> * t = t_h;
- t_h = t_h->next;
- delete t;
- }
- siz = 0;
- head->pre = tail->next = nullptr;
- };
-
- // 判断元素t是否在list中
- bool contains(T t) const {
- Node<T> *t_h = head->next;
- while (t_h != tail) {
- if (t_h->val == t) return true;
- t_h = t_h->next;
- }
- return false;
- };
-
- T get(int index) {
- if (index < 0 || index > siz - 1) {
- std::__throw_out_of_range_fmt("LinkList<T>::get(int index) index out of range");
- }
- Node<T> *ind_node;
- if (index < (siz >> 1)) {
- ind_node = head->next;
- for (int i = 0; i < index; i++) {
- ind_node = ind_node->next;
- }
- } else {
- ind_node = tail->pre;
- for (int i = siz - 1; i > index; i--) {
- ind_node = ind_node->pre;
- }
- }
-
- return ind_node->val;
- };
-
- T get_first() const { return head->next->val; }
-
- T get_last() const { return tail->pre->val; }
-
- int index_of(T t);
-
- int size() const { return siz; }
-
- // 打印
- void print() {
- if(!siz) return;
- Node<T> *t = head->next;
- while (t != tail) {
- std::cout << t->val << " ";
- t = t->next;
- }
- std::cout << std::endl;
- }
-
- LinkList() {
- head = tail = new Node<T>();
- head->pre = tail->next = nullptr;
- }
-
- ~LinkList() {
- Node<T> *t_h = head;
- while (t_h != tail) {
- t_h = t_h->next;
- Node<T> *t = t_h;
- delete t;
- }
- }
-
- private:
- Node<T> *head; // 头指针
- Node<T> *tail; // 尾指针
- int siz = 0; // 元素个数
- };
-
- #endif //LIST_LINK_LIST_H
- template<typename T>
- void LinkList<T>::add(T t) {
- Node<T> *node = new Node<T>();
- node->val = t;
-
- if (!siz) {
- head->next = node;
- tail->pre = node;
- node->next = tail;
- node->pre = head;
- } else {
- tail->pre->next = node;
- node->pre = tail->pre;
- tail->pre = node;
- node->next = tail;
- }
-
- siz++;
- }
-
- template<typename T>
- void LinkList<T>::add(int index, T t) {
- Node<T> *node = new Node<T>();
- node->val = t;
- Node<T> *ind_node;
-
- if (index < 0) {
- add_first(t);
- } else if (index >= siz) {
- add(t);
- } else {
- if (index < (siz >> 1)) {
- ind_node = head->next;
- for (int i = 0; i < index; i++) {
- ind_node = ind_node->next;
- }
- } else {
- ind_node = tail->next;
- for (int i = siz - 1; i > index; i--) {
- ind_node = ind_node->pre;
- }
- }
- }
- node->pre = ind_node->pre;
- ind_node->pre->next = node;
- ind_node->pre = node;
- node->next = ind_node;
- siz++;
- }
-
- template<typename T>
- void LinkList<T>::add_first(T t) {
- Node<T> *node = new Node<T>();
- node->val = t;
-
- if (!siz) {
- head->next = node;
- tail->pre = node;
- node->pre = head;
- node->next = tail;
- } else {
- head->next->pre = node;
- node->next = head->next;
- node->pre = head;
- head->next = node;
- }
- siz++;
- }
-
- template<typename T>
- int LinkList<T>::index_of(T t) {
- int i = 0;
- Node<T> *t_h = head->next;
- for (i; i < siz; i++) {
- if (t_h->val == t) return i;
- t_h = t_h->next;
- }
-
- return -1;
- }
- #include "link_list.h"
-
- int main() {
- LinkList<int> linkList = LinkList<int>();
- linkList.add_first(1);
- linkList.add(2);
- linkList.add_first(0);
- linkList.add(0,10);
- linkList.print();
-
- std::cout << linkList.index_of(1) << std::endl;
- std::cout<< linkList.get(2)<<std::endl;
-
- std::cout << linkList.contains(2) << std::endl;
- linkList.clear();
- std::cout << "----------" << std::endl;
- linkList.print();
- linkList.add(1);
- linkList.add(2);
- linkList.add(3);
- linkList.print();
- }
- 10 0 1 2
- 2
- 1
- 1
- ----------
- 1 2 3
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。