简体   繁体   English

如何在链表 C++ 的开头插入一个数字?

[英]How can I insert a number to the beginning of a linked list c++?

I am trying to insert a number into a linked list that is sorted in increasing order, I have the parts where I insert in the middle and at the end but I can seem to do it when the value is less than the starting value.我试图将一个数字插入到按递增顺序排序的链表中,我在中间和最后插入了部分,但是当值小于起始值时,我似乎可以这样做。

void List::InsertInFibonacci()
{
first = new Node(0,NULL);
Node* current = first;
Node* second = new Node (1,NULL);
current->setNext(second);
bool x = true, y = true;
// Algorithm for Fibonacci Sequence
for(int i = 0;i<5;i++)
{
    current = first;
    while(current&&x==true)
    {
        if(current->getNext()->getNext()==NULL)
        {
            x=false;
        }
        else
        {
            current = current->getNext();
        }
    }
    int temp = current->getData() + current->getNext()->getData();
    Node* slider = new Node(temp,NULL);
    current->getNext()->setNext(slider);
    x=true;
}
current=first;
Node* number = new Node(-4,NULL);
// Loop to insert a number inside my sorted list
while(current&&y==true)
{
    // Inserts in the end
    if(current->getData()<number->getData()&&current->getNext()==NULL)
    {
        current->setNext(number);
        y=false;
    }
    //Inserts in the beginning
    if(number->getData()<first->getData())
    {
        number->setNext(current);
        current = number;
        y=false;
    }
    // Inserts in the middle
    else if(current->getData()<number->getData()&&current->getNext()->getData()>number->getData())
    {
        number ->setNext(current->getNext());
        current->setNext(number);
        y=false;
    }
    else
    {
        current = current->getNext();
    }
}
current = first;
// Prints my list
while (current)
{
    cout<<current->getData()<<"   ";
    current = current->getNext();
}
cout<<endl;

} }

When I try and run it as it is, I will not get -4 at the start and I will only get my previous list.当我尝试按原样运行它时,一开始我不会得到 -4,我只会得到我以前的列表。 Note that all of my variables have been previously defined this is just the snippet of the part that isn't working.请注意,我之前已经定义了所有变量,这只是不起作用的部分的片段。

You want to have a pointer to the head of the list and then change where it is pointing when you add a new element您希望有一个指向列表头部的指针,然后在添加新元素时更改它指向的位置

Generally, you can achieve this with something similar.通常,您可以使用类似的方法来实现这一点。

class Node{
   public:
   Node(int val)
   {
       this->val = val;
       this->next = nullptr
   }
   int val;
   Node* next;
}

Then you can use it like this.然后你可以像这样使用它。

Node element1(5);
Node element2(10);

Node* head = &element1
//add a new node in front

head->next = head;
head = &element2;

I assume that you node values of your list are sorted.我假设您的列表的节点值已排序。 You need first to set the variable first to number inside the conditional section Insert into begininng so that this variable will point to the node you want to add.您需要首先在条件部分Insert into begininng中将变量first设置为number ,以便该变量指向您要添加的节点。 You should also remove the line current = number .您还应该删除current = number Moreover, your loop does not work with empty lists.此外,您的循环不适用于空列表。 In such case, you have to set the first variable to number too.在这种情况下,您也必须将第first变量设置为number Finally, please note that the variable second defined in the beginning of your code will not point to the second node anymore.最后,请注意代码开头定义的变量second将不再指向第二个节点。

At the time of writing, it looks like you've solved your particular problem.在撰写本文时,您似乎已经解决了您的特定问题。 But I wrote this code and don't want to just delete it.但是我写了这段代码,不想就删除它。 It does demonstrate how simple an insert function can be for a sorted linked list.它确实演示了插入函数对于排序链表是多么简单。 Note the lack of an over-arching while loop, and how simplistic the one loop is.请注意缺少全面的 while 循环,以及 one 循环是多么简单。

My list is doubly linked, which I prefer since it makes mid-list erasing so much easier.我的列表是双重链接的,我更喜欢它,因为它使删除中间列表变得更加容易。 I didn't write an erase function because it doesn't pertain to your question.我没有编写擦除功能,因为它与您的问题无关。 There's actually a lot I didn't write that really should be included (big exclusions include a copy constructor and assignment operator overload; Rule of 3 is in play).实际上有很多我没有写的应该包括在内(大的排除包括复制构造函数和赋值运算符重载;3 规则在起作用)。

I wrote a print function as a class member to simplify things, but the reality is you should write an iterator class instead.我写了一个打印函数作为类成员来简化事情,但实际情况是你应该写一个迭代器类来代替。 My personal preference would have been to write a fully fleshed linked list, and then composite it into a sorted linked list.我个人的偏好是编写一个完整的链表,然后将其组合成一个排序的链表。

#include <iostream>
#include <random>

class Dlist {
public:
    Dlist() = default;
    ~Dlist();
    void insert(int data);
    void print() const;

private:
    struct Node {
        Node(int key)
            : key_m(key)
        {
        }
        int key_m = 0;
        Node* prev_m = nullptr;
        Node* next_m = nullptr;
    };

    Node* head_m = nullptr;
    Node* tail_m = nullptr;
};

Dlist::~Dlist()
{
    while (head_m) {
        Node* tmp = head_m;
        head_m = head_m->next_m;
        delete tmp;
    }
    head_m = nullptr;
    tail_m = nullptr;
}

void Dlist::insert(int data)
{
    Node* tmp = new Node(data);
    if (!head_m) {
        head_m = tmp;
        tail_m = head_m;
        return;
    }

    if (data < head_m->key_m) { // New node goes before head
        tmp->next_m = head_m;
        head_m->prev_m = tmp;
        head_m = tmp;
    } else if (data > tail_m->key_m) { // New node goes after tail
        tail_m->next_m = tmp;
        tmp->prev_m = tail_m;
        tail_m = tmp;
    } else { // New node goes somewhere in the middle
        Node* insertingBefore = head_m->next_m;
        while (tmp->key_m > insertingBefore->key_m && insertingBefore != tail_m) {
            insertingBefore = insertingBefore->next_m;
        }
        tmp->next_m = insertingBefore;
        tmp->prev_m = insertingBefore->prev_m;
        insertingBefore->prev_m->next_m = tmp;
        insertingBefore->prev_m = tmp;
    }
}

void Dlist::print() const
{
    if (!head_m) {
        return;
    }

    Node* i = head_m;
    while (i) {
        std::cout << i->key_m << ' ';
        i = i->next_m;
    }
}
int main()
{
    Dlist list;
    std::random_device rd;
    std::mt19937 engine(rd());
    std::uniform_int_distribution<int> dist(1, 100);

    for (int i = 0; i < 10; ++i) {
        int tmp = dist(engine);
        std::cout << "Inserting " << tmp << ".\n";
        list.insert(tmp);
    }

    list.print();
    std::cout << '\n';
}

Your class function sounds like it is generating data to insert into the list.您的类函数听起来像是在生成要插入到列表中的数据。 That sounds horrible.这听起来很可怕。 A list is a list, and nothing more.列表就是列表,仅此而已。 That data generation should be in a non-class function, which should then call the insert() function of your list.该数据生成应在非类函数中,然后应调用列表的insert()函数。 A class should represent one thing well, and a function should do one thing well.一个类应该很好地代表一件事,一个函数应该做好一件事。 These are foundational principles.这些是基本原则。

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

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