题目如下:
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入:head = [1,2,3,3,4,4,5] 输出:[1,2,5]
示例 2:
输入:head = [1,1,1,2,3] 输出:[2,3]
提示:
链表中节点数目在范围 [0, 300] 内
-100 <= Node.val <= 100
题目数据保证链表已经按升序 排列
效果如下:
代码部分:
第一部分
结构体定义:
typedef struct Node {
int val;
struct Node* next;
}Node;
typedef Node* List;
代码部分:
List head, head1, tail;
Node* p,*p1;//p用来创建空节点,p1用来释放被删除节点的内存
p = (Node*)malloc(sizeof(struct Node));
int ch;
int nums=0;
head = p,head1=p;
tail = p;
p1 = p;
head->next = NULL;
printf("请输入链表内容");
while ((ch = getchar()) != '\n') {
if (ch == ' ')
continue;
else {
p = (Node*)malloc(sizeof(struct Node));
p->val = ch - 48;
tail->next = p;
tail = p;
tail->next = NULL;
}
}
tail = head;
head1 = head1->next;//指向第一个节点
我们先进行内容的输入,因为题目的规定,所以我们这里采用升序输入。
之后让tail重新指向头节点,head1指向第一个储存值的节点。
第二部分
for (; head1->next != NULL;) {
if (head1->val != nums) {
nums = head1->val;
}
if(head1->next->val == nums) {
p1 = head1;
tail->next = head1->next;
head1 = head1->next;
free(p1);
if (head1->next == NULL) {//判断是否会越界
free(head1);
tail->next = NULL;
break;
}
else if (head1->next->val != nums) {
p1 = head1;
tail->next = head1->next;
head1 = head1->next;
continue;
}
continue;//避免tail和head1指向不是我们预期的节点
}
tail = tail->next;//避免tail一直停留在当前节点
head1 = head1->next;//避免head1一直停留在当前节点
}
我们先用一个if语句记录下第一个节点的值,之后又进行一次判断,如果下一个节点的值和当前节点的值相同,那么我们就进行删除当前节点的操作,在这里,我们又进行了一次判断,判断现在的head1是否是最后一个节点,如果是的话,就删除这个节点,并且结束循环,避免越界,如果不是,那么就进行删除操作,并且让head1指向下一个节点。
循环的后面部分,我们让tail指向下一个节点,也让head1指向下一个节点。
为什么呢,比如我们输入的是1 2 3,如果没有这两个语句,那么head1和tail就会一直停留在当前节点,有了这两个语句,那么我们的if语句内也要进行修改,所以我们才在if语句内加了continue。
第三部分
for (; head->next != NULL;) {
head = head->next;
printf("%d ", head->val);
}
return 0;
这部分进行打印,打印完成后直接结束程序。
至此,讲解完毕。
(新人写作,有些地方可能讲解不清,请谅解)。