【问题标题】:Adding nodes to linked list alphabetically in c++在 C++ 中按字母顺序将节点添加到链表
【发布时间】:2012-10-16 22:39:30
【问题描述】:

我正在尝试创建一个链接列表,从用户那里获取单词,直到输入为空白,然后添加每个单词,以便列表保持字母顺序。但是,只打印第一个节点。有什么我做错了吗?这是我所拥有的(减去标题和声明):

    //put in additional nodes until the input is blank
while(in != " "){
    cin >> in;
    newPtr->data = in;
    prevPtr->data = "";
    prevPtr->next = NULL;
    nextPtr = list;
    //shift the prevPtr and nextPtr until newPtr is alphabetically between them
    while(!(prevPtr->data<=in && nextPtr->data>in)){
        prevPtr = nextPtr;
        nextPtr = prevPtr->next;
    }
    //make newPtr point to the next node
    if(nextPtr != NULL){
        newPtr->next = nextPtr;
    }
    //make newPtr the "next" pointer of the previous node, if any
    if(prevPtr != NULL){
        prevPtr->next = newPtr;
    }
    //if there's nothing before newPtr, make it the first node
    else{
        list = newPtr;
    }
    printList(list);
};

}

【问题讨论】:

  • 我认为你应该发布你的整个程序。
  • 我同意 paddy,你至少应该给我们 printList 的代码

标签: c++ sorting linked-list


【解决方案1】:

我会将此作为评论发布,因为我担心我可能会遗漏一些东西,但我还不能这样做,所以这里没有答案:

是什么阻止您使用std::list?您可以插入一个单词,检查它是否为非空,立即应用标准sorting algorithm(它依赖于已排序对象的比较运算符)并打印它。它速度快,您的代码简短易读,而且您不会花时间重新发明轮子。

PS:如果你想测试一个空字符串,我认为它应该是 "",而不是 " "

【讨论】:

  • 老实说。我在课堂上这样做,老师希望我们这样做。这个问题对于希望了解内部库内部运作的未来读者也很有用。
  • 别担心,我们都去过那里。这东西需要时间
【解决方案2】:

我认为这里有很多问题。

对于初始迭代中的一个,prevPtr->data 指向什么?如果它没有指向任何内容或尚未分配给任何内存,则您不应该将其设置为任何内容。

另外,您需要在每次迭代时为 newPtr 分配内存,否则您只是在覆盖列表中它指向的最后一个内存位置。

第二个假设 prevPtr 指向某个东西,在此 while 循环的第二次(或更多)迭代中,prevPtr 已在列表中向下移动(prevPtr = nextPtr),这将导致 prevPtr->data = " " 擦除该元素中的任何数据。所以你可以打印第一个节点加上一堆空格。

第三,你应该在你的循环中首先检查 list 是否为 NULL,因为如果循环为 NULL,nextPtr->data 将指向垃圾,这是不好的。这个对列表的 NULL 检查可能是第一个元素的极端情况。

尝试这样的事情,我没有时间测试它,但它应该朝着正确的方向前进:

Node *list = NULL; 

while(in != " "){
    cin >> in;
    Node *newPtr = new Node();
    newPtr->data = in;
    newPtr->next = NULL;

    prevPtr = list;
    nextPtr = list;

    // Do we have an empty list
    if(list != NULL)
    {
        // Corner Case: First on the list
        if(newPtr->data <= prevPtr->data)
        {
            list = newPtr;
            newPtr->next = prevPtr;
        }
        else
        {
            // CASE: Somewhere between the first and the list
            while(nextPtr->next != NULL)
            {
                nextPtr = nextPtr->next;
                if(newPtr->data >= prevPtr->data && newPtr->data <= nextPtr->data)
                {
                    prevPtr->next = newPtr;
                    newPtr->next = nextPtr;
                    break;
                }
                prevPtr = prevPtr->next;
            }

            // Corner Case: end of list
            if(nextPtr->next == NULL)
            {
                nextPtr->next = newPtr;
            }
        }
    }
    else 
    {
        // Corner Case: We had an empty list
        list = newPtr;
    }
    printList(list);

【讨论】:

  • 循环之前是这组声明:list = new Node;串入;辛 >> 在;列表->数据=在;列表->下一个 = NULL; newPtr = 新节点; prevPtr = 新节点;这足够了吗?如果不是,你将如何分配内存?
  • 你可以让它工作,但你不需要分配prevPtr,你应该在循环的每次迭代中分配newPtr。我在答案中添加了更多内容,请查看。
猜你喜欢
  • 2012-11-05
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
相关资源
最近更新 更多