【问题标题】:Inserting a new node in a singly-linked list while maintaining the sorting在保持排序的同时在单链表中插入新节点
【发布时间】:2019-06-24 07:42:57
【问题描述】:

我是个菜鸟,我正在努力正确地实现在单链表中插入新节点。我从这里和其他网站尝试了一些更易于理解的解决方案,问题肯定在我的脑海中,但我就是无法做到这一点。

所以我所拥有的是这个由 n 个节点组成的链表(其中 n 作为用户的输入给出),我试图在其中按递增顺序插入从 0 到 100 的随机数,然后我正在打印列表的内容。

我认为我的代码完全不正确,因为我得到的输出一遍又一遍是相同的数字,但除此之外,如果我更改代码以允许用户输入数字而不是随机生成它们,如果我输入两个不同的数字,程序就会崩溃(如果我一遍又一遍地输入相同的数字,它就可以正常工作)。编辑:此外,除非 srand(time(NULL));写在一个循环中,一旦我输入列表中的元素数量,程序将编译但崩溃。

我真的不明白我做错了什么。

代码如下所示:

/*The program inserts n elements generated randomly in a linked list sorted increasingly, and prints the result.*/

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

struct node {
    int num;
    node *next;
};
node *top=NULL,*nodenew;

void sortedinsert();
void printlist();

int main() {
    int n;
    do {
        cout<<"Insert the amount of elements in your list: ";
        cin>>n;
        if (n<2) {
            cout<<"The list needs to contain at least 2 nodes."<<endl;
        }
    }
    while (n<2);
    for (int i=0;i<n;i++) {
        srand(time(NULL));
        sortedinsert();
    }
    printlist();
}

void sortedinsert() {
    int gen=rand()%101;
    nodenew=new node;
    nodenew->num=gen;
    nodenew->next=NULL;
    if (top==NULL or top->num>=gen) {
        nodenew->next=top;
        top=nodenew;
        return;
    }
    else if (top->next!=NULL and top->next->num>=gen){
        node *temp=top->next;
        nodenew->next=temp;
        top->next=nodenew;
        return;
    }
    else {
        node *left;
        node *right=top;
        while (right!=NULL and right->next->num<=gen) {
            left=right;
            right=right->next;
        }
        left->next=nodenew;
        nodenew->next=right;
    }
}
void printlist() {
    cout<<"The sorted list is shown below: "<<endl;
    for (nodenew=top;nodenew!=NULL;nodenew=nodenew->next) {
        cout<<nodenew->num<<endl;
    }
}

【问题讨论】:

  • 旁注:srand(time(NULL));此初始化应该在程序的开头而不是在某个循环内
  • 旁注:while (n&lt;2);这行如果条件满足就是无限循环
  • @Spinkoo 啊是的,我忘了提,除非我放 srand(time(NULL));在一个循环中,程序崩溃了,这包括将 srand 放在 int main() { 之后,这让我觉得我的代码还有一些我可能看不到的其他潜在问题
  • 导航链表作业的最佳方式是绘制大量图片以帮助您将问题可视化。一旦您有了可以用作基线的图片,就可以逐条执行您的纸上代码,以尝试绘制相同的列表。如果你做不到,你就发现了一个错误,并且由于你有一张你应该画的图片,你可能会在你开始画错误的东西时停下来,知道错误在哪里以及你需要做什么。到那时,胜利很可能属于你。
  • 如果没有,请将您的程序放到您的开发环境中应该附带的调试器中。如果您没有调试器,请进入 1980 年代并获得带有调试器的开发环境。使用调试器,您可以控制程序的执行,如果需要,可以逐条指令推进。当程序做了一些意想不到的事情时,你只是发现了一个错误。检查所涉及的变量以了解它发生的原因。如果您必须找出任何变量错误的原因,请回溯。

标签: c++ list sorting linked-list singly-linked-list


【解决方案1】:

我已经评论了我改变的部分:)

int main() {
    int n; // as mentioned in top srand initialized at the begining 
    srand(time(NULL));

    do {
        cout << "Insert the amount of elements in your list: ";
        cin >> n;
        if (n < 2) {
            cout << "The list needs to contain at least 2 nodes." << endl;
        }
    } while (n < 2);
    for (int i = 0;i < n;i++) {
        sortedinsert();
    }
    printlist();
}

void sortedinsert() {
    int gen = rand() % 101;
    nodenew = new node;
    nodenew->num = gen;
    nodenew->next = NULL;
    // split the top part
    if (top == NULL) {

        top = nodenew;
        return;
    }
    if( top->num >= gen) {
        nodenew->next = top;
        top = nodenew;
        return;
    }

    else if (top->next != NULL and top->next->num >= gen) {
        node *temp = top->next;
        nodenew->next = temp;
        top->next = nodenew;
        return;
    }
    else {
        // left was uninitialized so if it doesn't go into the loop you are going to call left->next  Undefined behavior
       //right->next->num<=gen you don't test this until you test right->next is not null otherwise Undefined behavior as well
        node *left=top;
        node *right = top->next;

        while (right != NULL and right->num <= gen) {
            left = right;
            right = right->next;
        }       


            left->next = nodenew;
            nodenew->next = right;


    }
}

【讨论】:

  • 感激不尽,这真的帮助我理解我做错了什么!
【解决方案2】:

事实上 srand(time(NULL)) 你必须在 for 循环之前声明它,因为它给出了相同的 number 。 插入新节点时遇到问题。

在这里我已经更正了你的代码,它运行良好:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

struct node {
    int num;
    node *next;
};
node *top = NULL, *nodenew;

void sortedinsert();
void printlist();

int main() {
    int n;

    do {
        cout << "Insert the amount of elements in your list: ";
        cin >> n;
        if (n<2) {
            cout << "The list needs to contain at least 2 nodes." << endl;
        }
    } while (n<2);

    srand(time(NULL));
    for (int i = 0; i<n; i++) {


        sortedinsert();
    }
    printlist();

    system("pause");
}

void sortedinsert() {


    int gen = rand() % 101;
    cout << gen << endl;
    nodenew = new node;
    nodenew->num = gen;
    nodenew->next = NULL;
    if (top == NULL || top->num >= gen) {
        nodenew->next = top;
        top = nodenew;

    }
    else
    {
        node *A = top;
        node *B = top->next;
        while (B != NULL)
        {
            if (B->num > gen)
            {
                nodenew->next = B;
                A->next = nodenew;
                return;
            }
            else
            {

                A = B;
                B = B->next;
            }
        }
        A->next = nodenew;
        nodenew->next = NULL;
        return;
    }
}
void printlist() {
    cout << "The sorted list is shown below: " << endl;
    nodenew = top;

    for (nodenew = top; nodenew != NULL; nodenew = nodenew->next) {
        cout << nodenew->num << endl;
    }
}

【讨论】:

    【解决方案3】:

    您可以使用如下所示的 Python 代码。使用 Python 的好处是:

    --> 它现在被用于许多行业,并且在您探索数据科学和机器学习领域时会为您提供帮助。

    --> 就像实现伪代码一样简单。

    我已经向你展示了将节点插入到排序的双向链表中的python方法,尝试让代码干运行并获取逻辑,然后使用相同的方法导出单链表的代码。

    def sortedInsert(head, data):
    node = DoublyLinkedListNode(data)
    status = 0
    if not data>head.data:
        node.prev=head.prev
        head.prev=node
        node.next=head
        head=node
    else:
        dup = head
        while(data>dup.data):
            if not dup.next:
                status = 1
                break
            else:
                dup = dup.next
        if status:
            node.prev = dup
            node.next = dup.next
            dup.next = node
        else:
            node.prev = dup.prev
            dup.prev.next = node
            node.next = dup
            dup.prev = node
    return head
    

    【讨论】:

    • 所问的问题是用 C++ 编写的,可以合理地假设(因为没有其他指示)这需要在 C++ 中完成。在这种情况下,用 Python 回答没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2016-09-15
    • 2014-10-07
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    相关资源
    最近更新 更多