Реализация круговых списков и как удалить средний узел в списке - PullRequest
0 голосов
/ 17 декабря 2018
#include <stdio.h>
#include <stdlib.h>

struct cir{

    int info;
    struct cir* next;

};

struct cir* create(int num){

    struct cir* temp;

    temp=(struct cir*)malloc(sizeof(struct cir));

    temp->info=num;
    temp->next=NULL;

    return(temp);
}


struct cir* insertlast(struct cir** head0, struct cir* new1){

    struct cir* temp;

    temp=(*head0);

    if(temp==NULL){

        new1->next=new1;

        return(new1);
    }

    else{

        while(temp->next !=(* head0) ){

            temp=temp->next;

        temp->next=new1;
        new1->next=(*head0) ; }

    }

    return(*head0);

}

void vizualize(struct cir* head0){

    struct cir* temp;

    temp=head0;

    printf("Lista:");

    while(head0->next != temp ){

        printf("[%d]-->", head0->info);
        head0 =head0 ->next;

    }

    printf("%d(testa)", head0->info);



}

int main(){

    struct cir* head;
    int i,n1,n2;
    struct cir* new1;


    printf("Insert the number of elements you want to put in  the list:\n\n");
    scanf("%d", &n1);

    for(i=0;i<n1;i++){

        printf("Insert the element you want to insert in the list:\n\n");
        scanf("%d", &n2);

        new1=create(n2);

        insertlast(&head,new1);
    }

    vizualize(head);

}

Привет!Я написал этот код для реализации списка CIRCULAR, но когда я пытаюсь запустить код, он вылетает.

Я создал функцию struct cir* create(int num), чтобы создать отдельный элемент для вставки в круговой список.вызывая функцию struct cir* insertlast(struct cir** head0, struct cir* new1 для атаки элемента на круговой список.

Кроме того, что касается двунаправленных списков:

 if(temp->next!=NULL){

        (temp->next)->prev=NULL;

что означает

(temp->next)->prev=NULL;

do?

Последний вопрос, есть ли кто-нибудь, кто может написать здесь код для удаления элемента в середине однонаправленного списка?Я пытался любым способом, но каждый раз, когда я пытаюсь удалить один элемент, программа падает или список визуализируется одинаково!

Большое спасибо!

ps.В чем разницамежду удалением и извлечением элемента из списка?

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Проблема в функции insertlast.Первая проблема - когда вставка выполняется, а список пуст (вы также забыли инициализировать заголовок в основном как NULL), потому что вы просто устанавливаете указатель «следующий» для нового элемента, не делая его новым заголовкомсписок.
Затем при прокрутке списка тем способом, который вы написали в цикле while, вы выполняете цикл до тех пор, пока не найдете точку вставки, а затем выходите, фактически ничего не делая.

Здесь это исправленорабочая версия функции:

struct cir* insertlast(struct cir** head0, struct cir* new1) {
    struct cir* temp;
    temp = (*head0);
    if(temp == NULL) {
        new1->next = new1;
        *head0 = new1;
        return(*head0);
    }
    else {
        while(temp->next != (*head0)) {
            temp = temp->next;
        }

        temp->next = new1;
        new1->next = (*head0);

    }
    return(*head0);
}

Что касается значения

(temp->next)->prev=NULL;

в двунаправленном списке, он устанавливает узел, на который указывает "temp", значение NULL, поскольку из "temp"Вы переходите к следующему элементу, затем снова к предыдущему, который совпадает с началом (при условии, что «next» и «prev» установлены правильно).

Наконец, чтобы удалить элемент изоднонаправленный список, вы должны остановиться на элементе прямо перед тем, как захотеть удалить и переставить указатели:

while(temp->next->info != target){
      temp=temp->next
}
struct circ* node_to_delete = temp->next;
temp->next = node_to_delete->next;
free(node_to_delete);

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

0 голосов
/ 17 декабря 2018

Это будет работать:

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

struct cir {
    int info;
    struct cir* next;
};

struct cir* create(int num) {

    struct cir* temp;

    temp = (struct cir*)malloc(sizeof(struct cir));

    temp->info = num;
    temp->next = NULL;

    return(temp);
}


struct cir* insertlast(struct cir* head0, struct cir* new1) {

    struct cir* last;

    if ( head0 == NULL ) {

        new1->next = new1;

        return new1;
    }
    else {
        last = head0;
        while (last->next != head0) {
            last = last->next;
        }

        last->next = new1;
        new1->next = head0;

        return head0;
    }
}

void vizualize(struct cir* head0) {

    struct cir* temp;

    if (head0) {
        temp = head0;

        printf("List:");

        do {
            printf("[%d]-->", temp->info);
            temp = temp->next;
        } while ( temp != head0 );
    }
}

int main() {

    struct cir* head;
    int i, n1, n2;
    struct cir* new1;

    head = 0;

    printf("Insert the number of elements you want to put in  the list:\n\n");
    scanf("%d", &n1);

    for (i = 0; i < n1; i++) {

        printf("Insert the element you want to insert in the list:\n\n");
        scanf("%d", &n2);

        new1 = create(n2);

        head = insertlast(head, new1);
    }

    vizualize(head);
}

Заметьте, я тестировал его на компиляторе c ++, а не на c.

, в чем разница между удалением и извлечением элементаиз списка?

Извлечь означает, что вы удаляете элемент из списка и можете использовать его.Удалить означает, что вы не только удаляете из списка, но и освобождаете память.

...