删除递增有序单链表中的重复元素。
时间: 2023-05-18 20:03:24 浏览: 100
可以使用双指针法,遍历链表,如果当前节点的值与下一个节点的值相同,则删除下一个节点,否则继续遍历下一个节点。具体实现可以参考以下代码:
```
struct ListNode* deleteDuplicates(struct ListNode* head){
if(head == NULL || head->next == NULL) return head;
struct ListNode *p = head, *q = head->next;
while(q != NULL){
if(p->val == q->val){
p->next = q->next;
free(q);
q = p->next;
}else{
p = q;
q = q->next;
}
}
return head;
}
```
这段代码可以删除递增有序单链表中的重复元素,时间复杂度为 O(n),空间复杂度为 O(1)。
相关问题
使用CPP对任意输入的一组数据,建立一个递增有序的单链表。 将单链表拆分成两个单链表,其中一个全为奇数,另一个全为偶数(尽量利用原存储空间)。 用递增有序的链表A、B表示两个集合,设计算法求它们的并集。 删除递增有序单链表中的重复元素。 求单循环链表中所有结点的最大值、最小值以及平均值。 判断双循环链表是否对称。
1. 使用CPP对任意输入的一组数据,建立一个递增有序的单链表。
可以使用链表的插入排序来实现。具体步骤如下:
1)首先创建一个空链表,将第一个元素插入到链表中。
2)从第二个元素开始遍历输入的数据,将每个元素插入到链表中的正确位置,使得链表保持递增有序。
代码示例:
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* insert(ListNode* head, int val) {
ListNode* node = new ListNode(val);
if (!head) {
return node;
}
if (val < head->val) {
node->next = head;
return node;
}
ListNode* cur = head;
while (cur->next && cur->next->val < val) {
cur = cur->next;
}
node->next = cur->next;
cur->next = node;
return head;
}
ListNode* createList() {
ListNode* head = NULL;
int val;
while (cin >> val) {
head = insert(head, val);
}
return head;
}
2. 将单链表拆分成两个单链表,其中一个全为奇数,另一个全为偶数(尽量利用原存储空间)。
可以使用两个指针分别指向奇数链表和偶数链表的尾部,遍历原链表,将奇数节点插入到奇数链表的尾部,偶数节点插入到偶数链表的尾部。
代码示例:
void splitList(ListNode* head, ListNode*& odd, ListNode*& even) {
ListNode* oddTail = NULL;
ListNode* evenTail = NULL;
while (head) {
if (head->val % 2 == 1) {
if (!odd) {
odd = head;
} else {
oddTail->next = head;
}
oddTail = head;
} else {
if (!even) {
even = head;
} else {
evenTail->next = head;
}
evenTail = head;
}
head = head->next;
}
if (oddTail) {
oddTail->next = NULL;
}
if (evenTail) {
evenTail->next = NULL;
}
}
3. 用递增有序的链表A、B表示两个集合,设计算法求它们的并集。
可以使用归并排序的思想,将两个有序链表合并成一个有序链表。具体步骤如下:
1)创建一个新链表,用两个指针分别指向链表A和链表B的头部。
2)比较两个指针所指节点的值,将较小的节点插入到新链表中,并将指针后移。
3)如果其中一个链表已经遍历完了,将另一个链表的剩余部分直接插入到新链表的尾部。
代码示例:
ListNode* merge(ListNode* A, ListNode* B) {
ListNode* head = NULL;
ListNode* tail = NULL;
while (A && B) {
if (A->val < B->val) {
if (!head) {
head = A;
} else {
tail->next = A;
}
tail = A;
A = A->next;
} else {
if (!head) {
head = B;
} else {
tail->next = B;
}
tail = B;
B = B->next;
}
}
if (A) {
tail->next = A;
}
if (B) {
tail->next = B;
}
return head;
}
4. 删除递增有序单链表中的重复元素。
可以使用两个指针,一个指向当前节点,另一个指向下一个节点,如果当前节点的值等于下一个节点的值,就将下一个节点删除。
代码示例:
void deleteDuplicates(ListNode* head) {
ListNode* cur = head;
while (cur) {
ListNode* next = cur->next;
while (next && next->val == cur->val) {
cur->next = next->next;
delete next;
next = cur->next;
}
cur = cur->next;
}
}
5. 求单循环链表中所有结点的最大值、最小值以及平均值。
可以使用一个指针遍历链表,同时记录最大值、最小值和节点个数,最后计算平均值。
代码示例:
void calcStats(ListNode* head) {
if (!head) {
return;
}
ListNode* cur = head->next;
int maxVal = head->val;
int minVal = head->val;
int sum = head->val;
int count = 1;
while (cur != head) {
maxVal = max(maxVal, cur->val);
minVal = min(minVal, cur->val);
sum += cur->val;
count++;
cur = cur->next;
}
double avg = (double)sum / count;
cout << "Max value: " << maxVal << endl;
cout << "Min value: " << minVal << endl;
cout << "Average value: " << avg << endl;
}
6. 判断双循环链表是否对称。
可以使用两个指针,一个指向头部,一个指向尾部,依次比较两个指针所指节点的值是否相等,如果不相等,则不是对称的。
代码示例:
bool isSymmetric(ListNode* head) {
if (!head) {
return true;
}
ListNode* front = head;
ListNode* back = head->prev;
while (front != back && front->prev != back) {
if (front->val != back->val) {
return false;
}
front = front->next;
back = back->prev;
}
return true;
}
在有序递增的单链表中,存在重复的元素,要求删除重复元素,用c语言
在C语言中,如果你想从一个已排序的递增单链表中删除重复的元素,可以采用两个指针的方式来操作。首先创建两个指针,一个指向当前节点(`current`),另一个用于比较并记录已访问过的节点(`prev`)。遍历链表的过程中,如果当前节点的值等于或大于`prev`节点的值,说明有重复,就将`prev`节点的下一个节点设置为当前节点,然后继续移动`prev`到当前节点,直到找到不同的值。
以下是简化的伪代码:
```c
struct Node {
int data;
struct Node* next;
};
void removeDuplicates(struct Node** head) {
if (*head == NULL) return;
// 初始化前驱节点为头结点
struct Node* prev = *head;
struct Node* current = (*head)->next;
while (current != NULL) {
if (current->data >= prev->data) { // 如果当前值大于等于前驱值
prev = current; // 更新前驱指针
} else {
// 更改前驱的下一个节点为当前节点
prev->next = current->next;
// 移动前驱节点
prev = current;
}
current = current->next; // 指向下一个节点
}
}
```
阅读全文