题目:
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,最后返回链表头指针。
如:
链表1->2->3->3->4->4->5
输出为 1->2->5
思路:
定义辅助指针:p pre q和resHead。初始时 p和pre都指向链表头指针。
resHead初始化为值为-1。(头结点前的一个结点)
接下来依次遍历链表。p始终指向当前遍历到的结点。
A 如果p和p的下一个结点值相等 => 向后遍历。p = p -> next
否则
B 如果p的下一个结点存在 判断pre和p是否相等。 (同一个结点)
相等 => 说明指向的这个结点不是重复 将p链接到q。
C p的下一个结点不存在 说明已经遍历到最后一个结点。 指向B中相同的判断。
最后 将链表的最后一个结点置空。
贴代码:
#include <iostream>
using namespace std;
typedef int dataType;
struct DulNode
{
dataType val;
struct DulNode *next;
DulNode(dataType _val):
val(_val), next(NULL){}
};
void buildLink(DulNode **head)
{
dataType _val;
cin>>_val;
if (_val == -1)
{
*head = NULL;
return;
}
DulNode *p = NULL;
while(_val != -1)
{
DulNode *tmp = (DulNode*)malloc(sizeof(DulNode));
tmp->val = _val;
if (*head == NULL)
{
p = tmp;
*head = tmp;
}
else
{
p->next = tmp;
p = p->next;
}
cin>>_val;
}
p->next = NULL;
}
void traverseLink(DulNode *head)
{
DulNode *p = head;
while(p)
{
cout<<(p->val)<<" ";
p = p->next;
}
cout<<endl;
}
DulNode* deleteDuplication(DulNode *pHead)
{
if (pHead == NULL || pHead->next == NULL)
{
return pHead;
}
DulNode *p = pHead;
DulNode *pre = p;
DulNode *resHead = new DulNode(-1); // 最终输出链表头结点的前一个结点
DulNode *q = resHead;
while(p != NULL)
{
// 有重复结点 p往后遍历
if (p->next && p->val == p->next->val)
{
p = p->next;
}
else if(p->next)
{
// 当前p指向的结点不是重复结点
if (pre == p)
{
// 加入
q->next = new DulNode(p->val);
q = q->next;
}
// pre和p 都指向下一个结点
pre = p->next;
p = p->next;
}
// 遍历到最后一个结点
else
{
// 不是重复结点 加入
if (pre == p)
{
q->next = new DulNode(pre->val);
q = q->next;
}
break;
}
}
// 链表尾结点置空
q = NULL;
return resHead->next; // 输出头结点
}
int main(void)
{
DulNode *head = NULL;
buildLink(&head);
traverseLink(head);
head = deleteDuplication(head);
traverseLink(head);
return 0;
}