Penyisipan dan Penghapusan
Ubah list.
Penyisipan dan Penghapusan adalah pelajaran C Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C Academy mencakup 4 pelajaran total.
Memodifikasi daftar
Keunggulan daftar tertaut adalah penyisipan dan penghapusan yang murah. Anda mengatur ulang penunjuk, bukan menggeser elemen seperti pada larik.
Pelajaran ini membahas penyisipan dan penghapusan simpul di berbagai posisi.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *head = make(2);
printf("start: %d\n", head->value);
free(head);
return 0;
}Menyisipkan di awal
Menyisipkan di kepala memiliki kompleksitas O(1). Buat simpul baru, arahkan next-nya ke kepala saat ini, lalu ubah kepala agar menunjuk ke simpul baru.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *head = make(2);
struct Node *fresh = make(1);
fresh->next = head;
head = fresh;
printf("%d -> %d\n", head->value, head->next->value);
return 0;
}Mengapa harus meneruskan penunjuk ganda
Untuk mengubah kepala dari dalam suatu fungsi, Anda harus meneruskan alamat-nya: sebuah struct Node **.
Jika tidak, fungsi hanya mengubah salinan lokal dan kepala milik pemanggil tetap tidak berubah.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void push(struct Node **head, int v) {
struct Node *n = make(v);
n->next = *head;
*head = n;
}
int main(void) {
struct Node *head = NULL;
push(&head, 5);
push(&head, 4);
printf("%d %d\n", head->value, head->next->value);
return 0;
}Menyisipkan di akhir
Menambahkan di akhir memerlukan penelusuran hingga simpul terakhir, lalu menghubungkan simpul baru ke next-nya.
Jika daftar kosong, simpul baru menjadi kepala.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void append(struct Node **head, int v) {
struct Node *n = make(v);
if (!*head) { *head = n; return; }
struct Node *p = *head;
while (p->next) p = p->next;
p->next = n;
}
int main(void) {
struct Node *head = NULL;
append(&head, 1); append(&head, 2);
printf("%d %d\n", head->value, head->next->value);
return 0;
}Menyisipkan setelah simpul
Untuk menyisipkan di tengah, temukan simpul setelahnya Anda ingin menyisipkan, lalu sisipkan simpul baru di antara simpul tersebut dan penerusnya saat ini.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void insert_after(struct Node *node, int v) {
struct Node *n = make(v);
n->next = node->next;
node->next = n;
}
int main(void) {
struct Node *head = make(1);
head->next = make(3);
insert_after(head, 2);
printf("%d %d %d\n", head->value, head->next->value, head->next->next->value);
return 0;
}Urutan operasi itu penting
Saat menyisipkan simpul, selalu tetapkan next milik simpul baru sebelum mengubah next milik simpul sebelumnya.
Jika dilakukan sebaliknya, referensi ke sisa daftar akan hilang.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *a = make(1), *c = make(3);
a->next = c;
struct Node *b = make(2);
b->next = a->next;
a->next = b;
printf("%d %d %d\n", a->value, b->value, c->value);
return 0;
}Menghapus simpul pertama
Menghapus kepala berarti menyimpannya, memajukan kepala ke head->next, lalu membebaskan kepala lama.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void pop(struct Node **head) {
if (!*head) return;
struct Node *old = *head;
*head = old->next;
free(old);
}
int main(void) {
struct Node *head = make(1);
head->next = make(2);
pop(&head);
printf("new head: %d\n", head->value);
free(head);
return 0;
}Menghapus berdasarkan nilai
Untuk menghapus simpul dengan nilai tertentu, lacak simpul sebelumnya agar Anda dapat melewati target dengan menetapkan prev->next = target->next.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void del(struct Node **head, int v) {
struct Node *cur = *head, *prev = NULL;
while (cur && cur->value != v) { prev = cur; cur = cur->next; }
if (!cur) return;
if (prev) prev->next = cur->next; else *head = cur->next;
free(cur);
}
int main(void) {
struct Node *head = make(1);
head->next = make(2);
head->next->next = make(3);
del(&head, 2);
printf("%d %d\n", head->value, head->next->value);
return 0;
}Menangani kasus kepala
Penghapusan memiliki kasus khusus saat target adalah kepala: tidak ada simpul sebelumnya, sehingga Anda memperbarui penunjuk kepala secara langsung.
Penunjuk ganda membuat proses ini lebih sederhana, seperti yang ditunjukkan di atas.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *head = make(1);
head->next = make(2);
struct Node *old = head;
head = head->next;
free(old);
printf("head now %d\n", head->value);
free(head);
return 0;
}Mencegah kebocoran memori
Setiap simpul yang Anda hapus dari daftar harus di-free. Menghapus simpul tanpa membebaskannya menyebabkan memori yang ditempatinya bocor.
Demikian pula, jangan pernah membebaskan simpul saat masih tertaut, karena Anda akan membuat penunjuk yang menggantung.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *n = make(7);
free(n);
printf("node freed, no leak\n");
return 0;
}Penyisipan dengan urutan terurut
Menyisipkan dalam urutan terurut adalah variasi yang umum: telusuri daftar hingga menemukan posisi yang sesuai dengan nilai tersebut, lalu sisipkan di sana.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void insert_sorted(struct Node **head, int v) {
struct Node *n = make(v);
if (!*head || (*head)->value >= v) { n->next = *head; *head = n; return; }
struct Node *p = *head;
while (p->next && p->next->value < v) p = p->next;
n->next = p->next; p->next = n;
}
int main(void) {
struct Node *head = NULL;
insert_sorted(&head, 3);
insert_sorted(&head, 1);
insert_sorted(&head, 2);
for (struct Node *p = head; p; p = p->next) printf("%d ", p->value);
printf("\n");
return 0;
}Pemeriksaan Singkat
Uji pemahaman Anda tentang modifikasi daftar.
Ringkasan
Anda telah mempelajari cara menyisipkan dan menghapus simpul:
- Penyisipan di awal berkompleksitas O(1); penambahan di akhir atau penyisipan berurutan memerlukan penelusuran.
- Gunakan penunjuk ganda saat kepala mungkin berubah.
- Sisipkan dengan hati-hati: tetapkan
nextmilik simpul baru sebelum menautkannya kembali. - Lacak simpul sebelumnya untuk penghapusan, dan selalu
freesimpul yang dihapus.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Penyisipan dan Penghapusan” gratis?
Ya — teks lengkap “Penyisipan dan Penghapusan” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C Academy, upgrade ke CoddyKit PRO. Kursus C Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Penyisipan dan Penghapusan”?
Ubah list. Kamu berlatih C Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai C Academy?
Tidak diperlukan pengalaman sebelumnya. C Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Penyisipan dan Penghapusan” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran C Academy ini?
Ya. Setiap pelajaran C Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Linked List Satu Arah
- Penyisipan dan Penghapusan
- Penelusuran dan Pencarian
- Linked List Dua Arah