簡體   English   中英

雙鏈表的實現

[英]Implementation of a Doubly Linked List

我正在嘗試實現一個鏈表,我完全迷路了。 我到處都有斷點,特別是使用擦除方法。 每當我更改擦除方法時,都會不可避免地出現一些錯誤。 我遇到了指針錯誤,析構函數的問題,這些問題僅在調用擦除方法時才會發生,等等。

這是我到目前為止的內容:

頭文件:

#pragma once

class IntList {
private:

    class IntNode {
    public:
        IntNode(int v, IntNode *pr, IntNode *nx);
        ~IntNode();
        IntNode* previous;
        IntNode* next;

        class iterator {

        public:
            iterator(IntNode* t);
            int& operator*();
            iterator& operator++();
            iterator& operator--();
            bool operator!=(iterator other)const;
        private:
            IntNode* target;
        };

    private:
        int value;
    };

    IntNode* head;
    IntNode* tail;
    int count;

public:

    IntList();
    ~IntList();
    void push_back(int v);
    void pop_back();
    int size() const { return count; }
    typedef IntNode::iterator iterator;
    iterator begin();
    iterator end();
    //unsigned int size() const;
    void push_front(int value);
    bool empty() const;
    int& front();
    int& back();
    void clear();
    iterator erase(iterator position);
};

執行:

#include "IntList.h"
#include <stdexcept>

IntList::IntList() : head{ nullptr }, tail{ nullptr }, count{ 0 }
{}

IntList::~IntList() {
    while (head) {
        head = head->next;
        delete head;
    }
}

void IntList::push_back(int v) {
    tail = new IntNode{ v, tail, nullptr };
    if (!head) { head = tail; }
    count += 1;
}

void IntList::pop_back() {
    tail = tail->previous;
    delete tail->next;
    count -= 1;
}

IntList::iterator IntList::begin()
{
    return iterator{ head };
}

IntList::iterator IntList::end() {
    return iterator{ nullptr };
}

void IntList::push_front(int value) {
    head = new IntNode{ value, nullptr, head };
    if (!tail) { tail = head; }
    count += 1;
}

bool IntList::empty() const{
    return (count==0);
}

int& IntList::front() {
    return *begin();
}

int& IntList::back() {
    return *begin();
}

void IntList::clear() {
    head = nullptr;
    tail = nullptr;
    count = 0;
}

IntList::iterator IntList::erase(iterator position) {

    int midpointL = 0;

    for (iterator index = begin(); index != position; ++index) {
        midpointL++;
    }

    if (midpointL == 0) {
        head = head->next;
    }
    else if (midpointL == count) {
        tail = tail->previous;
    }
    else {

        // Move head to get a reference to the component that needs to be deleted
        for (int i = 0; i < midpointL; i++) {
            head = head->next;
        }

        // Change the previous and next pointers to point to each other
        (head->previous)->next = (head->next);
        (head->next)->previous = (head->previous);

        for (int i = midpointL-1; i > 0; i++) {
            head = head->previous;
        }

    }

    count-=1;

    return position;
}


IntList::IntNode::IntNode(int v, IntNode * pr, IntNode * nx)
    : previous{ pr }, next{ nx }, value{ v }
{
    if (previous) { previous->next = this; }
    if (next) { next->previous = this; }
}

IntList::IntNode::~IntNode() {
    if (previous) previous->next = next;
    if (next) next->previous = previous;
}

IntList::IntNode::iterator::iterator(IntNode* t)
    : target{ t }
{}

int& IntList::IntNode::iterator::operator*() {
    if (!target) { throw std::runtime_error{ "Deferenced sentinel iterator." }; }
    return target->value;
}

IntList::IntNode::iterator& IntList::IntNode::iterator::operator++()
{
    if (target) { target = target->next; }
    return *this;
}

IntList::IntNode::iterator& IntList::IntNode::iterator::operator--()
{
    if (target) { target = target->previous; }
    return *this;
}

bool IntList::IntNode::iterator::operator!=(iterator other)const
{
    return (!(target == other.target));
}

有人可以幫我指出正確的方向嗎?

謝謝!

讓我們在這里進行一下快速回顧:

IntList::~IntList() {
    while (head) {
        head = head->next;
        delete head;
    }
}

您應該改為:

IntList::~IntList() {
    while (head) {
        IntNode* newHead = head->next;
        delete head;
        head = newHead;
    }
}

當您刪除“下一個”對象,然后嘗試在下一次迭代中訪問它時。

void IntList::pop_back() {
    tail = tail->previous;
    delete tail->next;
    count -= 1;
}

在這里,您無需檢查tail是否為null或是否指向head ..(什么是空條件?),也許count!=0 萬一您可以刪除不存在的下一節點

IntList::iterator IntList::end() {
    return iterator{ nullptr };
}

.. end是否為空? ebd應該是你的尾巴...

int& IntList::back() {
    return *begin();
}

那是開始..不回來。

void IntList::clear() {
    head = nullptr;
    tail = nullptr;
    count = 0;
}

一個清除對象應釋放列表中的所有對象。 您正在此處生成垃圾(泄漏)。

我在這里停下來,對此感到抱歉,這只是喝咖啡休息時間。 但是您應該仔細看一下:*空指針的使用*不需要時刪除節點列表項*注意不要使用無效的指針(例如head->previous->next我見過的某個地方)

您必須自下而上檢查代碼。 希望這些第一提示可以幫助您完成學習過程。

玩得開心,Ste

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM