【问题描述】
给定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 数组标记。
总结一下,连表的操作其实就是指针域的操作。只要将每一个结点怎么连,连哪一个结点搞明白,那也就没什么难的地方了