在单链列表中插入新节点,同时保持排序

时间:2019-01-30 22:30:02

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

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

所以我所拥有的这个链表是由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;
    }
}

3 个答案:

答案 0 :(得分:0)

我已评论了我更改的部分:)

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;


    }
}

答案 1 :(得分:0)

实际上srand(time(NULL))必须在for循环之前声明,因为这样它会给出相同的数字。 并且在插入新节点时遇到问题。

在这里,我已经更正了您的代码,并且效果很好:

#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;
    }
}

答案 2 :(得分:-1)

您可以使用如下所示的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