習題11-8 單鏈表結點刪除 (20分)
本題要求實現兩個函數,分別將讀入的數據存儲為單鏈表、將鏈表中所有存儲了某給定值的結點刪除。鏈表結點定義如下:
struct ListNode {
int data;
ListNode *next;
};
函數接口定義:
struct ListNode *readlist();
struct ListNode *deletem( struct ListNode *L, int m );
函數readlist
從標准輸入讀入一系列正整數,按照讀入順序建立單鏈表。當讀到−1時表示輸入結束,函數應返回指向單鏈表頭結點的指針。
函數deletem
將單鏈表L
中所有存儲了m
的結點刪除。返回指向結果鏈表頭結點的指針。
裁判測試程序樣例:
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
struct ListNode *readlist();
struct ListNode *deletem( struct ListNode *L, int m );
void printlist( struct ListNode *L )
{
struct ListNode *p = L;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
int m;
struct ListNode *L = readlist();
scanf("%d", &m);
L = deletem(L, m);
printlist(L);
return 0;
}
/* 你的代碼將被嵌在這里 */
輸入樣例:
10 11 10 12 10 -1
10
輸出樣例:
11 12
我一開始的時候在 連續從頭、中、尾刪除 這個測試用例過不去,后來想想指向現在要刪除的這個結點的前一個結點如果是要刪除的呢?或者已經 free() 了呢?
如果你也是第四個過不去試試:
1 2 1 1 1 2 1 -1
1
struct ListNode *readlist()
{
struct ListNode *head, *tail, *p;
int n;
head = tail = p = NULL;
do {
scanf("%d", &n);
if (n < 0) {
break;
} else {
p = malloc(sizeof(struct ListNode));
p->data = n;
p->next = NULL;
if (tail != NULL) {
tail->next = p;
} else {
head = p;
}
tail = p;
}
} while (n > 0);
return head;
}
struct ListNode *deletem( struct ListNode *L, int m )
{
struct ListNode *p, *q;
for (p = L, q = NULL; p != NULL; p = p->next) {
if (p->data == m) {
if ( q && p != L) {
q->next = p->next;
} else {
L = p->next;
}
free(p);
} else {
q = p;
}
}
return L;
}