使用shared_ptr智能指针实现双链表

/* 基于智能指针实现双向链表 */
#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;
}

GitHub - parallel101/hw02: 高性能并行编程与优化 - 第02讲的回家作业

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值