简体   繁体   English

在C ++中按字母顺序将节点添加到链表

[英]Adding nodes to linked list alphabetically in c++

I'm trying to make a linked list that gets words from the user until the input is blank, and every word is added so the list stays in alphabetical order. 我正在尝试创建一个链接列表,该列表从用户那里获取单词,直到输入为空,并且添加了每个单词,以便列表按字母顺序排列。 However, only the first node is printed. 但是,仅打印第一个节点。 Is there something I'm doing wrong? 我做错了什么吗? Here's what I have (minus the header and declarations): 这是我所拥有的(减去标题和声明):

    //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);
};

} }

I would post this as a comment, because I am afraid I might be missing something, but I can't yet do this, so here goes a non-answer: 我将其发布为评论,因为恐怕我可能会遗漏一些东西,但是我还不能做到这一点,因此这里没有答案:

What keeps you from using the std::list ? 是什么让您无法使用std :: list You can insert a word, check if it is non-empty, immediately apply a the standard sorting algorithm (It relies on the comparison operators of the sorted objects) and print it. 您可以插入一个单词,检查它是否为非空,立即应用标准的排序算法 (它依赖于排序对象的比较运算符)并打印出来。 It is fast, your code is short and readable and you don't spend your time reinventing the wheel. 它速度很快,您的代码简短易读,并且您无需花费时间重新发明轮子。

PS: If you want to test for an empty string it should be "" , not " " , I think. PS:如果您想测试一个空字符串,我想应该是"" ,而不是" "

I think there is a number of issues here. 我认为这里有很多问题。

For one in the initial iteration what is prevPtr->data pointing at? 对于初始迭代中的一个,prevPtr-> data指向什么? If it's pointing at nothing or hasn't been allocated to any memory you shouldn't be setting this to anything yet. 如果它什么也没有指向或尚未分配给任何内存,则不应将其设置为任何值。

Plus you need to allocate memory for newPtr on every iteration, otherwise you are just writing over the memory location of where it is pointing to last from the in the list. 另外,您需要在每次迭代时为newPtr分配内存,否则,您将只写列表中指向它最后的位置的内存位置。

Second lets assume that prevPtr is pointing to something, on the second iteration (or more) of this while loop prevPtr has been moved farther down the list (prevPtr = nextPtr) which would cause prevPtr->data = " " to erase any data in that element. 第二个让我们假设prevPtr指向某个对象,在此过程的第二次迭代(或更多次迭代)上,而循环prevPtr已移到列表的更下方(prevPtr = nextPtr),这将导致prevPtr-> data =“”擦除其中的任何数据。该元素。 So you could be printing the first node plus a bunch of spaces afterwards. 因此,您可以随后打印第一个节点以及一堆空格。

Third you should check if list is NULL first in your loop, because if loop is NULL, nextPtr->data would be pointing at junk which is not good. 第三,您应该首先在循环中检查list是否为NULL,因为如果循环为NULL,则nextPtr-> data将指向垃圾,这不好。 This NULL check on list could be your corner case of the first element. 列表上的NULL检查可能是第一个元素的特殊情况。

Try something like this, I didn't have time to test it but it should get going in the right direction: 尝试这样的事情,我没有时间对其进行测试,但是它应该朝着正确的方向发展:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM