Для моего задания я должен создать список с двойной связью и рядом с ним иметь функции поиска, вставки и удаления. При разработке функции поиска я столкнулся с ошибкой: если кто-то будет искать с использованием ключа, который не может быть сопоставлен ни с чем в связанном списке, программа выйдет из строя - напечатает адрес памяти, где находятся первые данные связанный список был найден. Но, помимо этого, я столкнулся с другой ошибкой, когда, если бы я должен был искать какие-либо данные, выходящие за рамки первой записи данных, программа вылетала бы из строя - печатая адрес памяти первой записи.

Эти проблемы связаны с тем, что моя функция поиска неправильно выполняет итерацию по всему списку, а может без проблем прочитать только первую запись. Поэтому, если бы я попытался получить доступ к любым данным, выходящим за рамки первой записи, вся программа вылетела бы. Я знаю, что в конечном итоге проблема, но я не понимаю, что я сделал, что вызвало это, и как мне это исправить.

Header.h:

#pragma once
#ifndef Header_H
#define Header_H
#include "stdafx.h"
#include<iostream>
#include <string>

template<typename T>
struct Node {
    T record;
    Node<T> *next;
    Node<T> *prev;
    Node() {
        next = NULL;
        prev = NULL;
    }
};


template<class T> 
class datax {
    Node<T> *top;
    Node<T> *bot;
public:
    datax() {
        top = NULL;
        bot = NULL;
    }
    ~datax() {}
    //Searches the list that has a requested key word
    void find();
    //Inserts into the list a requested word
    void insert();
    //Searches the list for a requested key word and pops it out
    void Delete();
    void show();
private:
};

template<typename T>
void datax<T>::show() {
    Node<T> *temp = top;
    while (temp != NULL) {
        cout << temp->record << "";
        temp = temp->next;
    }

}
template<typename T>
void datax<T>::Delete() {
    T get;
    Node<T>*ser = top;
    cin >> get;
    while (ser != NULL && ser->record != get) {
        ser = ser->next;

    }
    if (ser != NULL && ser->record == get) {
        cout << "Removing data from " << ser << endl;
        ser->next->prev = ser->prev;
        delete ser;
    }
    else {
        cout << "Data not found" << endl;
    }
}

template<typename T> 
void datax<T>::insert() {
    T val;
    Node<T> *ptr = new Node<T>;
    cin >> val;
    ptr->record = val;
    ptr->next = NULL;
    if (bot != NULL) {
        bot->next = ptr;
        ptr->prev = bot;
    }
    if (top == NULL) {
        top = ptr;
    }
    bot = ptr;
}
template<typename T>
void datax<T>::find() {
    T get;
    Node<T>*ptr= top;
    cin >> get;
    if (ptr == NULL) {
        cout << "Data not found" << endl;
    }
    else {
        while (top != NULL && ptr->record != get) {
            top->next = ptr;
        }

        if (ptr != NULL && ptr->record == get) {
            cout << "Found: " << ptr << endl;
        }
        else {
            cout << "Data not found" << endl;
        }
    }

}

#endif // !Header_H

Основной:

// LinkedList.cpp : Defines the entry point for the console application.
//

    #include "stdafx.h"
    #include<iostream>
    #include <string>
    #include"Header.h"
    using namespace std;
        int main()
        {
            int take;
            datax<int> m;
            while (true) {
                cout << "\n\n1. Insert\n\n2.Find\n\n3.Delete" << endl;
                cin >> take;
                switch (take) {
                case 1:
                    m.insert();
                    m.show();
                    break;
                case 2:
                    m.find();
                    break;
                case 3:
                    m.Delete();
                    m.show();
                    break;
                default:
                    cout << "Error" << endl;
                }
            }
            return 0;
        }
c++
-1
pk pulse fall 6 Окт 2018 в 00:15

1 ответ

Лучший ответ

Взгляните на свой цикл поиска:

while (top != NULL && ptr->record != get) {
    top->next = ptr;
}

Теперь ваше условие состоит в том, чтобы вы продолжали цикл до тех пор, пока либо top не станет NULL ИЛИ ptr->record будет тем, что вы ищете. Но в теле вашего цикла меняется ли top? Меняется ли ptr ?? Нет!

Другими словами, если вы не выйдете из этого цикла с первого раза, вы никогда не выйдете .

Вы, вероятно, хотели, чтобы это выглядело так:

while (ptr != NULL && ptr->record != get) {
    ptr = ptr->next;
}

Или, если вы чувствуете себя модно и хотите однострочник (этот IMO все еще читается):

for(ptr = top; ptr && ptr->record != get; ptr = ptr->next) { }
1
scohe001 23 Фев 2021 в 19:38