具有指针的C ++双链表:类的对象构造不正确

时间:2018-11-03 00:23:25

标签: c++ data-structures linked-list

就像这里的许多其他人一样,我也在实现双向链表。我的问题是在测试期间(这意味着我快完成了)!我想使用我的静态函数进行测试,但是终端上没有任何内容。您是否发现我的代码中可能导致此问题的任何缺陷?

主要功能:

#include <iostream>
int main() {
    std::cout << "Testing linked_list class:" << endl;
    linked_list::linked_list_test();
}

linked_list.h:

#include <vector>
#include <iostream>

using namespace std;

class linked_list {
private:
    struct Node {
        int value;
        Node* next;
        Node* previous;

        Node() {
            value = 0;
            next = nullptr;
            previous = nullptr;
        }

        Node(int n) {
            value = n;
            next = nullptr;
            previous = nullptr;
        }

        Node(int n, Node* p) {
            value = n;
            next = p;
        }
    };

    int size;
    Node* head;
    Node* tail;

    Node* get_node(int index) {
        if(index < 0 or index >= size) {
            throw out_of_range("IndexError: Index out of range");
        }

        Node* current = head;
        for (int i=0; i<index; i++) {
            current = current->next;
        }
        return current;
    }

public:
    linked_list();
    linked_list(vector<int> initial);
    ~linked_list();

    int operator [](int i);

    int length();

    int pop(int index);
    int pop();

    void insert(int value, int index);
    void remove(int index);
    void append(int value);
    void print();

    static void linked_list_test();
};

#endif

linked_list.cpp:

#include "linked_list.h"


linked_list::linked_list() {
    size = 0;
    head = nullptr;
    tail = nullptr;
}

linked_list::~linked_list() {
    Node* current;
    Node* next;

    current = head;

    while (current != nullptr) {
        next = current->next;
        delete current;
        current = next;
    }
}

int linked_list::operator[] (int index) {
    return get_node(index) -> value;
}

linked_list::linked_list(vector<int> initial) {
    size = 0;
    head = nullptr;
    tail = nullptr;

    for (int n: initial) {
        append(n);
    }
}

int linked_list::length() {
    return size;
}

void linked_list::append(int value) {
    if(head == nullptr && tail == nullptr) {
        head = new Node(value);
        tail = head;
        size++;
        return;
    }

    tail -> next = new Node(value);
    tail = tail ->next;
    size++;
}

void linked_list::remove(int index) {
    if(index == 0) {
        Node* current = head -> next;
        delete head;
        head = current;

    }
    else if(index == size -1) {
        Node* current = tail -> next;
        delete tail;
        tail = current;
    }

    Node* current;
    Node* previous = new Node;
    current = head;
    for (int i=0; i<index; i++) {
        previous = current;
        current = current->next;
    }
    previous->next = current->next;

    size--;
}

int linked_list::pop(int index) {
    if(index <= size) {
        int n = get_node(index) -> value;
        remove(index);

        return n;
    }

    else if(index > size) {
        throw out_of_range("IndexError");
    }
}

int linked_list::pop() {
    return pop(size - 1);
}

void linked_list::insert(int val, int index) {
    Node* previous = get_node(index-1);
    Node* next = previous -> next;
    previous ->next = new Node(val, next);
}

void linked_list::print() {
    Node* current = head;
    cout << "[";
    while (current->next != nullptr) {
        cout << current->value;
        cout << ", ";
        current = current->next;
    }
    cout << current->value << "]" << endl;
}

void linked_list::linked_list_test() {
    linked_list dynamic_list;
    dynamic_list.print();
    dynamic_list.append(9);
    dynamic_list.append(2);

    cout <<"appended 9 and 2"<< endl;
    dynamic_list.print();

    cout << "Instantiating an array with elements 3, 4, and 5" << endl;
    linked_list t_array({3, 4, 5});
    t_array.print();

    cout << "Inserting 6 to index 1 on the new array" << endl;
    t_array.insert(1, 6);
    t_array.print();

    cout << "Using pop() to remove last element in list" << endl;
    t_array.print();
}

1 个答案:

答案 0 :(得分:3)

我想我首先要使用的是您的打印功能,这种功能不能很好地处理列表为空的情况。在这里,我确保指针current为空时不要使用它。我们可以确定在while循环范围内使用它是安全的,因为我已将其限制为current != nullptr

void linked_list::print() {
    Node* current = head;
    cout << "[";
    bool bFirst = true;
    while (current != nullptr) {  // was current->next
        if (bFirst) {
            bFirst = false;
        } else {
            cout << ", ";
        }
        cout << current->value;
        current = current->next;
    }
    cout << "]" << endl; //no longer referencing current->value here where it's unsafe
}

在插入或删除节点时,您还需要照顾下一个指针和上一个指针的书

void linked_list::append(int value) {
    if(head == nullptr && tail == nullptr) {
        head = new Node(value);
        tail = head;
    } else { 
        tail->next = new Node(value);
        tail->next->previous = tail;
        tail = tail->next;
    }
    size++;
}

void linked_list::remove(int index) {
    Node* current = head;
    for (int i = 0; (i < index) && (current != null) ; i++) {
        current = current->next;
    }
    if (current != null) {
        Node* next = current->next;
        Node* previous = current->previous;

        if (next == null) {
            tail = previous; // no next
        } else {
            next->previous = previous;
        }

        if (previous == null) {
            head = next; //no previous
        } else {
            previous->next = next;
        }
        size --; //only if we found something
    }
}