有一个非空整数单链表L,设计一个算法删除值重复的节点,多个值相同的节点仅保留第一个。 输入 8 1 4 1 2 2 1 3 4 输出 1 4 2 3 样例输入 8 1 4 1 2 2 1 3 4 样例输出 1 4 2 3用c语言写出上述程序代码
时间: 2024-09-22 20:05:58 浏览: 26
基于链表的两个非递减有序序列的合并.docx
在C语言中,你可以通过遍历链表并使用两个指针来解决这个问题。一个指针`p`正常遍历,另一个指针`q`作为标记当前唯一的元素。当遇到重复元素时,将`q`的下一个节点指向`p`,然后继续前进。最后返回`p`即可得到去重后的链表。
下面是相应的C语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义链表结构体
typedef struct ListNode {
int val;
struct ListNode* next;
} ListNode;
// 创建一个新的链表节点
ListNode* createNode(int val) {
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
newNode->val = val;
newNode->next = NULL;
return newNode;
}
// 删除重复节点
ListNode* deleteDuplicates(ListNode* head) {
if (head == NULL || head->next == NULL)
return head; // 如果链表为空或只有一个元素,无需处理
ListNode* p = head;
ListNode* q = head;
while (p != NULL && p->next != NULL) {
if (p->val == p->next->val) {
q = q->next; // 跳过重复的节点
} else {
p->next = p->next->next; // 非重复节点的next指向前一个非重复节点
q = p;
}
p = p->next;
}
return head;
}
// 打印链表
void printList(ListNode* node) {
while (node != NULL) {
printf("%d -> ", node->val);
node = node->next;
}
printf("NULL\n");
}
int main() {
int n, val;
scanf("%d", &n); // 输入节点个数
ListNode* head = NULL;
for (int i = 0; i < n; ++i) {
scanf("%d", &val);
if (i == 0 || head->val != val) {
head = createNode(val);
head->next = head; // 处理头节点,使其指向自身
} else {
head->next = deleteDuplicates(head->next); // 更新链表头的next为去重后的链表
}
}
printList(head);
return 0;
}
```
这个程序首先创建一个链表,如果遇到新的值则添加新节点,如果遇到重复值则跳过。在主函数中调用`deleteDuplicates`并打印结果。
阅读全文