Сегодня я пытался сделать программу, которая вводила бы 15 случайных значений (от 100 до 120) в связанный список. Эта часть работает как шарм. Затем я нашел максимальное и минимальное значения из этого списка и нашел среднее.

Я хочу переместить все значения выше среднего в конец этого списка , который я пытался реализовать с помощью функции prebaci. Функция unos помещает все элементы в список, а функция unosK помещает все элементы в конец списка. Программа заходит в бесконечный цикл, и я не знаю почему. Можете ли вы помочь мне переместить все значения выше среднего (107) в конец списка? Мой КОД:

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

typedef struct lista* Pozicija;
struct lista {
    int el;
    Pozicija next;
};

void unos(Pozicija P, int el);//input front
void ispis(Pozicija P);//print 
int mini(Pozicija P);//find min
int maxi(Pozicija P);//find max
void prebaci(Pozicija P,int x);//function for transfering at the end
void unosK(Pozicija P,int x);//input end

int main() {
    srand(time(0));
    struct lista L;
    L.next = NULL;
    int min,max, i,j;
    int prvi[21], drugi[15];
    int avg;

    
    for (i = 0;i < 21;i++) {
        prvi[i] = i + 100;
        printf("%d ", prvi[i]);
    }
    for (i = 0;i < 15;i++) {
        int temp = prvi[i];
        int random = rand() % 15;

        prvi[i] = prvi[random];
        prvi[random] = temp;
    }
    printf("\n\n");
    for (i = 0;i < 15;i++) {
        //printf("%d ",prvi[i]);
        unos(&L, prvi[i]);
    }

    printf("Ispis\n");
    ispis(L.next);

    printf("\n\n");
    min = mini(L.next);
    printf("Minqi:%d\n", min);

    printf("\n\n");
    max = maxi(L.next);
    printf("Miaxi:%d\n", max);

    printf("\n\n");
    avg = (min + max) / 2;
    printf("avg:%d\n", avg);

    printf("\n\n");
    printf("Prebacaj:\n");
    prebaci(&L, avg);
    ispis(L.next);

}
void unos(Pozicija P, int el) {
    Pozicija q;
    q = (Pozicija)malloc(sizeof(struct lista));

    q->el = el;
    q->next = P->next;
    P->next = q;
}
void ispis(Pozicija P) {
    while (P != NULL) {
        printf("%d ", P->el);
        P = P->next;
    }
}
int mini(Pozicija P) {
    int min;
    min = INT_MAX;

    while (P != NULL) {
        if (min > P->el) {
            min = P->el;
        }
        P = P->next;
    }
    return min;
}
int maxi(Pozicija P) {
    int max;
    max = INT_MIN;

    while (P != NULL) {
        if (max< P->el) {
            max = P->el;
        }
        P = P->next;
    }
    return max;
}
void prebaci(Pozicija P,int x) {
    P = P->next;
    Pozicija t;
    t = P;
    while (t != NULL) {
        if (t->el > x)
        {
            unosK(P, t->el);
            t = t->next;
        }
        else if (t->el <= x) {
            unos(P, t->el);
            t = t->next;
        }
        
    }

}
void unosK(Pozicija P,int x) {
    Pozicija q=NULL;
    q = (Pozicija)malloc(sizeof(struct lista));
    q->el = x;

    while (P->next != NULL)
            P = P->next;

    
    q->next = P->next;
    P->next = q;

}
0
Jack Jones 10 Фев 2021 в 20:06

1 ответ

Лучший ответ

Вот работающая замена исходной функции prebaci. Он по-прежнему имеет фиктивный узел в начале списка, но не выделяет никаких новых элементов.

Вместо того, чтобы вызывать unos и unosK, которые выделяют новые элементы, он манипулирует указателями в исходном списке, чтобы переместить элементы, превышающие среднее значение, в конец списка.

Сначала он перемещает элементы, превышающие средние, из исходного списка в новый, изначально пустой список (q), а затем связывает последний элемент исходного списка с первым элементом нового списка, так что все большие чем средние элементы теперь находятся в конце исходного списка.

Новый список (q) был реализован как указатель вместо фиктивного узла.

Функция использует указатели на указатели (pp и pq) для управления ссылками в исходном списке и новом списке.

void prebaci(Pozicija P,int x) {
    Pozicija *pp = &P->next; /* pointer to link in original list */
    Pozicija q = NULL; /* new list for elements greater than average */
    Pozicija *pq = &q; /* pointer to end link of new list */
    while (*pp != NULL) {
        if ((*pp)->el > x) {
            /* move element from original list to end of new list */
            *pq = *pp;  /* end of new list points to moved element */
            *pp = (*pp)->next; /* remove element from original list */
            pq = &(*pq)->next; /* update pointer to end link of new list */
        }
        else {
            /* do not move this element */
            pp = &(*pp)->next; /* advance to next link in original list */
        }
    }
    *pq = NULL; /* terminate the new list */
    *pp = q; /* append the new list to the end of the original list */
}
1
Ian Abbott 10 Фев 2021 в 18:46