《算法通关村第一关——链表经典问题之删除链表元素笔记》

方式一:删除特定结点

示例:

输入:head = [1,2,6,3,4,5,6],data  = 6

输出:[1,2,3,4,5]

说明:删除节点node时,必须知道前驱pre节点和后继next结点,然后让pre.nextNode=node.nextNode,这样node就脱离了链表,会在某个时刻被gc回收掉。

思路:1.创建一个虚拟表头node,使其nextNode指向headNode,再创建一个新的结点:Node cur = node。

           2.开始循环链表寻找特定结点,使用cur.nextNode.data来判断是否为特定节点。

           3.如果找到目标元素,使用cur.nextNode=cur.nextNode.nextNode来删除。

           4.如果不是目标元素,使用cur=cur.nextNode。

           5.注意返回值应该为:node.next。

具体实现的代码封装在方法removeNode()中,如下:

    //移除指定数据的节点,data表示要删除结点的数据,headNode为头结点
	private static Node removeNode(int data,Node headNode) {
		//创建一个虚拟节点node,指向headNode
		Node node =new Node(0);
		node.nextNode = headNode;
		Node curNode = node;
		while(curNode.nextNode!=null) {
			if(curNode.nextNode.data == data) {
				curNode.nextNode = curNode.nextNode.nextNode;
			}else {
				curNode = curNode.nextNode;
			}
		}
		return node.nextNode;
	}

方式二:删除倒数第n个结点

示例:

输入:head=[1,2,3,4,5],n=2

输出:[1,2,3,5]

思路:先遍历一遍链表获得链表的长度L,然后再次遍历删除位置为L-n+1的结点 。

          1.创建一个虚拟表头node,使其nextNode指向headNode,再创建一个新的结点:Node curNode = node。 

           2.开始循环链表将curNode指向第L-n+1个结点的前驱结点,然后使用curNode.next=curNode.nextNode.nextNode删除结点。

具体代码入下:

//删除倒数第n个结点
	private static Node removeEndNode(int n,Node headNode) {
		Node node = new Node(0);
		node.nextNode = headNode;
		Node curNode = node;
		int m = linkedListLength(headNode);
		//删除第i个结点
		int i = m - n + 1;
		for(int k=1;k<i;k++) {
			curNode=curNode.nextNode;
		}
		curNode.nextNode = curNode.nextNode.nextNode;
		return node.nextNode;
	}
	//遍历链表获得链表的总长度L
	private static int linkedListLength(Node headNode) {
		int m=1;
		Node curNode = headNode;
		while(curNode.nextNode != null) {
			curNode=curNode.nextNode;
			m++;
		}
		return m;
	}

方式三:删除重复元素

(1)重复元素保留一个

前提:链表为升序。

示例:

输入:head=[1,1,2,3,3]

输出:[1,2,3]

思路: 由于链表已经是排序好的,因此重复的元素是连续的,对链表进行遍历,查询重复即可删除重复的元素。

具体代码如下:

//删除重复的结点,链表为有序
	private static Node deleteDuplicates(Node headNode) {
		Node node = headNode;
		if(headNode == null) {
			return headNode;
		}
		while(node.nextNode != null) {
			if(node.data == node.nextNode.data) {
				node.nextNode = node.nextNode.nextNode;
			}else {
				node = node.nextNode;
			}
		}
		return headNode;
	}

(2)重复元素都不要

前提:链表为有序。

示例:

输入:head=[1,2,3,3,4,4,5]

输出:[1,2,5]

思路:链表直接对curNode.nextNode以及curNode.nextNode.nextNode两个node进行比较就行了,这里需要注意两个node可能为空,需要判断。

具体代码如下所示:

        //删除重复的结点全部删除,链表为有序
		private static Node deleteDuplicates(Node headNode) {
			Node node = new Node(0);
			node.nextNode = headNode;
			Node curNode = node;
			if(headNode == null) {
				return headNode;
			}
			while(curNode.nextNode != null && curNode.nextNode.nextNode!=null) {
				if(curNode.nextNode.data == curNode.nextNode.nextNode.data) {
					int x = curNode.nextNode.data;
					while(curNode.nextNode != null && curNode.nextNode.data==x) {
						curNode.nextNode = curNode.nextNode.nextNode;
					}
				}else {
					curNode = curNode.nextNode;
				}
			}
			return node.nextNode;
		}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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 希望这个答案对你有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值