程序不读取和添加节点到2双链表c++

Program not reading in and adding node to 2 doubly linked lists C++

本文关键字:2双 链表 c++ 节点 添加 读取 程序      更新时间:2023-10-16

这是家庭作业!

我的任务是创建两个双重链表,一个用于偶数,一个用于奇数。这些列表将通过从整数文件中读入来填充。我必须搜索正确的列表(偶数或奇数,取决于从文件中读取的数字),以查看从文件中读取的数字是否已经在列表中。如果是,我必须忽略这个数字,继续前进。我们不允许使用OOP,但是我们正在研究ADT的概念。请不要在你的回答中包含任何OOP,因为我不允许使用它,而且我还不知道如何阅读它。

当我运行我的代码时,它编译没有错误,但它返回-1。在进行了一些调试之后,我发现它正在为每个列表读入并插入第一个数字,但在插入第二个数字时却挂起了。然而,我似乎无法弄清楚是什么导致它以-1退出。如果有人能给我指出正确的方向,问题在哪里,我将不胜感激。

噢,还有,程序将获取要从中读取整数的文件的文件名,以及稍后将在程序中使用的另一个文件的文件名(我还没有讲到这部分)作为命令行参数。

#include <iostream>
#include <fstream>
#include <cstddef>
#include <iomanip>
using namespace std;
struct doublyLinkList{
    int numberRead;
    doublyLinkList* prev;
    doublyLinkList* next;
    };
struct topAndCounter{
    int counter;
    doublyLinkList* head;
    };
void initializeList(topAndCounter& aLinkList);
bool searchOrderedList(topAndCounter aLinkList, int tempIntHold);
void orderedListInsertion(topAndCounter& aLinkList, bool& success, int tempIntHold);
bool isEmptyList(topAndCounter& aLinkList);
int main(int argC, char* argV[])     // allows usage of command line arguments
{
    ifstream intsForList;
    ifstream intsToSearchFor;
    topAndCounter evenList;        // even list struct
    topAndCounter oddList;         // odd list struct
    int tempIntHold;               // holds integer read in from file
    string storeIntsFile;          // holds name of file
    string intsToFindFile;         // holds name of file
    bool success = true;           // whether memory was successfully allocated

    cout << endl << endl;
    cout << "Program to read in and store a list of unique integers from one ";
    cout << "file and match numbers to it from a second file." << endl << endl;

    switch(argC) // takes the argument count
    {
    case 1:
        cout << "You didn't enter any filenames on the command line." << endl;
        cout << "Please enter them now" << endl;
        cout << "Filename for list of integers to store: ";
        cin >> storeIntsFile;
        cout << "Filename for integers to search list for: ";
        cin >> intsToFindFile;
        break;
    case 2:
        cout << "You didn't enter the file name of integers to search the list";
        cout << " for" << endl;
        cout << "Please enter it now: ";
        cin >> intsToFindFile;
        storeIntsFile = argV[1];
        break;
    case 3:
        storeIntsFile = argV[1];
        intsToFindFile = argV[2];
        break;
    }
    intsForList.open(storeIntsFile.c_str());        // trys to open first file
    intsToSearchFor.open(intsToFindFile.c_str());   // tries to open second file
    // if files are not opened successful        
    if ((!intsForList) || (!intsToSearchFor))
    {
        while(!intsForList)  // while the first file is not opened successfully
        {
            cout << "File for integers to populate list not found. " << endl;
            cout << "Please enter another filename: ";
            cin >> storeIntsFile;
            intsForList.open(storeIntsFile);  // try to open file
        } // end while
        while(!intsToSearchFor)  // while the second file is not opened successfully
        {
            cout << "File containing integers to search list for not found.";
            cout << endl;
            cout << "Please enter another filename: ";
            cin >> intsToFindFile;
            intsToSearchFor.open(intsToFindFile);  // try to open file
         } // end while
    } // end if
    initializeList(evenList);       // function call to initialize list to NULL
    initializeList(oddList);        // function call to initialize list to NULL
    intsForList >> tempIntHold;     // read in the first integer from the file
    while((intsForList) && (success))   // while there is still integers in the file and memory 
                                        // allocated successfully
    {
        if (tempIntHold % 2 == 0)      // if the number read from the file is even
        {
            orderedListInsertion(evenList, success, tempIntHold);  // call the even sort funct
        } // end if
        else                         // if the number is odd
        {
            orderedListInsertion(oddList, success, tempIntHold);   // odd num sort funct
        } // end else
        intsForList >> tempIntHold; // try to read next integer in file
    } // end while

    return 0;
}
void initializeList(topAndCounter& aLinkList)
{
    aLinkList.counter = 0;
    aLinkList.head = NULL;                     // initialize head pointer to null
    return;
}
// function to search the list to see if the number read in from file is already in list
bool searchOrderedList(topAndCounter aLinkList, int tempIntHold)
{
    bool found = false;
    doublyLinkList* searchNode;                      // pointer for searching list
    searchNode = aLinkList.head;                     // set pointer to top of list
    while ((searchNode != NULL) && (!found))       // there are nodes in list and the number is 
                                                   // not found
    { 
        if (searchNode -> numberRead >= tempIntHold) 
        {
            found = true;
        }
        else
        {
            searchNode = searchNode -> next;  // move pointer to next node
        }
    }
    if (found) 
    {
         found = (searchNode -> numberRead == tempIntHold);
    }
    return found;
} // end function
void orderedListInsertion(topAndCounter& aLinkList, bool& success, int tempIntHold)
{
    doublyLinkList* newNode;
    doublyLinkList* searchNode;
    bool intInUse;
    bool found;
    newNode = new (nothrow) doublyLinkList;
    if (newNode != NULL)
    {
        intInUse = searchOrderedList(aLinkList, tempIntHold);
        if (intInUse)
        {
            cout << "The current interger is already in the list.  It will now ";
            cout << "be  ignored" << endl;
        } // end if
        else
        {
            newNode -> numberRead = tempIntHold;
            if (isEmptyList(aLinkList))
            {
                newNode -> prev = NULL;
                newNode -> next = NULL;
                aLinkList.head = newNode;
            } // end if
            else
            {
                searchNode = aLinkList.head;
                found = false;
                while((searchNode != NULL) && (!found))
                {
                    if (searchNode -> numberRead > newNode -> numberRead)
                    {
                        found = true;
                    } // end if
                    else
                    {
                         searchNode = searchNode -> next;
                    } // end else
                } // end while
                if (searchNode == aLinkList.head)
                {
                    newNode -> next = searchNode;
                    newNode -> prev = NULL;
                    searchNode -> prev = newNode;
                    aLinkList.head = newNode;
                } // end if
                else
                {
                    if(searchNode == NULL)
                    {
                        newNode -> prev = searchNode -> prev;
                        newNode -> next = searchNode;
                    } // end if
                    else
                    {
                    newNode -> prev = searchNode -> prev;
                    newNode -> next = searchNode;
                    searchNode -> prev = newNode;
                    } // end else
                } // end else
                newNode -> next = searchNode;
                newNode -> prev = searchNode -> prev;
                searchNode -> prev = newNode;
            } // end else
            aLinkList.counter++;
            success = true;
        } // end else
    } // end if
    else
    {
        cout << "No more heap memory.  No more integers from the list will be";
        cout << " stored." << endl;
        success = false;
    } // end else
    return;
} // end function
bool isEmptyList(topAndCounter& aLinkList)
{
    if (aLinkList.head == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }
} // end function

忽略"这是作业,所以我不能做对"的方面,结果可能是这样的:

#include <set>
#include <vector>
#include <string>
#include <iostream>
int main() { 
    std::vector<std::set<int>> sets(2);
    std::vector<std::string> names {"Even numbers", "Odd numbers"};
    int num;
    while (std::cin >> num)
       sets[num % 2].insert(num);
    for (int i=0; i<sets.size(); i++) {
        std::cout << "n" << names[i];
        for (int j : sets[i])
            std::cout << "t" << j;
    }
}

这里没有OOP。事实上,这部分标准库的主要设计者(Alexander Stepanov)非常清楚地表明,他不是特别喜欢面向对象,而且真的根本没有时间研究它。

至于其余的需求,很抱歉,但它们太愚蠢了,无法考虑,更不用说实现了。与许多教师的想法相反,将集合实现为链表是一个非常糟糕的想法。

我不会在这里给你完整的答案,但我确实有一些评论,希望能帮助你自己解决这个问题。

  1. 我发现了一个访问冲突(你在第213行周围取消了NULL指针的引用):

    if(searchNode == NULL)
    {
        newNode -> prev = searchNode -> prev; // HERE, searchNode == NULL
        newNode -> next = searchNode;
    } // end if
    else
    {
       newNode -> prev = searchNode -> prev;
       newNode -> next = searchNode;
       searchNode -> prev = newNode;
    } // end else
    
  2. 让我吃惊的是,你有很多代码应该分解成更小的函数。

    我给你的建议是把你的代码重写成更小的函数,每个函数有一个非常具体的任务。

    例如:

    // Inserts an element, and returns a pointer to the newly inserted element.
    doublyLinkList * insert_at_end( topAndCounter &head, int val );
    doublyLinkList * insert_before( topAndCounter &head, doublyLinkList *existing, int val );
    
    换句话说,如果您有上面提到的两个函数,那么orderedListInsertion中的所有代码都可以简化为:
    void orderedListInsertion(topAndCounter& aLinkList, bool& success, int tempIntHold) {
        success = false;
        doublyLinkList *current = aLinkList->head;
        while (current != NULL) {
           if (current->numberRead == tempIntHold ) // Duplicate
               return;
           else if ( tempIntHold < current->numberRead ) {
                    insert_before(aLinkList, current, tempIntHold);
                    success = true;
                    return;
           }
        }
        insert_at_end(aLinkList, tempIntHold);
        success = true;
    }
    

    更好的是,提前测试小函数要容易得多,这样你就可以确定程序的哪些部分是有效的。