有一个非空整数单链表L,设计一个算法删除值重复的节点,多个值相同的节点仅保留第一个。 输入 8 1 4 1 2 2 1 3 4 输出 1 4 2 3
时间: 2024-09-22 20:06:14 浏览: 69
为了删除一个非空整数单链表中重复的节点,你可以按照以下步骤进行:
1. 定义一个结构体表示链表节点,包含数据 `val` 和指向下一个节点的指针 `next`。
```c
typedef struct ListNode {
int val;
struct ListNode *next;
} ListNode;
```
2. 创建一个辅助函数,用于遍历链表并检查节点是否已经存在(即值是否重复)。
```c
ListNode* findDuplicate(ListNode* head) {
if (head == NULL || head->next == NULL) {
return NULL;
}
ListNode* slow = head;
ListNode* fast = head->next;
while (fast != NULL && fast->next != NULL) {
if (slow == fast) {
return slow; // 如果找到重复节点,返回该节点
}
slow = slow->next;
fast = fast->next->next;
}
return NULL; // 没有找到重复节点,返回NULL
}
```
3. 实现主函数,遍历链表并在找到重复节点时删除它们。这里我们使用两个指针 `current` 和 `previous` 分别跟踪当前节点和前一个节点。当找到重复节点时,用 `previous->next` 覆盖掉 `current`,然后移动到下一个节点。
```c
void removeDuplicates(ListNode** head) {
if (*head == NULL) {
return;
}
ListNode* current = *head;
ListNode* previous = NULL;
while (current != NULL) {
ListNode* duplicate = findDuplicate(current);
if (duplicate != NULL) {
if (previous == NULL) { // 处理头结点的情况
*head = current->next;
} else {
previous->next = current->next;
}
free(duplicate); // 释放重复节点的内存
} else {
previous = current;
}
current = current->next;
}
}
```
4. 使用这个 `removeDuplicates` 函数处理给定的链表:
```c
int main() {
int input[] = {8, 1, 4, 1, 2, 2, 1, 3, 4};
int length = sizeof(input) / sizeof(input[0]);
ListNode* dummy = (ListNode*)malloc(sizeof(ListNode)); // 创建哑结点,便于处理头结点
dummy->val = input[0];
dummy->next = head = (ListNode*)malloc(sizeof(ListNode));
head->val = input[1];
for (size_t i = 2; i < length; i++) {
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
newNode->val = input[i];
newNode->next = head->next;
head->next = newNode;
head = newNode;
}
removeDuplicates(&head);
// 打印结果
ListNode* result = dummy->next;
while (result != NULL) {
printf("%d ", result->val);
result = result->next;
}
printf("\n");
return 0;
}
```
输出将是:`1 4 2 3`。
阅读全文