用C写一个删除链表中重复元素的算法
时间: 2023-09-20 18:05:48 浏览: 230
删除链表中重复元素(c语言版)
4星 · 用户满意度95%
### 回答1:
你好!如果你要用 C 语言编写一个删除链表中重复元素的算法,可以按照以下步骤进行:
1. 定义链表结构体
首先,你需要定义链表结构体,包括链表节点的值和指向下一个节点的指针。比如:
```
struct ListNode {
int val;
struct ListNode* next;
};
```
2. 定义删除函数
接着,你需要定义一个函数,用于删除链表中重复元素。该函数的输入是链表头指针,输出是删除重复元素后的链表头指针。你可以按照以下思路编写该函数:
- 定义一个指针p,指向链表头节点。
- 遍历链表,如果当前节点的值和下一个节点的值相等,说明当前节点是重复元素,需要将其从链表中删除。
- 删除重复元素的方法是将当前节点的next指针指向下一个节点的next指针,然后释放下一个节点。
- 如果当前节点不是重复元素,将p指向下一个节点,继续遍历。
代码实现如下:
```
struct ListNode* deleteDuplicates(struct ListNode* head) {
struct ListNode* p = head;
while (p != NULL && p->next != NULL) {
if (p->val == p->next->val) {
struct ListNode* tmp = p->next;
p->next = tmp->next;
free(tmp);
} else {
p = p->next;
}
}
return head;
}
```
3. 调用删除函数
最后,你可以在主函数中创建链表并调用删除函数。比如:
```
int main() {
struct ListNode* node1 = (struct ListNode*)malloc(sizeof(struct ListNode));
node1->val = 1;
struct ListNode* node2 = (struct ListNode*)malloc(sizeof(struct ListNode));
node2->val = 1;
struct ListNode* node3 = (struct ListNode*)malloc(sizeof(struct ListNode));
node3->val = 2;
struct ListNode* node4 = (struct ListNode*)malloc(sizeof(struct ListNode));
node4->val = 2;
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = NULL;
struct ListNode* new_head = deleteDuplicates(node1);
// 遍历新链表,输出元素
struct ListNode* p = new_head;
while (p != NULL) {
printf("%d ", p->val);
p = p->next;
}
return 0;
}
```
该程序的输出结果为:1 2
希望这个答案对你有帮助!
### 回答2:
在C语言中,可以通过以下算法来删除链表中重复元素:
1. 定义一个指针curr和一个指针prev,分别指向当前节点和前一个节点。
2. 遍历整个链表,直到遍历到链表的末尾。
3. 对于每个遍历到的节点curr,需要检查它的值是否和前一个节点prev的值相同。
4. 如果curr的值和prev的值相同,说明当前节点是重复元素,需要将当前节点从链表中删除。
a. 修改prev节点的指针,使其指向curr节点的下一个节点。
b. 释放curr节点的内存空间,并将curr指针指向prev的下一个节点。
5. 如果curr的值和prev的值不相同,则说明当前节点不是重复元素,将prev指针指向curr节点。
6. 继续下一次循环,遍历链表的下一个节点。
以下是一个示例的C代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int val;
struct ListNode *next;
};
void deleteDuplicates(struct ListNode *head) {
if (head == NULL) {
return;
}
struct ListNode *prev = head;
struct ListNode *curr = head->next;
while (curr != NULL) {
if (curr->val == prev->val) {
prev->next = curr->next;
free(curr);
curr = prev->next;
} else {
prev = curr;
curr = curr->next;
}
}
}
int main() {
// 创建链表
struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode *node1 = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode *node2 = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode *node3 = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode *node4 = (struct ListNode*)malloc(sizeof(struct ListNode));
head->val = 1;
head->next = node1;
node1->val = 2;
node1->next = node2;
node2->val = 2;
node2->next = node3;
node3->val = 3;
node3->next = node4;
node4->val = 3;
node4->next = NULL;
// 删除重复元素
deleteDuplicates(head);
// 输出链表
struct ListNode *curr = head;
while (curr != NULL) {
printf("%d ", curr->val);
curr = curr->next;
}
printf("\n");
// 释放内存
free(node4);
free(node3);
free(node2);
free(node1);
free(head);
return 0;
}
```
在示例代码中,在创建完链表后,调用deleteDuplicates函数删除链表中重复的元素。然后使用一个循环输出链表中剩余的元素。最后释放链表节点的内存空间。
### 回答3:
删除链表中重复元素的算法可以通过比较当前节点与其后续节点的值是否相等来实现。
具体的算法流程如下:
1. 首先判断链表是否为空或只有一个节点,若是,则直接返回该链表。
2. 声明一个指针current指向链表的头节点,并用一个哈希表来记录已经出现过的节点的值。
3. 遍历链表,若current节点的值在哈希表中不存在,则将其插入哈希表中,并将current节点的指针指向下一个节点。
4. 若current节点的值在哈希表中已经存在,则将current节点的下一个节点删除,并将current节点的指针指向删除节点后面的节点。
C语言实现如下:
```c
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int val;
struct ListNode* next;
};
struct ListNode* deleteDuplicates(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* current = head;
struct ListNode* temp;
while (current != NULL && current->next != NULL) {
if (current->val == current->next->val) {
temp = current->next;
current->next = current->next->next;
free(temp);
} else {
current = current->next;
}
}
return head;
}
```
该算法时间复杂度为O(n),其中n为链表的长度。
阅读全文