【問題描述】
給定N個整數,將這些整數中與M相等的刪除
假定給出的整數序列為:1,3,3,0,-3,5,6,8,3,10,22,-1,3,5,11,20,100,3,9,3
應該將其放在一個鏈表中,鏈表長度為20
要刪除的數是3,刪除以后,鏈表中只剩14個元素:1 0 -3 5 6 8 10 22 -1 5 11 20 100 9
【輸入】
包含3行:
第一行是一個整數n(1 <= n <= 200000),代表數組中元素的個數。
第二行包含n個整數,代表數組中的n個元素。每個整數之間用空格分隔;每個整數的取值在32位有符號整數范圍以內。
第三行是一個整數k,代表待刪除元素的值(k的取值也在32位有符號整數范圍內)。輸出輸出只有1行:
將數組內所有待刪除元素刪除以后,輸出數組內的剩余元素的值,每個整數之間用空格分隔。
【輸出】
輸出只有1行:
將數組內所有待刪除元素刪除以后,輸出數組內的剩余元素的值,每個整數之間用空格分隔。
嗯......就是依次查找要刪除的元素,在它前面的一個節點停下,將這個節點的 *next 連到要刪除的元素的下一個節點上,最后釋放要刪除的元素的內存。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 struct node 8 { 9 int data; 10 node *next; 11 }*head, *p, *r; 12 int n, x; 13 int main() 14 { 15 scanf("%d", &n); 16 int a; 17 head = new node; head -> next = NULL; 18 r = head; //初始化 19 for(int i = 1; i <= n; ++i) //建立鏈表 20 { 21 scanf("%d", &a); 22 p = new node; 23 p -> data = a; 24 p -> next = NULL; 25 r -> next = p; 26 r = p; 27 } 28 p = head; 29 scanf("%d", &x); 30 while(p != NULL) 31 { 32 node *s = p -> next; 33 if(s && s -> data == x) 34 { 35 p -> next = p -> next -> next; 36 free(s); //釋放結點s的內存 37 } 38 else p = p -> next; 39 /*一定要加上這個else,因為我們要判斷的是下一個數, 40 而刪除后的下一個數就是被刪除的數的下個數了。否則 41 將跳過一個數,會漏查*/ 42 } 43 p = head -> next; 44 while(p -> next != NULL) 45 { 46 printf("%d ",p -> data); 47 p = p -> next; 48 } 49 printf("%d\n", p -> data); 50 return 0; 51 }
因為鏈表中的元素沒有一個具體的位置,我們只能知道一個結點和誰連着的,這也就導致我們查找每一個結點是必須從頭找,不是很快捷。但凡事都是有兩面性,我們也就可以在鏈表中忽略位置這個概念,在刪除和添加結點時就不用想數組一樣將整體挪動位置或用 vis 數組標記。
總結一下,連表的操作其實就是指針域的操作。只要將每一個結點怎么連,連哪一個結點搞明白,那也就沒什么難的地方了