【问题标题】:Delete smallest node in a linkedlist删除链表中的最小节点
【发布时间】:2021-12-16 17:54:58
【问题描述】:

我有一个任务是删除链表中的最小节点。我为此编写了函数minelement,但它不会删除最小的节点。它只是删除了所有节点......为什么会这样?

我的代码:

#include <iostream>
#include <string>
using namespace std;

class linkedlist {

private:
    struct node {
        int item;
        node* next;
    };
    node* first;
    node* last;
    int count;

public:
    linkedlist()
    {
        first = last = NULL;
        count = 0;
    }

    bool isempty()
    {
        return (first == NULL);
    }

    void insertnode(int value) {
        node* newNode = new node;
        newNode->item = value;
        if (count == 0)
        {
            first = last = newNode;
            newNode->next = NULL;
        }
        else
        {
            newNode->next = first;
            first = newNode;
        }
        count++;
    }

    void insertfromLast(int value)
    {
        node* newNODE = new node;
        newNODE->item = value;
        if (count == 0)
        {
            first = last = newNODE;
            newNODE->next = NULL;
        }
        else
        {
            last->next = newNODE;
            newNODE->next = NULL;
            last = newNODE;
        }
    }

    void removefirst()
    {
        node* curr = first;
        if (count == 0)
        {
            cout << "empty list cannot be deleted" << endl;

        }
        else if (count == 1)
        {
            delete first;
            last = first = NULL;
            count--;
        }
        else
        {
            first = first->next;
            delete curr;
            count--;
        }       
    }

    void removelast()
    {
        if (count == 0)
        {
            cout << "empty list cannot be deleted" << endl;
        }
        else if (count == 1)
        {
            delete first;
            last = first = NULL;
            count--;
        }
        else
        {
            node* curr = first->next;
            node* prev = first;
            while (curr != last)
            {
                prev = curr;
                curr = curr->next;
            }
            delete curr;
            prev->next = NULL;
            last = prev;
            count--;
        }
    }

    void position(int pos)
    {
        node* curr = first;
        if (count == 0)
        {
            cout << "Element's positon cannot be found" << endl;
        }
        else
        {
            if (pos > count||pos<0)
            {
                cout << "Out of range so we can't return info of kth element" << endl;
            }
            else
            {
                for (int i = 0; i < pos; i++)
                {
                    curr = curr->next;
                }
                cout << curr->item;
            }
            count++;
        }
    }

    void remove_existed_element(int element)
    {
        if (count == 0)
        {
            cout << "Empty list cannot be deleted" << endl;
        }
        node* curr = first->next;
        node* prev = first;
        if (first->item == element)
        {
            curr = first;
            first = first->next;
            delete curr;
            count--;
        }
        else
        {
            while (curr != NULL)
            {
                if (curr->item == element)
                {
                    break;
                }
                prev = curr;
                curr = curr->next;

            }
            if (curr == NULL)
            {
                cout << "Element cannot be found to delete" << endl;
            }
            else
            {
                prev->next = curr->next;
                delete curr;
                count--;
            }
        }
    }

    void maxelement()
    {
        int max = first->item;
        node* curr = first->next;
        while (curr != NULL)
        {
            if (curr->item > max)   
            {
                max = curr->item;
            }
            curr = curr->next;
        }
        cout << "MAX ELEMENT IS " << max << endl;
        count++;
    }

    void minelement()
    {
        int min = first->item;
        node* curr = first->next;
        node* prev = first;
        if (isempty())
        {
            cout << "Empty linked list cannot be deleted" << endl;      
        }
        else if (count == 1)
        {
            delete first;
            count--;
        }
        else
        {
            while (curr != NULL)
            {
                if (min > curr->item)
                {
                    min = curr->item;
                }
                curr = curr->next;
            }
            while (curr->item != min) //10 6 5 2//
            {
                prev = curr;
                curr=curr->next;
            }
            prev->next = curr->next;// prev->next=NULL;
            delete (curr);
            count--;
        }
    }

    void print()
    {
        node* curr = first;
        while (curr != NULL)
        {
            cout << curr->item << " ";
            curr = curr->next;
        }
        cout << endl;
    }
};

int main()
{
    linkedlist l;
    l.insertnode(2);
    l.insertnode(5);
    l.insertnode(6);
    l.insertnode(10);
    l.minelement();
    l.print();
}

【问题讨论】:

  • 请在此处添加代码,而不是在某些临时源上

标签: data-structures visual-c++ linked-list singly-linked-list


【解决方案1】:

一些问题:

  • 确定NULL时,

    curr被取消引用:

    while (curr != NULL)
    {
        if (min > curr->item)
        {
            min = curr->item;
        }
        curr = curr->next;
    }
    while (curr->item != min) // <-- curr will be NULL!!!
    
  • 函数以取消引用first 开始,这是不安全的:当列表为空时,这将是无效引用。所以首先要做的就是检查列表是否为空。

  • count == 1 时,first 成员未设置为 NULL,...等。但是既然你已经在其他地方有了这个逻辑,那就打电话给removefirst()

遗憾的是,您有 2 个循环:一个用于查找最小值,另一个用于查找该最小值之前的节点。您应该在一个循环中完成这两项操作。

这是更新后的功能:

    void minelement()
    {
        if (isempty()) // Check this first!
        {
            cout << "Empty linked list cannot be deleted" << endl;      
        }
        else if (count == 1)
        {
            removefirst(); // Use your method
        }
        else
        {
            // Only access first members when it is safe:
            int min = first->item;
            node* beforemin = NULL;
            node* curr = first->next;
            node* prev = first;
            while (curr != NULL)
            {
                if (min > curr->item)
                {
                    min = curr->item;
                    // Remember where you found it
                    beforemin = prev;
                }
                prev = curr; // keep updated
                curr = curr->next;
            }
            if (beforemin == NULL) {
                removefirst();
            } else if (beforemin->next == NULL) {
                removelast();
            } else {
                curr = beforemin->next;
                beforemin->next = curr->next;
                delete (curr);
                count--;
            }
        }
    }

与您的问题无关,但您显然还应该更新 maxelement 函数。 position 函数也有一些问题,比如:

  • count++; 不应出现在那里。
  • pos &gt; count 应该是 pos &gt;= count,因为你似乎使用位置 0 作为头节点,所以最后一个节点的位置是 count-1

最后,尽量避免代码重复。你delete和更新count的地方太多了。尝试将这些通用代码集中在一个方法中,并在需要的地方调用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-11
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多