删除排序链表中重复的结点(C++)

题目:

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,最后返回链表头指针。

链表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;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值