【问题标题】:C++ Singly Linked List Insertion SortC++ 单链表插入排序
【发布时间】:2016-02-14 01:17:13
【问题描述】:

嘿,我的这个项目有问题。我应该从文件中读取整数并将它们插入到列表中。需要实现一个 findSpot 函数,它遍历链表,如果下一个节点的值大于正在检查的值,则返回当前的“点”。然后我们将链表输出到一个单独的文件中。

这是代码。

#include <iostream>
#include <fstream>
using namespace std;

class listNode {

public:
    int value;
    listNode* next;
    friend class linkedList;

    listNode()
        : value(0)
        , next(NULL)
    {
    }

public:
    ~listNode(){

    };
};

class linkedList {
    listNode* listHead;

public:
    linkedList()
        : listHead(NULL)
    {
    }

    bool isEmpty()
    {
        return (listHead == 0);
    }

    void listInsert(int data, listNode* spot)
    {

        listNode* newNode;
        newNode->value = data;
        newNode->next = NULL;

        if (isEmpty()) {
            listHead = newNode;
        }

        else {
            newNode->next = spot->next;
            spot->next = newNode;
            cout << newNode;
        }
    }

    /*void listDelete ()
    {

    }*/

    listNode* findSpot(int data)
    {
        listNode* spot;
        spot = listHead;

        while (spot->next != 0 && spot->next->value < data) {
            spot = spot->next;
        }

        return spot;
    }

    void printList(listNode* spot)
    {
        listNode* newNode = spot;

        while (newNode != NULL) {
            cout << "Inserting " << newNode->value << ": "
                 << "listHead-->(" << newNode->value << "," << newNode->next->value << ")-->(";
            newNode = newNode->next;
        }

        cout << endl;
    }

    /*~linkedList()
    {
        listNode* temp = spot->next;
        spot->next = spot->next->next;
        delete temp;

    }*/
};

int main(int argc, char* argv[])
{

    int data;
    listNode* spot;

    ifstream infile;
    infile.open(argv[1]);
    ofstream outfile(argv[2]);

    cout << "Reading Data from the file" << endl;

    while (infile >> data) {
        cout << data << endl;
    }

    infile.close();

    linkedList myList;
    infile.open(argv[1]);

    while (infile >> data) {
        myList.findSpot(data);
        myList.listInsert(data, spot);
        myList.printList(spot);
    }

    cout << "Printing your linked list to the output file.";

    /*while (outfile.is_open())
    {
        myList.printList();

    }*/

    infile.close();
    outfile.close();

    return 0;
}

不知道问题主要出在insertList函数还是findSpot函数。 findSpot 函数对我来说似乎是正确的,但我可能只是遗漏了一些东西。

当我运行代码时,第一次实际读取文件没问题。实际上,将任何内容插入到链表中都会导致程序挂起。

【问题讨论】:

  • 为什么你的代码里都是空行?它使阅读变得非常困难。在从文件中读取任何内容之前,您应该测试您的链表是否真的与一个小的 main 函数一起使用,该函数调用插入具有硬编码值的条目,以便您(和其他人)轻松诊断.如果您的链表根本不起作用,那么担心文件读取是没有意义的。
  • 哦,对不起,我想这只是一个奇怪的个人喜好。空旷的空间让我可以很容易地区分东西XD
  • 请正确重新格式化和重新缩进您的代码。难道你不想让你的代码尽可能地易于理解和可读,让其他人更容易看到你做了什么,问题出在哪里?

标签: c++ linked-list insertion-sort


【解决方案1】:

好的,让我们再试一次。我实际上会包含一些代码,但请尝试将其用作学习点,而不是仅仅复制粘贴。我知道你说你在复制你老师的算法,但他们给你的可能只是那个,一个算法。你的工作是在工作代码中实际实现它,检查错误条件等。无论如何,我们开始吧:

对于函数findSpot:

listNode* linkedList::findSpot(int data) {
  listNode* spot = listHead;  // Initialize spot to start of list

  if ( isEmpty() )    // if list is empty, return NULL
    return NULL;

  // now we know listHead isn't null, so look through the list and
  // find the entry that has a value greater than the one provided
  // return the list item BEFORE the one with the greater value
  while (spot->next != 0 && spot->next->value < data) {
    spot = spot->next;
  }

  // return the one we found;  This could be the same as listHead
  // (start of list), something in the middle, or the last item on the
  // list.  If we return from here, it will not be NULL
  return spot;
}

现在我们可以执行插入功能了:

void linkedList::listInsert(int data, listNode* spot) {

  // We need a new item to put on the list, so create it
  listNode* newNode = new listNode();
  newNode->value = data;
  newNode->next = NULL;

  // If the list is empty, update the head to point at our new object
  if ( isEmpty() ) {
    listHead = newNode;

  // otherwise point spot to new item, and new item to the one spot
  // pointed to
  } else {
    newNode->next = spot->next;
    spot->next = newNode;
  }
}

查看您的打印功能,这将有它自己的问题。看起来您想打印整个列表,但似乎您是从“spot”开始打印的。这一切都非常混乱。使用 newNode->next->value 也有问题,没有检查 newNode->next 是否为 NULL。这是我认为您正在尝试做的一个简短示例...请注意,我什至不需要通过现场,只需添加数据点:

void linkedList::printList(int data) {

  // if some huckleberry called this before calling insert,
  // list will be empty... always a good idea to check
  if ( isEmpty())
    return;

  // first line of output... just print out the data point
  // added and start of output text
  cout << "Inserted " << data << ": " << "listHead-->(";

  // start at start of list
  listNode* newNode = listHead;

  // loop through until we find the end
  while (newNode != NULL) {

    cout << newNode->value;       // print the value
    newNode = newNode->next;      // move to the next item on the list

    // We moved to the next node;  It might be NULL and the loop will end
    // if not, we want to print an open bracket since we know another one
    // is going to be printed
    if ( newNode != NULL )
      cout << ")-->(";
  }

  // last item was just printed, so close off the last bracket
  cout << ")" << endl;
}

希望对你有所帮助

【讨论】:

    【解决方案2】:

    因为这看起来像是一项家庭作业,所以我要给你一个解决办法:

    改变

    myList.findSpot(data);
    

    spot = myList.findSpot(data);
    

    如果您仔细观察,会使用点,但从未分配任何内容。

    【讨论】:

    • 谢谢我在一些摆弄之后忘了把它改回来。但现在我真的被困住了。我似乎无法确切找出链接列表有什么问题。所有参数似乎都已正确初始化,但什么不是?
    • 好的。我再给你一个:这里没有初始化newNode:istNode* newNode;新节点->值=数据; newNode->next = NULL;
    • 哦,你的意思是通过 listNode* newNode = new listNode; 来初始化它吗? ?
    【解决方案3】:

    嗯,你的程序有几个问题(除了格式)。在函数 findSpot() 中,您有:

    listNode* spot;
    spot = listHead;
    
    while (spot->next != 0 && spot->next->value < data) {
       spot = spot->next;
    }
    return spot;
    

    这里的问题是,第一次调用这个,listHead是NULL,所以

    while (spot->next
    

    将失败,因为 spot 为 NULL。

    我还注意到,您的代码中没有任何地方调用 new()。在 listInsert 中,你需要使用 new() 来初始化你的 newNode 变量。

    最后,find spot 有两个条件可以返回 NULL。如果列表为空,它应该返回 NULL,并且您希望在列表的开头插入。如果您添加的新值大于其他所有值,您还将返回 NULL,并且您必须添加到列表的末尾。

    由于这是一项家庭作业,我不想为您编写代码,但希望对您有所帮助。

    【讨论】:

    • 既然 listHead 为空,函数不会只返回 Spot(当前在 listHead 吗?) While 循环只会导致它遍历,在这种情况下不需要遍历,因为没有什么可以穿越的?当我使用listIInsert函数时不会,它不会使用spot(即listHead)首先插入一个新节点吗?
    • 不,它不会返回 null,它会崩溃。原因是您在 while 循环中检查 spot->next。如果 spot 为 NULL,您正在尝试执行 NULL->next,这是一个问题
    • 我不确定如何进行此修复?我的教授给我的算法几乎就是这样。我不认为我应该只用随机值初始化 listHead?
    • 嘿,不,这不是一个好主意。也许在进入 while 循环之前检查列表是否为空? (如果是则返回NULL?)
    • 嗯,我记得我的教授说过要为 listHead 创建一个虚拟/垃圾节点,所以我尝试将它的值初始化为 -9999。原来我的插入工作现在......太糟糕了,我现在必须处理重复的条目。 XD
    猜你喜欢
    • 2020-06-13
    • 2020-12-11
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 2013-04-04
    • 2012-12-29
    • 1970-01-01
    相关资源
    最近更新 更多