Özet - Dinamik veri
- C kursu
- Orta seviye
- Ders 75/116
- 5 dk
Bağlı liste, yığın ve kuyruğu birleştirerek bir geri-al/yinele sistemi yazarsın.
Özet - Dinamik veri
Bu grupta bağlı listeyi baştan kurduk: düğüm tanımı, başa ekleme, gezip yazdırma, silme ve dizi tabanlı yığın. Şimdi tüm parçaları bir araya getireceğiz.
Mini görev: 10 -> 20 -> 30 listesi kur, yazdır, ortadaki 20'yi sil, tekrar yazdır ve tüm belleği iade et. Bu, gerçek bir C programında dinamik verinin tipik yaşam döngüsüdür: kur, kullan, değiştir, temizle. malloc ile ayrılan her düğüm free ile iade edilmelidir; unutulursa sızıntı oluşur. Gezme döngüsü cur = cur->next ile ilerler; NULL görünce durur.
Uygulama Tüm parçaları birleştir
list_push_front, list_print ve list_remove işlevlerini yaz. main'de 30, 20, 10 değerlerini başa ekle; list_print(head); çağır; head = list_remove(head, 20);; tekrar list_print(head);; son olarak while (head) { Node *t = head; head = head->next; free(t); } ile tüm belleği iade et.
Başlangıç kodu
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
// list_push_front: başa ekle
// list_print: gezerek yazdır
// list_remove: value'yu sil
// main: 30, 20, 10 ekle; yazdır; 20'yi sil; yazdır; tümünü free et
int main(void) {
// buraya yaz
return 0;
}Örnek çözüm
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
Node *list_push_front(Node *head, int v) {
Node *n = malloc(sizeof(Node));
n->data = v; n->next = head;
return n;
}
void list_print(Node *head) {
Node *cur = head;
while (cur) { printf("%d ", cur->data); cur = cur->next; }
printf("\n");
}
Node *list_remove(Node *head, int v) {
if (!head) return NULL;
if (head->data == v) { Node *t = head; head = head->next; free(t); return head; }
Node *prev = head, *cur = head->next;
while (cur) {
if (cur->data == v) { 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);
list_print(head);
head = list_remove(head, 20);
list_print(head);
while (head) { Node *t = head; head = head->next; free(t); }
return 0;
}Beklenen çıktı
10 20 30 10 30
Dinamik veride dikkat
Dinamik veri güçlüdür ama dikkat ister. Üç temel ilke: her malloc'a bir free, iade edilen belleği bir daha kullanma, listeyi değiştirirken başın değişme olasılığını unutma.
Silme işlevi her zaman yeni başı döndürmelidir; çağıran da head = list_remove(head, x); ile geri almalıdır. Bu desen, başın silinmesi olasılığına karşı koruma sağlar. Gezme sırasında düğümü free edip sonra cur->next okumak hatalıdır; önce next'i sakla, sonra free yap. Yığın ve kuyruk, bu desenlerin dizilerle yapılan basit varyantlarıdır; aynı ilkeler geçerlidir.
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Liste yaşam döngüsü
| Kavram | Anlamı |
|---|---|
kur |
push_front ile |
yazdır |
list_print ile |
sil |
list_remove ile |
temizle |
free ile |
2 Listeyi tamamen temizlemek için ne yapılır?
- head = NULL yazmak yeter
- sadece ilk düğümü free et
- list_print çağır
- her düğümü free ile iade et Doğru cevap
Açıklama: Her malloc'a karşılık bir free gerekir.