单链接列表添加功能 - 读取访问冲突

时间:2016-05-06 20:14:14

标签: c++ linked-list visual-studio-2015

我正在尝试使用单独的Node类和LinkedList类创建一个基本的单链表。我刚开始学习C ++时几乎不知道自己在做什么,所以非常感谢任何帮助。

代码的LinkedList部分独立运行,但我确信在那里也有一些更正。我的主要问题是,当我尝试添加到链表时,我得到了(在LinkedList.h的第64行):

  

抛出异常:读取访问冲突。 this-> head是nullptr。

我正在使用Microsoft Visual Studio 2015.这是代码:

LinkedList.h(它是内联的):

#pragma once
#include <iostream>

using namespace std;

class Node
{
private:
    Node *next = NULL;
    int data;



public:
    Node(int newData) {
        data = newData;
        next = NULL;
    }
    Node() {

    }
    ~Node() {
        if(next)
            delete(next);
    }
    Node(int newData, Node newNext) {
        data = newData;
        *next = newNext;
    }
    void setNext(Node newNext) {
        *next = newNext;
    }
    Node getNext() {
        return *next;
    }
    int getData() {
        return data;
    }

};


class LinkedList
{

private:
    Node *head;
    int size;
public:

    LinkedList()
    {
        head = NULL;
        size = 0;
    }

    ~LinkedList()
    {

    }

    void add(int numberToAdd)
    {
        head = new Node(numberToAdd, *head);
        ++size;
    }

    int remove()
    {
        if (size == 0) {
            return 0;
        }
        else {
            *head = (*head).getNext();
            --size;
            return 1;
        }
    }

    int remove(int numberToRemove)
    {
        if (size == 0)
            return 0;
        Node *currentNode = head;
        for (int i = 0; i < size; i++) {
            if ((*currentNode).getData() == numberToRemove) {
                *currentNode = (*currentNode).getNext();
                return 1;
            }
        }
    }

    void print()
    {
        if (size == 0) {
            return;
        }
        else {
            Node currentNode = *head;
            for (int i = 0; i < size; i++) {
                cout << currentNode.getData();
                currentNode = currentNode.getNext();
            }
            cout << endl;
        }
    }

};

列出Tester.cpp

    // List Tester.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include "LinkedList.h"

using namespace std;

int main()
{
    LinkedList myList;
    myList.add(4);
    system("pause");
}

2 个答案:

答案 0 :(得分:0)

你正在复制你不应该的地方:

此:

Node(int newData, Node newNext) {
    data = newData;
    *next = newNext;
}

应该是:

Node(int newData, Node* newNext) {
    data = newData;
    next = newNext;
}

因为现在这个:

head = new Node(numberToAdd, *head);

成为这个:

head = new Node(numberToAdd, head);

即使head是空指针也会有效。您可能需要相应地调整其他代码。

答案 1 :(得分:0)

您的整个实施都充满了错误。它应该看起来更像是这样:

#pragma once
#include <iostream>

class Node
{
private:
    int data;
    Node *next;

public:
    Node(int newData, Node *newNext = NULL)
        : data(newData), next(newNext)
    {}

    void setNext(Node *newNext) {
        next = newNext;
    }

    Node* getNext() {
        return next;
    }

    int getData() {
        return data;
    }
};

class LinkedList
{
private:
    Node *head;
    int size;

public:
    LinkedList()
        : head(NULL), size(0)
    {
    }

    ~LinkedList()
    {
        Node *currentNode = head;
        while (currentNode)
        {
            Node *nextNode = currentNode->getNext();
            delete currentNode;
            currentNode = nextNode;
        }    
    }

    void add(int numberToAdd)
    {
        head = new Node(numberToAdd, head);
        ++size;
    }

    bool remove()
    {
        Node *currentNode = head;
        if (!currentNode)
            return false;

        head = currentNode->getNext();
        delete currentNode;
        --size;

        return true;
    }

    bool remove(int numberToRemove)
    {
        Node *currentNode = head;
        Node *previousNode = NULL;

        while (currentNode)
        {
            if (currentNode->getData() == numberToRemove)
            {
                if (head == currentNode)
                    head = currentNode->getNext();
                if (previousNode)
                    previousNode->setNext(currentNode->getNext());
                delete currentNode;
                return true;
            }

            previousNode = currentNode;
            currentNode = currentNode->getNext();
        }

        return false;
    }

    void print()
    {
        Node *currentNode = head;
        if (!currentNode) return;
        do
        {
            std::cout << currentNode->getData();
            currentNode = currentNode->getNext();
        }
        while (currentNode);
        std::cout << std::endl;
    }    
};

然后可以使用std::forward_list类简化(如果您使用的是C ++ 11或更高版本):

#pragma once
#include <iostream>
#include <forward_list>
#include <algorithm>

class LinkedList
{
private:
    std::forward_list<int> list;

public:
    void add(int numberToAdd)
    {
        list.push_front(numberToAdd);
    }

    bool remove()
    {
        if (!list.empty())
        {
            list.pop_front();
            return true;
        }
        return false;
    }

    bool remove(int numberToRemove)
    {
        std::forward_list<int>::iterator iter = list.begin();
        std::forward_list<int>::iterator previous = list.before_begin();

        while (iter != list.end())
        {
            if (*iter == numberToRemove)
            {
                list.erase_after(previous);
                return true;
            }

            ++previous;
            ++iter;
        }

        return false;
    }

    void print()
    {
        if (list.empty()) return;
        std::for_each(list.cbegin(), list.cend(), [](int data){ std::cout << data });
        std::cout << std::endl;
    }    
};