Связанный список с несколькими элементами и поиск самого большого - PullRequest
0 голосов
/ 19 октября 2019

Когда я создавал связанный список для репликации менеджера расходов, я застрял с поиском дня с наибольшими расходами. Мне каким-то образом удалось найти максимальное значение total через обход, но я не смог распечатать day, связанный с ним. Пожалуйста, помогите.

Код моей структуры:

struct node{
int day;
int movies;
int groceries;
int travel;
int total;
struct node* left;
struct node* right;
};
void find_max()
{
    struct node *new1 = start;
    int max, c;
    if(start == NULL) {
        printf("List is empty\n");
        return;
    }
    else {
        max = start->total;
        while(new1 != NULL) {
            if(new1->total > max)
            {
                max = new1->total;
            }
            new1 = new1->right;
        }
    }
printf("The maximum spending was: %d",max);
}

Здесь, когда я пытаюсь напечатать new1->day (я не уверен, как это называется. Это ветвь?), он показывает мне значение мусора или перестает работать.

Как правильно отобразить его?

Редактировать (код):


#include<stdio.h>
#include<stdlib.h>

struct node{
int day;
int movies;
int groceries;
int travel;
int total;
struct node* left;
struct node* right;
};

void maximumNode();

//Main goes here, where I choose the option using switch case. Say the example is case 3

case 3:
        {
            maximumNode();
            break;
        }

//End of main

void maximumNode() {
    struct node *new1 = start;
    struct node *max;

    if(start == NULL) {
        printf("List is empty\n");
        return;
    }

    else {
        max->total = start->total;
        while(new1 != NULL) {
            if(new1->total > max->total)
            {
                max->total = new1->total;
            }
            new1 = new1->right;
        }
    }
printf("The maximum spending was: %d and the day was: %d\n\n",max->total, max->day);
}

Здесь, как только я наберу слово 3 после добавления его в список,программа даже не запускается. (Он запустился, когда я взял max в качестве значения int).

Редактировать 2: Я просто перезапустил свой код и, по-видимому, допустил ошибки даже во вставке. Прошу прощения за трату времени всех и благодарю всех за поддержку.

Мой код для вставки, на всякий случай:

void Insert(int a, int b, int c, int d)
{
    struct node *temp,*t;
    int total1=b+c+d;
    temp=(struct node*)malloc(sizeof(struct node));
    if(start==NULL)
    {
        start=temp;printf("%d", total1);
        start->day=a;
        start->movies=b;
        start->groceries=c;
        start->travel=d;
        start->total=total1;
        start->left=NULL;
        start->right=NULL;
    }
    else
    {
       temp=start;
        while(temp->right!=NULL)
        {
            temp=temp->right;
        }
        t=(struct node*)malloc(sizeof(struct node));
        start->day=a;
        start->movies=b;
        start->groceries=c;
        start->travel=d;
        start->total=total1;
        t->right=NULL;
        t->left=temp;
        temp->right=t;
    }
    printf("\n\nYour expense has been saved successfully!\n\n");
}

Ответы [ 2 ]

0 голосов
/ 20 октября 2019

После долгих часов долгих обсуждений с @MOehm я пришел к следующему: этот код полностью @ MOehm's , и я внес несколько небольших изменений. (Слава ему)


void maximumNode()
{
    const struct node *node = h;
    const struct node *max = h;

    if (h==NULL)
    {
        printf("\n\nThe expense list is empty!\n\n");
    }
    else
    {
          while (node->next != NULL) {
        if(node->total > max->total) {
            max = node;
        }
        node = node->next;
    }
    if (node->next==NULL)
        {
            if (node->total > max->total)
            {
                max = node;
            }
        }
    printf("Max. total of %d was on day %d.\n",max->total, max->day);
    return;
    }

}

Я даже внес некоторые изменения в код для вставки. Я использовал и изменил вставную часть кода, взятого с этого сайта.

void create()
{
    int data;
    int d,m,g,t;
    int total1=0;
    temp =(struct node *)malloc(1*sizeof(struct node));
    temp->prev = NULL;
    temp->next = NULL;
    printf("\n\nDay: ");
    scanf("%d",&d);
    printf("\n\nEnter the expenses:\n1. Movies: ");
    scanf("%d",&m);
    printf("2. Groceries: ");
    scanf("%d",&g);
    printf("3. Travel: ");
    scanf("%d",&t);
    total1 = m+g+t;
    temp->day=d;
    temp->movies=m;
    temp->groceries=g;
    temp->travel=t;
    temp->total=total1;
}
void insert2()
{
    if (h == NULL)
    {
        create();
        h = temp;
        temp1 = h;
    }
    else
    {
        create();
        temp1->next = temp;
        temp->prev = temp1;
        temp1 = temp;
    }
}

В остальной части кода я не внес никаких изменений.

Редактировать 1: отредактировано в коде, если список пуст, т.е. h==NULL

0 голосов
/ 19 октября 2019

В первой версии кода, который вы разместили, вы просто сохранили максимальное значение в целом числе. Это было бы хорошо, если вы хотели найти значение, но информация о том, какой узел был потерян.

В комментариях я предложил вам сделать max узлом. Вы сделали это, но допустили несколько ошибок:

  • Вы max не инициализированы, что означает, что плохие вещи будут происходить. (C-говорить об этом "неопределенное поведение".) Инициализировать max = start. (Просмотр определения указателя без инициализации должен поднять красный флаг. Если вы не знаете, что инициализировать, по крайней мере, сделайте это NULL, чтобы вы могли выполнять проверки на NULL позже. Просто написание struct node *max; означает, чтоmax имеет неопределенное значение, которое вы даже не можете проверить!
  • Тогда, когда вы найдете лучший узел, не устанавливайте max->total. Это означает, что вы просто используете первый узелв качестве хранилища для вашего максимума, тем самым изменяя данные списка, которые вам не нужны. Установите новый узел:

    if (new1->total > max->total) max = new1;
    

    (Если вы внимательно прочитаете мой комментарий, это то, что я предложил.)

Давайте реализуем это, а также исправим некоторые семантические проблемы с кодом, см. Примечания ниже:

const struct *node maximumNode()
{
    const struct node *node = start;
    const struct node *max = start;

    while (node != NULL) {
        if(node->total > max->total) {
            max = node;
        }

        node = node->right;
    }

    return max;
}

Примечания:

  • Функция теперь возвращает ссылку на узел с максимальным значением total. Затем вызывающий код может распечатать информацию или использовать узел другими способами, как того пожелает, например:

    const struct node *max = maximumNode();
    
    if (node) {
        printf("Max. total of %d was on day %d.\n",
            node->totel, node->day;
    }
    

    Это чищечем делать печать в самой функции. Это будетТакже позволяет вам использовать ту же функцию в других контекстах, где вам нужно макс. узел.

  • Я сделал указатели узлов const struct node * в ваших функциях. Это означает, что вы не можете изменять содержимое структур. Просто найти максимум означает, что вы просто просматриваете список, но не меняете его. С этим объявлением компилятор жаловался бы на попытку установить max->total, и вы бы увидели вашу ошибку.
  • Вам не нужен первый тест для NULL. Когда start == NULL , then also node == NULL and max == NULL . That doesn't change, because the loop isn't entered and we terurn NULL`, что является лучшим, что мы можем сделать в этом случае.
  • Я изменил имяузла от new1 до node. Это косметическое изменение, но new для меня предполагает, что создается узел, но поскольку мы только проверяем, это имя может вводить в заблуждение. Мелочи считаются. (Также я придирка.)
...