/* 基于智能指针实现双向链表 */
#include<iostream>
using namespace std;
#include <memory>
struct Node {
// 这两个指针会造成什么问题?请修复 会诱发循环引用,导致内存泄漏
std::shared_ptr<Node> next;
//std::shared_ptr<Node> prev;
//修改后
std::weak_ptr<Node> prev;
// 如果能改成 unique_ptr 就更好了!
int value;
// 这个构造函数有什么可以改进的?
Node(int val=0) {
value = val;
next = nullptr;
prev.lock() = nullptr;
}
void insert(int val,shared_ptr<Node>& head) {
auto node = std::make_shared<Node>(val);//
if (this) {
node->prev = prev;
if (!prev.expired()) {
node->next = prev.lock()->next;
prev.lock()->next = node;
prev = node;
}
else {
node->next = head;
prev = node;
head = node;
}
}
else {
if (!head.get()) {
head = node;
}
else {
shared_ptr<Node> tmp = head;
while (tmp->next) {
tmp = tmp->next;
}
tmp->next = node;
node->prev = tmp;
}
}
}
void erase() {
if (!prev.expired())
prev.lock()->next = next;
if (next)
next->prev = prev;
}
~Node() {
printf("~Node()\n");
}
};
struct List {
std::shared_ptr<Node> head;
List() = default;
List(List const& other) {
printf("List 被拷贝!\n");
//head = other.head; // 这是浅拷贝!
// 请实现拷贝构造函数为 **深拷贝**
//深拷贝
auto curr = other.front();
if (curr) {
head = make_shared<Node>(curr->value);
auto p = head;
for (curr=curr->next.get(); curr; curr = curr->next.get()) {
p->next = make_shared<Node>(curr->value);
p = p->next;
}
}
else {
head = make_shared<Node>();
}
}
List& operator=(List const&) = delete; // 为什么删除拷贝赋值函数也不出错?
List(List&&) = default;
List& operator=(List&&) = default;
Node* front() const {
return head.get();
}
int pop_front() {
int ret = head->value;
head = head->next;
return ret;
}
void push_front(int value) {
auto node = std::make_shared<Node>(value);
node->next = head;
if (head)
head->prev = node;
head = node;
}
Node* at(size_t index) const {
auto curr = front();
for (size_t i = 0; i < index; i++) {
curr = curr->next.get();
if (!curr)
break;
}
return curr;
}
};
void print(List const& lst) { // 有什么值得改进的? 加上 const& 防止重复拷贝
printf("[");
for (auto curr = lst.front(); curr; curr = curr->next.get()) {
printf(" %d", curr->value);
}
printf(" ]\n");
}
int main() {
List a;
a.push_front(7);
a.push_front(5);
a.push_front(8);
a.push_front(2);
a.push_front(9);
a.push_front(4);
a.push_front(1);
print(a); // [ 1 4 9 2 8 5 7 ]
a.at(2)->erase();
print(a); // [ 1 4 2 8 5 7 ]
List b = a;
a.at(3)->erase();
a.at(1)->insert(10, a.head);
a.at(0)->insert(20, a.head);
a.at(10)->insert(20, a.head);
print(a); // [20 1 10 4 2 5 7 20]
print(b); // [ 1 4 2 8 5 7 ]
b = {};
a = {};
return 0;
}