簡體   English   中英

如何刪除鏈表的第一個節點?

[英]How to delete the first node of a linked list?

我想刪除列表的第一個節點(我稱之為“頭”),但 output 給我一個錯誤“未分配指針被釋放”。 你知道問題出在哪里嗎? 如果您不明白某些內容,請原諒意大利語單詞,我可以編輯我的問題。 我認為問題在於void cancellaTriangolo 也許我保存了錯誤的節點,他們沒有保存自己。

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

/* STRUTTURE */
typedef struct punto {
    int x;
    int y;
} PUNTO;

typedef struct triangolo {
    PUNTO v;
    int lato;
} TRIANGOLO;

typedef struct nodo {
    TRIANGOLO t;
    struct nodo *next;
} NODO;

/* STAMPA LISTA */
int perimetro(TRIANGOLO t) {
    return t.lato * 3;
}

void stampaTriangolo(TRIANGOLO t) {
    printf("Il triangolo ha il lato uguale a: %d con un perimetro pari a %d, il vertice in alto ha coordinate (%d,%d)\n",
           t.lato, perimetro(t), t.v.x, t.v.y);
}

void stampaLista(NODO *head) {
    if (head->next == NULL) {
        printf("Lista vuota!\n");
    } else {
        while (head->next != NULL) {
            head = head->next;
            stampaTriangolo(head->t);
        }
    }
}

/* INSERIMENTO */
TRIANGOLO creaTriangolo() {
    TRIANGOLO nuovo;
    printf("Inserisci il lato del nuovo triangolo: ");
    scanf("%d", &nuovo.lato);
    printf("\n");
    printf("Inserisci le coordinate del vertice con y maggiore:\n");
    printf("x: ");
    scanf("%d", &nuovo.v.x);
    printf("\n");
    printf("y: ");
    scanf("%d", &nuovo.v.y);
    printf("\n");
    
    return nuovo;
}

void inserisciPerPerimetro(NODO *head) {

    NODO *nuovo = malloc(sizeof(NODO));
    nuovo->t = creaTriangolo();
    nuovo->next = NULL;

    if (head == NULL) {
        head = nuovo;
    } else {
        if (perimetro(nuovo->t) < perimetro(head->t)) {
            nuovo->next = head;
            head = nuovo;
        } else {
            while (head->next != NULL && perimetro(head->next->t) < perimetro(nuovo->t)) {
                head = head->next;
            }
            nuovo->next = head -> next;
            head->next = nuovo;
        }
    }
    printf("Inserimento effettuato!\n\n");
}

/* CANCELLAZIONE IN TESTA */
void cancellaTriangolo(NODO *head) {
    NODO *primoNodo = NULL;

    /* lista vuota? */
    if (head == NULL) {
        primoNodo = NULL;
        printf("Lista vuota!\n\n");
    } else {
        primoNodo = head;
        head = head->next;
        free(primoNodo);
        printf("Cancellazione effettuata!\n");
    }
}

int main() {
    /* inizializza la lista */
    NODO *head = malloc(sizeof(NODO));
    head->next = NULL;
    
    int risposta = -1;          // per interazione con utente

    while (risposta != 0) {
        /* richiedi un'operazione all'utente */
        printf("Che operazione vuoi svolgere?\n");
        printf("1 -> Inserisci un triangolo nella lista ordinata secondo il perimetro crescente\n");
        printf("2 -> Cancella il triangolo in testa alla lista\n");
        printf("3 -> Visualizza la lista di triangoli\n");
        printf("0 -> Termina il programma\n");
        scanf("%d", &risposta);

        /* gestisci le operazioni dell'utente */
        if (risposta == 1) {
            inserisciPerPerimetro(head);
        } else
        if (risposta == 2) {
            cancellaTriangolo(head);
        } else
        if (risposta == 3) {
            stampaLista(head);
        } else
        if (risposta == 0) {
            printf("Finito!\n\n");
        } else {
            printf("Selezione non valida!\n\n");
        }
    }
}

(很抱歉沒有正確回答問題)

編輯: cancellaTriangolo中參數head的更改將不適用於main中的head ,只需在 function 中執行head = head->next 為了解決這個問題,下面的代碼可能會有所幫助:

void cancellaTriangolo(NODO** head) {
    if (*head) {
        NODO* p = *head;
        *head = (*head)->next;
        free(p);
    }
}

cancellaTriangolo(&head)調用它。

對於插入新節點時的其他問題...如果您發現沒有插入新節點,可能是相同的原因。 使用NODO** head發送指向head的指針,以便訪問和更改函數中的head

  1. 您使用實際上不包含數據的頭部的方法是錯誤的,並且會使您的代碼過於復雜。 根據定義,列表的第一個節點是列表的頭部。 如果頭部是 NULL,則列表為空。
  2. 在C中參數是按值傳遞的,所以如果要修改一個已經傳遞到function中的指針,則需要指針指向指針。 此 SO 問題中解釋了詳細信息: 如何修改已傳遞到 C 中的 function 的指針? .

你基本上想要這個:

這不是整個代碼,而是錯誤的只是 function。


void stampaLista(NODO* head) {
  NODO* current = head;

  if (current == NULL) {
    printf("Lista vuota!\n");
  }
  else {
    while (current != NULL) {
      stampaTriangolo(current->t);
      current = current->next;
    }
  }

  printf("\n");
}

void inserisciPerPerimetro(NODO** head) {

  NODO* nuovo = malloc(sizeof(NODO));
  nuovo->t = creaTriangolo();
  nuovo->next = NULL;

  if (*head == NULL) {
    *head = nuovo;
  }
  else {
    if (perimetro(nuovo->t) < perimetro((*head)->t)) {
      nuovo->next = *head;
      *head = nuovo;
    }
    else {
      while ((*head)->next != NULL && perimetro((*head)->next->t) < perimetro(nuovo->t)) {
        *head = (*head)->next;
      }
      nuovo->next = (*head)->next;
      *head->next = nuovo;    
    }
  }

  printf("Inserimento effettuato!\n\n");
}

void cancellaTriangolo(NODO** head) {
  NODO* primoNodo = NULL;

  /* lista vuota? */
  if (*head == NULL) {
    primoNodo = NULL;
    printf("Lista vuota!\n\n");
  }
  else {
    primoNodo = *head;
    *head = (*head)->next;
    free(primoNodo);
    printf("Cancellazione effettuata!\n");
  }
}

int main() {
  /* inizializza la lista */
  NODO* head = NULL;
  ...
    
    if (risposta == 1) {
      inserisciPerPerimetro(&head);  // use &head
    }
    else if (risposta == 2) {
      cancellaTriangolo(&head);      // use &head
    }
    ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM