為什么要使用雙向鏈表
單向鏈表只能從頭節(jié)點(diǎn)往后遍歷豁辉,雙向鏈表每個(gè)節(jié)點(diǎn)都有指向上一個(gè)節(jié)點(diǎn)的指針庶橱,支持反向遍歷夷恍,如果數(shù)據(jù)量比較大的時(shí)候拱雏,從后往前遍歷遍歷效率更高棉安,查找的效率會(huì)間接影響增刪的效率。
具體邏輯實(shí)現(xiàn)
//
// Created by ygq on 2024/11/1.
//
#include "log.h"
#ifndef YGQ_TAG
#define YGQ_TAG
template<class E>
struct Node {
E value;
Node<E> *pre;
Node<E> *next;
Node(E value, Node<E> *pre, Node<E> *next) {
this->value = value;
this->pre = pre;
this->next = next;
}
};
template<class E>
class LinkedList {
private:
int len = 0;
Node<E> *head = nullptr;
Node<E> *end = nullptr;
public:
void push(E e);
void insert(int index, E e);
E remove(int index);
Node<E> *findNode(int index);
E get(int index);
int size();
void linkLast(E e);
void linkBefore(Node<E> *cur, E e);
};
/*
template<class E>
void LinkedList<E>::push(E e) {
Node<E> *new_node = new Node<E>(e, nullptr);
if (head) {
Node<E> *last = findNode(len - 1);
last->next = new_node;
} else {
head = new_node;
}
len++;
}*/
template<class E>
void LinkedList<E>::push(E e) {
Node<E> *new_node = new Node<E>(e, end, nullptr);
if (head) {
end->next = new_node;
end = new_node;
} else {
head = new_node;
end = new_node;
}
len++;
}
template<class E>
void LinkedList<E>::linkLast(E e) {
Node<E> *new_node = new Node<E>(e, end, nullptr);
if (head) {
end->next = new_node;
end = new_node;
} else {
head = new_node;
end = new_node;
}
}
template<class E>
void LinkedList<E>::linkBefore(Node<E> *cur, E e) {
Node<E> *new_node = new Node<E>(e, cur->pre, cur);
cur->pre->next = new_node;
cur->pre = new_node;
}
template<class E>
void LinkedList<E>::insert(int index, E e) {
if (index > len - 1 || index < 0) {
LOGE("index:%d illegal,must <= %d or > 0", index, len - 1);
return;
}
Node<E> *node = findNode(index);
linkBefore(node, e);
len++;
}
template<class E>
E LinkedList<E>::remove(int index) {
if (index > len - 1 || index < 0) {
LOGE("index:%d illegal,must <= %d or > 0", index, len - 1);
return E();
}
Node<E> *cur = findNode(index);
if (cur->pre) {
cur->pre->next = cur->next;
} else {//頭節(jié)點(diǎn)
head = cur->next;
}
if (cur->next) {
cur->next->pre = cur->pre;
} else {//尾節(jié)點(diǎn)
end = cur->pre;
}
E value = cur->value;
delete cur;
len--;
return value;
}
template<class E>
E LinkedList<E>::get(int index) {
return findNode(index)->value;
}
template<class E>
Node<E> *LinkedList<E>::findNode(int index) {
if (index > len >> 1) {
//從后往前遍歷
Node<E> *cur = end;
for (int i = len - 1; i > index; --i) {
cur = cur->pre;
}
return cur;
} else {
//從前往后遍歷
Node<E> *cur = head;
for (int i = 0; i < index; ++i) {
cur = cur->next;
}
return cur;
}
}
template<class E>
int LinkedList<E>::size() {
return len;
}
#endif
運(yùn)行效果
index:0,value:0
index:1,value:1
index:2,value:2
index:3,value:5
index:4,value:6
index:5,value:7
---------
index:0,value:1
index:1,value:5
index:2,value:6