【问题标题】:Singly Linked List Infinite Loop单链表无限循环
【发布时间】:2018-04-04 04:09:19
【问题描述】:

自从我开始学习链表已经一周了,我只学习了单链表。所以今天我实现了我在 C++ 中学到的链表,当我尝试运行它时,代码进入了一些随机数的无限循环。我尝试调试代码,但我找不到代码有什么问题。代码如下。感谢您的帮助。谢谢

#include <iostream>
using namespace std;

struct node{
int data;
node * next;
};

class singly{
private:
node * head,*tail;
public:
singly(){
    head=NULL;
    tail=NULL;
}

void createNode(int value){
    node * temp = new node;
    temp->data=value;
    temp->next=NULL;
    if(head==NULL){
        head=temp;
        tail=temp;
        temp=NULL;
    }

    else{
        tail->next=temp;
        tail=temp;
    }
}

void display(){
    node * temp = new node;
    head=temp;

    while(temp!=NULL){
        cout << temp->data << "\t" << endl;
        temp->next=temp;
    }
}

void insert_end(int value){
    node*newnode = new node;
    node*temp = new node;
    newnode->data=value;
    newnode->next=NULL;
    temp=head;

    while(temp->next!=NULL){
        temp = temp->next;
    }
    temp->next=newnode;
}

void delete_node(){
    node*current = new node;
    node*previous = new node;
    current = head;
    while(current->next!=NULL){
        previous=current;
        current=current->next;
    }

    tail=previous;
    previous->next=NULL;
    delete current;
}
};

int main(){

singly lists;
lists.createNode(32);
lists.createNode(654);
lists.createNode(34);
lists.createNode(234);

cout<<"\n--------------------------------------------------\n";
cout<<"---------------Displaying All nodes---------------";
cout<<"\n--------------------------------------------------\n";
lists.display();
cout<<"\n--------------------------------------------------\n";
cout<<"-----------------Inserting At End-----------------";
cout<<"\n--------------------------------------------------\n";
lists.createNode(55);
lists.display();
cout<<"\n--------------------------------------------------\n";
cout<<"-----------------Deleing At End-------------------";
cout<<"\n--------------------------------------------------\n";
lists.delete_node();
lists.display();
}

【问题讨论】:

  • 什么时候进入死循环?您不能指望我们为您调试整个代码。
  • 我建议你对new关键字的作用做一些研究,因为从这段代码来看你并不真正了解它
  • displaydelete_node 都坏了。您应该只在将节点添加到列表的函数中写入 new。不要使用new 创建指针——如果您想要一个与head 具有相同值的指针,您只需要node* temp = head;
  • 顺便说一句,insert_end 对于带有尾指针的列表来说是不必要的复杂,此外,在末尾插入是 createNode 所做的。
  • @molbdnilo 非常感谢您的帮助

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


【解决方案1】:

成员函数display 没有意义。 它用未初始化的新创建的temp 覆盖数据成员head

    node * temp = new node;
    head=temp;

所以函数调用未定义的行为。

函数看起来像

void display()
{
    for ( node * temp = head; temp != nullptr; temp = temp->next )
    {
        cout << temp->data << "\t";
    }
}

或者最好如下定义

std::ostream & display( std::ostream &os = std::cout )
{
    for ( node * temp = head; temp != nullptr; temp = temp->next )
    {
        os << temp->data << "\t";
    }

    return os;
}

数据成员insert_end 也是错误的。没有考虑到headtail可以等于nullptr,不会改变它们。

函数可以通过以下方式定义

void insert_end(int value)
{
    node *newnode = new node { value, nullptr };

    if ( tail == nullptr )
    {
        head = tail = newnode;
    }
    else
    {
        tail = tail->next = newnode;
    }
}

成员函数delete_node 首先对单链表没有意义,然后又是错误的并调用未定义的行为。该函数应该从列表中删除第一个节点。

如果你想从列表中删除最后一个节点,那么函数看起来像

void delete_node()
{
    if ( head != nullptr )
    {
        tail = nullptr;
        node *current = head;

        while ( current->next )
        {
            tail = current;
            current = current->next;
        }

        if ( tail == nullptr )
        {
            head = tail;
        }
        else
        {
            tail->next = nullptr;
        }

        delete current;
    }
}

【讨论】:

  • 谢谢兄弟,我还是个菜鸟,所以还在学习阶段。但这对我有很大帮助并解决了我的问题。
【解决方案2】:
  1. 对于初学者来说,display() 是错误的。您希望更新为temp = temp-&gt;next;,也可以初始化为node * temp = head,因此不需要第二行。

  2. 您的delete_node() 可以重写为:

    if (head->next == NULL) // handles the case that it consists of 1 element
    {
        delete head;
        head = NULL;
    }
    else
    {
        node *nextToEnd = head;
        node *end = head->next;
        while (end->next != NULL)
        {
            nextToEnd = end;
            end = end->next;
        }
        delete end;
        nextToEnd->next = NULL;
    }
    
  3. 如 cmets 中所述,查看 new keyword 的使用情况

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-05
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    相关资源
    最近更新 更多