CodeBlanks Logo Icon CodeBlanks

Listeden silme

  • C kursu
  • Orta seviye
  • Ders 73/116
  • 5 dk

Bağlı listeden eleman silmeyi öğrenirsin.

Listeden silme

Silme, bir düğümü listeden koparıp belleğini iade etmektir. İki durum vardır: silinen düğüm başsa ya da ortada/sondasa.

Baş silinirken: Node *tmp = head; head = head->next; free(tmp);. Yeni baş, eski başın next'i olur. Ortada silinirken: bir prev imleci silinecek düğümün öncesinde durur; prev->next = cur->next; ile cur atlanır, sonra free(cur);. Önceki düğümün next'ini güncellemek, listedeki bağın kopmamasını sağlar. Silme işlemi O(n) olabilir çünkü value'yu bulmak için gezme gerekir.

list_remove işlevi

Tam bir silme işlevi iki dalı birleştirir. Önce head == NULL kontrolü yapılır; boş listede silinecek şey yoktur. Sonra başın değeri eşleşirse baş silinir.

Aksi halde prev ve cur çifti ile gezilir. cur->data == value bulunduğunda prev->next = cur->next; ile cur atlanır, free(cur); ile bellek iade edilir ve head döndürülür. Değer bulunamazsa liste değişmeden döndürülür. İşlev her zaman yeni başı döndürür; çağıran head = list_remove(head, 20); biçiminde geri almalıdır. Bu desen, başın değişme olasılığı nedeniyle gereklidir.

Uygulama 20'yi sil

Node *list_remove(Node *head, int value) yaz. head == NULL ise return NULL. head->data == value ise tmp = head; head = head->next; free(tmp); return head;. Değilse prev = head; cur = head->next; ile gez; cur->data == value bulunca prev->next = cur->next; free(cur); return head;. main'de 30, 20, 10 ekle; head = list_remove(head, 20);; list_print(head);; tüm düğümleri free et.

Başlangıç kodu

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

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

Node *list_push_front(Node *head, int value) {
    Node *n = malloc(sizeof(Node));
    n->data = value;
    n->next = head;
    return n;
}

void list_print(Node *head) {
    Node *cur = head;
    while (cur != NULL) { printf("%d ", cur->data); cur = cur->next; }
    printf("\n");
}

// list_remove: value'yu bul ve sil; yeni başı döndür
// main: 30, 20, 10 ekle; 20'yi sil; list_print; tüm düğümleri free et

int main(void) {
    // buraya yaz
    return 0;
}

Örnek çözüm

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

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

Node *list_push_front(Node *head, int value) {
    Node *n = malloc(sizeof(Node));
    n->data = value;
    n->next = head;
    return n;
}

void list_print(Node *head) {
    Node *cur = head;
    while (cur != NULL) {
        printf("%d ", cur->data);
        cur = cur->next;
    }
    printf("\n");
}

Node *list_remove(Node *head, int value) {
    if (head == NULL) return NULL;
    if (head->data == value) {
        Node *tmp = head;
        head = head->next;
        free(tmp);
        return head;
    }
    Node *prev = head;
    Node *cur = head->next;
    while (cur != NULL) {
        if (cur->data == value) {
            prev->next = cur->next;
            free(cur);
            return head;
        }
        prev = cur;
        cur = cur->next;
    }
    return head;
}

int main(void) {
    Node *head = NULL;
    head = list_push_front(head, 30);
    head = list_push_front(head, 20);
    head = list_push_front(head, 10);
    head = list_remove(head, 20);
    list_print(head);
    while (head) { Node *t = head; head = head->next; free(t); }
    return 0;
}

Beklenen çıktı

10 30

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Ortadaki bir düğümü silerken ne güncellenir?

  • cur->data
  • prev->next Doğru cevap
  • cur->next
  • head->data

Açıklama: prev->next = cur->next ile cur atlanır.

2 Başı sil

Soru
Node *tmp = head; head = head->____; free(tmp);
Cevap
Node *tmp = head; head = head->next; free(tmp);

Açıklama: head->next yeni baş olur.

3 Silme durumları

Kavram Anlamı
boş liste return NULL
baş eşleşir head = head->next
orta eşleşir prev->next = cur->next
bulunamaz return head

Orta seviye bölümündeki tüm dersler