【2015统考真题】用单链表保存m个整数,结点的结构为[data] [link],且|data|<=n(n为正整数)。现要求设计一个时间复杂度尽可能高动的管法,对干链表中data的绝对值相等的结点,仅

【2015统考真题】用单链表保存m个整数,结点的结构为[data] [link],且|data|<=n(n为正整数)。现要求设计一个时间复杂度尽可能高动的管法,对干链表中data的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。例如,若给定的单链表head 如下:

在这里插入图片描述

代码思路:
这个说白了,就是链表版的去重,只不过这里的去重不仅仅是去除相同元素,连它的相反数也要去掉。我这里的思路就是,你用一个新链表,存储原先链表的元素,每次遍历原先链表元素,判断一下新链表中有无该元素的绝对值,如果有,就跳过,如果没有,你就插进去。

插完新链表,把新链表地址赋给原先链表,这样就完成了去重。

//判断当前链表L中是否有同元素a的绝对值的元素,有返回1,没有返回0
int contain(LinkList L, int a) {
	LNode* p = L->next;
	while (p != NULL) {
		if (p->data == a||p->data==0-a) {
			return 1;
		}
		p = p->next;
	}
	return 0;
}

//去除链表中绝对值重复
void del_CommonAbs(LinkList* L) {//删除链表中重复绝对值的元素
	LinkList L2=(LNode*)malloc(sizeof(LNode));//将原先链表中不重复的部分放到L2中
	LNode* p = (*L)->next;//用p遍历L
	LNode* q=(LNode*)malloc(sizeof(LNode)) ;//用q遍历L2
	//由于L中第一个元素是不可能重复的(第一个元素前面没有元素怎么重复?)
	//直接把L中第一个元素放到L2中
	q->data = p->data;
	q->next = NULL;
	L2->next = q;

	//第一个L中第一个节点已经放到L2中了,我们从L第二个节点开始遍历
	p = p->next;
	while (p != NULL) {
		int tmp = p->data;
		if (!contain(L2, tmp)) {//如果原先L2里面没有当前遍历元素的的绝对值,把当前值放到L2中
			q->next = (LNode*)malloc(sizeof(LNode));//新建一个L2节点
			q = q->next;
			q->data = tmp;
			q->next = NULL;
		}
		p = p->next;
	}

	//L2装填完毕,把L2的值重新写回L
	(*L) = L2;
}

int main()
{
	LinkList L;
	InitList2(&L);//初始化一个带头结点的链表 21,-15,-15,-7,15,2,3,2,2,9
	printf("初始链表为:");
	print2(L);

	printf("\n");
	printf("去除重复绝对值元素后的链表为:");
	del_CommonAbs(&L);
	print2(L);

	return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

劲夫学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值