【问题标题】:finding min, max, and average of linked list查找链表的最小值、最大值和平均值
【发布时间】:2020-04-11 22:14:46
【问题描述】:

我有一个程序,我应该在其中使用链表构建函数来执行各种任务。目前,我在查找链表的最小值和最大值时遇到问题。由于某种原因,当两者都是最高的哪个数字是 9 时,当我试图找到列表的平均值时,它仍然是 9。

此外,我认为它干扰了我的 pop 功能,该功能应该删除最后一个项目,但是当我尝试按部分工作时,一个部分将无法工作,直到上一个部分因任何原因运行。

这是我的标题

#include <iostream>

using std::cout;
using std::endl;

#ifndef LINKEDLIST_H
#define LINKEDLIST_H


class LinkedList
{
    private:

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

        int size;
        Node *head, *tail;

    public:
        LinkedList();
        ~LinkedList();

        // misc
        void display();

        // sorting and searching
        // reverse --> sorting in descending
        int linearSearch(int key);
        void sort();
        void reverse();

        // various math
        int min();
        int max();
        int mean();

        // adding
        void append(int num);
        void insert(int num, int pos);

        // removing
        void pop();
        void remove(int pos);
};

#endif // LINKEDLIST_H

头文件的源文件

#include "linkedlist.h"



LinkedList::LinkedList()
{
    head = nullptr;
    tail = nullptr;
    size = 0;
}

LinkedList::~LinkedList()
{
    if(head != nullptr)
    {
        Node *temp;

        while(head != nullptr)
        {
            temp = head->next;

            // deletes head
            delete head;

            // goes to next element
            head = temp;
        }
    }
}

void LinkedList::display()
{
    Node *temp = head;

    for(int i = 0; i < size; i++)
    {
        cout << temp->data << "\t";

        temp = temp->next;
    }

    cout << endl;
}

void LinkedList::append(int num)
{
    // list is empty
    if(head == nullptr)
    {
        head = new Node;

        head->data = num;
        head->next = nullptr;

        // sets tail to head
        tail = head;
    }

    else
    {
        // creates new node
        Node *temp = new Node;

        // sets new node data
        temp->data = num;
        temp->next = nullptr;

        // sets previous tail link to new node
        tail->next = temp;

        // sets this node to new tail
        tail = temp;
    }

    // increments size
    size++;
}

void LinkedList::pop()
{
    if(size > 1)
    {
        Node *temp = head;

        // loops to node before tail
        while(temp->next->next != nullptr)
        {
            temp = temp->next;
        }

        // deletes tail
        delete tail;

        // sets new tail
        tail = temp;
        tail->next = nullptr;
    }

    // if there's only one item
    else if(size == 1)
    {
        Node *temp = tail;

        // head and tail are now null
        head = nullptr;
        tail = nullptr;

        // deletes node
        delete temp;
    }

    size--;
}



void LinkedList::insert(int num, int pos)
{
    if(pos ==0)
    {

        Node *temp=new Node;
        temp->data=num;
        temp->next=head;
        head=temp;
    }

    if(pos>1)
    {
        Node *pre=new Node;
        Node *cur=new Node;
        Node *temp=new Node;
        cur=head;
        for(int i=1;i<pos+1;i++)
        {
          pre=cur;
          cur=cur->next;
        }
        temp->data=num;
        pre->next=temp;
        temp->next=cur;
    }



    size++;

}

int LinkedList::linearSearch(int key)
{
    Node *temp = head;
    for(int i = 0; i < size; i++)
    {
        if(temp->data == key)
        {
            return i;
        }

        temp = temp->next;
    }

    return -1;
}

int LinkedList::max()
{
    int max = INT_MIN;
    for(int i = 0; i < size; i++)
    {
        while (head != NULL)
        {
                if (head->data < max)
                    max = head->data;
                head = head->next;

        }

     }

}

int LinkedList::min()
{
    int min = INT_MAX;
    for(int i = 0; i < size; i++)
    {
        while (head != NULL)
        {
                if (head->data < min)
                    min = head->data;
                head = head->next;

        }

     }
}

void LinkedList::reverse()
{
    Node* temp = head;

    // Traverse the List
    while (temp) {
        Node* min = temp;
        Node* r = temp->next;

        // Traverse the unsorted sublist
        while (r)
        {
            if (min->data < r->data)
                min = r;

            r = r->next;
        }

        // Swap Data
        int x = temp->data;
        temp->data = min->data;
        min->data = x;
        temp = temp->next;
    }
}

void LinkedList::remove(int pos)
{
    Node *temp = head;

    if(pos ==0)
    {

        head = temp->next;
        free(temp);
    }

    if(pos>1)
    {
       for(int i=0; temp!=NULL && i<pos-1;i++)
       {
           temp=temp->next;
       }

       temp->next = temp->next->next;
       free(temp->next);
       temp->next = temp->next;
    }



    size--;
}

int LinkedList::mean()
{


        int sum = 0;
        float avg = 0.0;

         Node *temp = head; 
        while (head != NULL)
        {

            sum += temp->data;
            temp = temp->next;
        }

        // calculate average
        avg = (double)sum / size;
}

void LinkedList::sort()
{
    Node* temp = head;

    // Traverse the List
    while (temp) {
        Node* min = temp;
        Node* r = temp->next;

        // Traverse the unsorted sublist
        while (r) {
            if (min->data > r->data)
                min = r;

            r = r->next;
        }

        // Swap Data
        int x = temp->data;
        temp->data = min->data;
        min->data = x;
        temp = temp->next;
    }
}

还有主要的

#include <iostream>

#include "linkedlist.h"

using namespace std;

int main()
{
    LinkedList nums;

    // adding through append
    nums.append(8);
    nums.append(6);
    nums.append(7);
    nums.append(8);
    nums.append(0);
    nums.append(9);

    // displays list
    cout << "List after append: " << endl;
    nums.display();
    cout << endl;

    // adding through insert
    nums.insert(1, 0);
    nums.insert(5, 4);
    nums.insert(3, 8);


    // displays list
    cout << "List after inserting: " << endl;
    nums.display();
    cout << endl;

    // testing searching
    cout << "Testing linear search:" << endl;

    int pres = nums.linearSearch(7);

    if(pres < 0)
    {
        cout << "7 is not present in the list." << endl;
    }

    else
    {
        cout << "7 can be found at location " << pres << endl;
    }

    pres = nums.linearSearch(5);

    if(pres < 0)
    {
        cout << "5 is not present in the list." << endl;
    }

    else
    {
        cout << "5 can be found at location " << pres << endl;
    }

    cout << endl;

    // does math
    cout << "Minimum, maximum, and average before removing any items: " << endl;
    cout << "Min: " << nums.min() << endl;
    cout << "Max: " << nums.max() << endl;
    cout << "Mean: " << nums.mean() << endl << endl;

    // displays items reversed
    cout << "Items reversed: " << endl;
    nums.reverse();
    nums.display();
    cout << endl;

   // removing through pop
    nums.pop();
    nums.pop();

    // displays list
    cout << "List after popping: " << endl;
    nums.display();
    cout << endl;

    // removing through remove
    nums.remove(0);
    nums.remove(2);
    nums.remove(4);

    // displays list
    cout << "List after removing: " << endl;
    nums.display();
    cout << endl;

   // displays items sorted
    cout << "Items sorted: " << endl;
    nums.sort();
    nums.display();
    cout << endl;

    // does math
    cout << "Minimum, maximum, and average after removing items: " << endl;
    cout << "Min: " << nums.min() << endl;
    cout << "Max: " << nums.max() << endl;
    cout << "Mean: " << nums.mean() << endl << endl;

    // testing searching
    cout << "Testing linear search:" << endl;

    pres = nums.linearSearch(7);

    if(pres < 0)
    {
        cout << "7 is not present in the list." << endl;
    }

    else
    {
        cout << "7 can be found at location " << pres << endl;
    }

    pres = nums.linearSearch(5);

    if(pres < 0)
    {
        cout << "5 is not present in the list." << endl;
    }

    else
    {
        cout << "5 can be found at location " << pres << endl;
    }

    return 0;
}

我真正苦苦挣扎的唯一部分是最大值、最小值和平均值,以及让我的 pop 函数真正启动。我知道 pop 函数的编写是正确的,但是自从我做了 max 和 min 之后,它现在就不能工作了。

【问题讨论】:

  • 您的最小值和最大值都有 if (head-&gt;data &lt; max)。你也没有任何回报。
  • 如果您的编译器没有为mean 的定义提供警告,请调高警告级别。
  • @maciek97x 你什么意思?我在 min 函数中将它设置为小于 min。
  • @aschepler 它没有给我警告
  • @x-reaper 在你拥有的最大函数中if (head-&gt;data &lt; max)

标签: c++ linked-list max min


【解决方案1】:

我在代码中发现了几个错误,对此我有几点意见:

  1. 您应该使用空格,并且更加一致。有的地方间距不够,有的地方空行太多!
  2. 如果你有insertappendpopremove这样的两个函数,它们应该互相使用,意思是,append只是insert(0)(注意我在代码)。
  3. 您正在使用没有意义的双循环(这不是错误,而是错误!)。
  4. 在函数max 中,您进行了错误的比较,询问max 是否大于当前值...
  5. 您永远不会从minmax 返回值,这至少应该在编译过程中产生警告!
  6. 您正在创建空节点,然后您只是在它们的指针中放置了不同的值,这意味着这个新内存仍然被分配(因为没有delete),但是没有办法再访问这些(这是内存泄漏)。
  7. 最大的错误 - 当你在 minmax 函数中循环时,你会改变 head 列表中的一个主要错误(这就是为什么您在使用此函数 之后遇到错误的原因)。解决方案是 C++ 中的一个简单但重要的课程 - Const Correctness

什么是 const 正确性,为什么它很重要?

如果您有一个不会改变对象的状态的函数,则应将其声明为const。这是我们告诉编译器(和其他程序员)它不能改变我们对象的状态的方式。例如,minmaxaverage 是经典的 const 函数 - 它们只是进行不更改列表的计算,然后返回。如果你在声明中写了const,编译就会失败,因为你实际上改变了列表(改变了头部),虽然你不应该!

此外,当将对象接收到函数中时,只要有可能,您应该使const T&amp; 其中T 是一个类型。他们将强制您只使用这种类型的 const 函数。

另外,我建议编译(至少在 g++ 上)带有标志 -Wpedantic -Werror'. The first adds some warnings about ISO C++ standards and the second makes all warnings into errors (and thus, yourmin,maxandmean 不应该编译,因为它们不返回值)。

代码如下:

class LinkedList
{
    private:

        struct Node
        {
            int data;
            Node *next;

            Node(int data_, Node* next_ = nullptr) :
                data(data_),
                next(next_)
            {
            }
        };

        int size;
        Node *head, *tail;

    public:
        LinkedList();
        ~LinkedList();

        void clear();

        // various math
        int min() const;
        int max() const;
        int average() const;

        // adding
        void append(int data);
        void insert(int data, int pos);

        // removing
        void pop();
        void remove(int pos);
};

LinkedList::LinkedList()
{
    head = nullptr;
    tail = nullptr;
    size = 0;
}

LinkedList::~LinkedList()
{
    clear();
}

void LinkedList::clear()
{
    if (head != nullptr)
    {
        Node *temp;

        while(head != nullptr)
        {
            temp = head->next;

            delete head;

            head = temp;
        }
    }

    head = nullptr;
    tail = nullptr;

    size = 0;
}

void LinkedList::display()
{
    Node *temp = head;

    for(int i = 0; i < size; i++)
    {
        std::cout << temp->data << "\t";

        temp = temp->next;
    }

    std::cout << std::endl;
}

void LinkedList::insert(int data, int pos)
{
    if (pos == 0)
    {
        Node* prev_head = head;
        head = new Node(data, prev_head);

        if (size == 0)
        {
            tail = head;
        }
    }
    else
    {
        Node *pre=nullptr;
        Node *cur = head;

        for(int i = 0 ; i < pos + 1; ++i)
        {
          pre = cur;
          cur = cur->next;
        }

        Node *temp = new Node(data, cur);
        pre->next = temp;
    }

    ++size;
}

void LinkedList::append(int data)
{
    insert(data, 0);
}

void LinkedList::pop()
{
    if (size == 1)
    {
        Node *temp = tail;

        head = nullptr;
        tail = nullptr;

        delete temp;
    }
    else
    {
        Node *temp = head;

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

        Node* node_to_pop = tail;

        tail = temp;
        tail->next = nullptr;

        delete node_to_pop;
    }  

    --size;
}

int LinkedList::max() const
{
    int max = INT_MIN;
    for (Node* temp = head; temp != nullptr; temp = temp->next)
    {   
        if (temp->data > max)
        {
            max = temp->data;
        }
    }

    return max;
}

int LinkedList::min() const
{
    int min = INT_MAX;
    for(Node* temp = head; temp != nullptr; temp = temp->next)
    {
        if (head->data < min)
        {
            min = temp->data;
        }
     }

     return min;
}

int LinkedList::average() const
{
    int sum = 0;

    for(Node* temp = head; temp != nullptr; temp = temp->next)
    {

        sum += temp->data;
        temp = temp->next;
    }

    return (double)sum / size;
}

【讨论】:

  • mean 不返回值,但 OP 在 cout &lt;&lt; "Mean: " &lt;&lt; nums.mean() &lt;&lt; endl &lt;&lt; endl; 中使用 mean
  • @ThomasSablik 是的,但是声明为int mean(),不返回与声明不一致。
  • 最后一个错误是杀手。 :-) gcc 也因没有注意到没有返回而臭名昭著
  • @pm100 其实编译器已经注意到了,问题是他没有使用-Werror标志。也将其添加到我的答案中。
  • @Juv 等调试好了,就不放代码了。但是在这里,更多的是关于如何编写代码,因此它更不容易出错。像 CR 一样看待它。
猜你喜欢
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
  • 2014-06-11
  • 2017-07-24
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
相关资源
最近更新 更多