在链表中插入似乎将下一个指针设置错误



我正在为数据结构课程进行链表作业。插入值工作正常,但是当尝试打印出来时,程序一旦点击插入的值就会崩溃。因此,如果我在驱动程序的 switch 语句中使用 add 功能,然后尝试在其中任何一个之间插入一个值,则显示函数将在输出新数据值后立即崩溃。我已经在这个上工作了一段时间,只是似乎无法理解它。任何建议将不胜感激。

列表.h

// List.h
#ifndef LIST
#define LIST
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std; 
typedef string ElementType;
class List
{
private:
    class Node
    {
    public:
        ElementType data;
        Node * next;
        Node()
            : data(ElementType()), next(NULL)
        { }
        Node(ElementType initData)
            : data(initData), next(NULL)
        { }
    }; // end of Node class
    typedef Node * NodePointer;
public:
    List();
    /* Construct a List object
    Precondition: none.
    Postcondition: An empty List object has been constructed.
    */
    List(const List &source);
    /* Construct a copy of a List object.
    Precondition: None.
    Postcondition: A copy of source has been constructed.
    */
    ~List();
    /* Destroys a List object.
    Precondition:  None.
    Postcondition: Any memory allocated to the List object has been freed.
    */
    const List & operator=(const List &rightSide);
    /* Assign a copy of a List object to the current object.
    Precondition: none
    Postcondition: A copy of rightside has been assigned to this
    object. A constant reference to this list is returned.
    */
    int getSize() const;
    /* Returns the size of the list (number of items in the list)
    Precondition: none
    Postcondition: The return value is the number of items in the list.
    */
    bool empty() const;
    /* Check if this List is empty
    Precondition: none
    Postcondition: The return value is true if this List object is empty;
    otherwise the return value is false.
    */
    void insert(ElementType dataVal, int index);
    /* Insert a value into this List at a given index
    Precondition:  The index is valid (0 <= index <= the list size).
    The first position is index 0, the second position is index 1, etc.
    Postcondition: dataval has been inserted into the list at the position
    determined by index (provided there is room and index is a legal
    position).
    */
    void erase(int index);
    /* Remove the value from this List at a given index.
    Precondition:  The list is not empty and index is valid
    (0 <= index < the list size).
    Postcondition: the element at position index has been
    removed (provided index is a legal position).
    */
    void display(ostream &out) const;
    /* Display the contents of this List
    Precondition:  ostream out is open
    Postcondition: the items in this List have been output to stream out
    */

    int find(ElementType value) const;
    /* Find the first occurrence of a value in this List
    Preconditions:  None
    Postconditions: The return value is the index of the first List item
    that matches value. The first list item has index 0, the second has
    index 1, etc. The return value is -1 if value is not found in the list.
    */

private:
    NodePointer first;
    int mySize;
}; // end of List class
#endif

列表.cpp

#include "List.h"
#include <cassert>
// Definition of List constructor
List::List()
: first(0), mySize(0)
{}
// Definition of List copy constructor
List::List(const List &source)
{
    first = 0; 
    if (!source.empty())
    {
        first = new List::Node(source.first->data); 
        List::NodePointer lastPtr = first,
                            origPtr = source.first->next;
        while (origPtr != 0)
        {
            lastPtr->next = new List::Node(origPtr->data);
            lastPtr = lastPtr->next;
            origPtr = origPtr->next;
        }
    }
}
// Definition of List destructor
List::~List()
{
    List::NodePointer currPtr = first,
                    nextPtr;
    while (currPtr != 0)
    {
        nextPtr = currPtr->next; 
        delete currPtr; 
        currPtr = nextPtr; 
    }
}
const List & List::operator=(const List &rightSide)
{
    if (this != &rightSide) // lhs != rhs
    {
        this->~List(); 
        if (rightSide.empty())
            first = 0; 
        else
        {
            first = new List::Node(rightSide.first->data); 
            List::NodePointer lastPtr = first,
                                rhsPtr = rightSide.first->next; 
            while (rhsPtr != 0)
            {
                lastPtr->next = new List::Node(rhsPtr->data); 
                lastPtr = lastPtr->next; 
                rhsPtr = rhsPtr->next; 
            }
        }
    }
    return *this; 
}
// Definition of getSize
int List::getSize() const
{
    return mySize; 
}
// Definition of empty
bool List::empty() const
{
    return (first == 0); 
}
// Definition of insert
void List::insert(ElementType dataVal, int index)
{
    assert(index >= 0 && index <= mySize); 
    List::NodePointer ptr = first; 
    List::NodePointer predPtr = 0; 
    for (int i = 0; i < index; i++)
    {
        predPtr = ptr;
        ptr = ptr->next;
    }
    List::NodePointer newPtr = new Node(dataVal); 
    if (predPtr != 0)
    {
        newPtr->next = predPtr->next; 
        predPtr->next = newPtr; 
    }
    else
    {
        newPtr->next = first;   
        first = newPtr;         //reset first
    }
    delete ptr;                 //return pointer to heap
    mySize++;
}
// Definition of erase
void List::erase(int index)
{
    assert(!empty() && (index >= 0) && (index < mySize)); 
    List::NodePointer ptr = first;
    List::NodePointer predPtr = 0;
    for (int i = 0; i < index; i++)
    {
        predPtr = ptr;
        ptr = ptr->next;
    }
    if (predPtr != 0)
    {
        ptr = predPtr->next; 
        predPtr->next = ptr->next; 
    }
    else
    {
        ptr = first; 
        first = ptr->next; 
    }
    delete ptr;                 //return pointer to heap
    mySize--; 
}
// Definition of display
void List::display(ostream &out) const
{
    List::NodePointer ptr = first; 
    while (ptr != 0)
    {
        out << ptr->data << endl; 
        ptr = ptr->next; 
    }
}
// Definition of find
int List::find(ElementType value) const
{
    List::NodePointer ptr = first; 
    int i = 0; 
    while (ptr != 0)
    {
        if (ptr->data == value)
            return i; 
        i++; 
        ptr = ptr->next; 
    }
    return -1; 
}

啊和司机

#include <cctype>       // Provides toupper
#include <iostream>     // Provides cout and cin
#include <cstdlib>      // Provides EXIT_SUCCESS
#include <ctime>        // Provides seed for rand. 
using namespace std;
#include "List.h"  
// PROTOTYPES:
void print_menu();
// Postcondition: A menu of choices has been printed.
string get_string();
// Postcondition: The user has been prompted to enter an integer number. The
// number has been read, echoed to the screen, and returned by the function.
string generate_string(); 

int main()
{
    List test;     // A List to perform tests on
    char choice;   // Command entered by the user
    srand((unsigned int) time(0));
    cout << "I have initialized an empty list of strings." << endl;
    do
    {
        print_menu();
        cout << "Enter choice: ";
        cin >> choice;
        choice = toupper(choice);
        ElementType value;
        int position;
        switch (choice)
        {
        case 'A': 
            cout << "Enter the amount of items to add: "; 
            cin >> position; 
            for (int i = 0; i < position; i++)
            {
                test.insert(generate_string(), test.getSize());
            }
            break;
        case 'E': // Is Empty
            cout << "Empty: " << boolalpha << test.empty() << endl; 
            break;
        case 'F': // add code to find item in the list.
            break;
        case 'P': //Print
            test.display(cout); 
            break;
        case 'I': //Insert
            cout << "Enter value: "; 
            cin >> value; 
            cout << endl << "Enter position: "; 
            cin >> position; 
            test.insert(value, position);
            break;
        case 'R': //Erase
            cout << endl << "Enter position: ";
            cin >> position;
            test.erase(position);
            break;
        case 'Q': cout << "Test program ended." << endl;
            break;
        default:  cout << choice << " is invalid." << endl;
        }
    } while ((choice != 'Q'));
    return EXIT_SUCCESS;
}
void print_menu()
{
    cout << endl;
    cout << "The following choices are available: " << endl;
    cout << " A     Add a number of random strings to end of list" << endl;
    cout << " E     Print the result from the empty( ) function" << endl;
    cout << " F     Find and item in the list using find( )" << endl;
    cout << " P     Print a copy of the entire list" << endl;
    cout << " I     Insert a new string with the insert(...) function" << endl;
    cout << " R     Remove a string with the erase( ) function" << endl;
    cout << " Q     Quit this test program" << endl;
}
char get_user_command()
// Library facilities used: iostream
{
    char command;
    cout << "Enter choice: ";
    cin >> command; // Input of characters skips blanks and newline character
    return command;
}
string get_string()
// Library facilities used: iostream
{
    string result;
    cout << "Please enter an string for the list: ";
    getline(cin, result);
    cout << result << " has been read." << endl;
    return result;
}
string generate_string()
{
    const int STR_LENGTH = 5; // Length of random generated strings. 
    string randomString; 
    for (int i = 0; i < STR_LENGTH; i++)
        randomString += (char)((rand() % 52) + 65); 
    return randomString; 
}

再次感谢。

看看插入方法:

delete ptr;                 //return pointer to heap

如果要插入节点,则无需删除任何内容。此代码

newPtr->next = predPtr->next;

newPtr->next分配给ptr,删除ptr后指向已释放的内存。

逐步制作整个操作的图表(框和箭头(。这应该显示您的代码误入歧途的地方。

相关内容

  • 没有找到相关文章

最新更新