链表的基本操作

// 1两个链表的第一个公共节点
public static Node findFirstCommonNode(Node head1, Node head2) {
	Node tmp1 = head1;
	Node tmp2 = head2;
	int size1 = 0;
	int size2 = 0;
	while (tmp1 != null) {
		tmp1 = tmp1.next;
		size1++;
	}
	while (tmp2 != null) {
		tmp2 = tmp2.next;
		size2++;
	}
	tmp1 = head1;
	tmp2 = head2;
	if (size1 > size2) {
		int x = size1 - size2;
		while (x > 0) {
			tmp1 = tmp1.next;
			x--;
		}
	} else {
		int x = size2 - size1;
		while (x > 0) {
			tmp2 = tmp2.next;
			x--;
		}
	}

	while (tmp1 != tmp2 && tmp1 != null && tmp2 != null) {
		tmp1 = tmp1.next;
		tmp2 = tmp2.next;
	}
	return tmp1;
}

// 2从尾到头打印链表
public ArrayList<Integer> printListFromTailToHead(Node head) {
	// 递归
	ArrayList<Integer> list = new ArrayList<>();
	while (head != null) {
		list = printListFromTailToHead(head.next);
		list.add(head.data);
	}
	return list;
	//非递归
	ArrayList<Integer> list = new ArrayList<>();
	Node tmp = head;
	while(tmp != null) {
		list.add(0,tmp.data);
		tmp = tmp.next;
	}
	return list;
}

// 3判断链表是否有环,有环的情况下找出环的入口
public Node hasLooper(Node head) {
	if (head == null || head.next == null) {
		return null;
	}
	Node fast = head;
	Node slow = head;
	while (fast != null && fast.next != null) {// 无环的话,循环正常结束
		fast = fast.next.next;
		slow = slow.next;
		if (fast == slow) {// 有环的话,两个指针会相遇,这时退出循环
			System.out.println("111");
			break;
		}
	}
	if (fast == null || fast.next == null) {// 无环的话,循环正常结束,这里判断一下
		return null;
	}
	// 相遇之后,让其中一个指针从头开始每次一步,另外一个指针从当前位置开始,每次一步,最终这两个指针会在入口处相遇
	fast = head;
	while (fast != slow) {
		fast = fast.next;
		slow = slow.next;
	}
	return fast;
}

// 4删除重复节点(1-->2-->3-->3-->4-->4-->5变成1-->2-->3-->4-->5)
public Node deleteDuplicate(Node head) {
	if (head == null || head.next == null) {
		return head;
	}
	Node newHead = new Node(0);// 创建一个头节点,然后从第二个节点开始遍历
	newHead.next = head;
	Node pre = head;
	Node last = head;
	while (last != null) {// 遍历整个链表
		if (last.next != null && last.data == last.next.data) {// 判断当前节点的下一个节点是否重复
			while (last.next != null && last.data == last.next.data) {// 循环判断是否连续重复
				last = last.next;
			}
			pre.next = last;// 越过重复的节点,相同的节点只保留最后一个
		} else {// 没有重复,节点向后移动
			pre = pre.next;
			last = last.next;
		}
	}

	return newHead.next;
}
//5链表的反转
public Node reverse(Node head) {
	if(head == null || head.next == null) {
		return head;
	}
	//递归
	//先递归到最后一个节点
	/*Node newHead = reverse(head.next);
	//假设已经执行到最外层的递归方法了
	head.next.next = head;
	head.next = null;
	return newHead;*/
	//非递归
	Node preNode = null;
	Node curNode = head;
	while(curNode != null) {
		//先把当前节点的下一个节点记录下来,防止后续节点丢失
		Node tmp = curNode.next;
		//当前节点断开并反过来
		curNode.next = preNode;
		//preNode  与    curNode  同时向后一步
		preNode = curNode;
		curNode = tmp;
	}
	return preNode;
}
//6找到倒数第K个节点
public Node findLastK(Node head, int k) {
	if (k < 0 || head == null || head.next == null) {
		return null;
	}
	//快慢两个指针,快指针先走k步,然后两个指针再一起走
	Node fast = head;
	Node slow = head;
	while(fast != null) {
		if(k<=0) {
			slow = slow.next;
		}
		fast = fast.next;
		k--;
	}
	return k > 0 ? null : slow;
}

//7找到链表的中间结点
public Node findMidNode(Node head) {
	if(head == null || head.next == null) {
		return head;
	}
	Node fast = head;
	Node slow = head;
	while(fast !=null && fast.next != null && fast.next.next != null) {
		fast = fast.next.next;
		slow = slow.next;
	}
	return slow;
}
//8合并两个排序的链表
public Node Merge(Node list1,Node list2) {
	//建立一个空链表
	Node head = new Node(0);
	Node tmp = head;
	//同时遍历两个链表,小的节点先加入新链表
	while(list1 !=null && list2!=null) {
		if(list1.data<list2.data) {
			tmp.next = list1;
			tmp=list1;
			list1 = list1.next;
		}else {
			tmp.next = list2;
			tmp=list2;
			list2 = list2.next;
		}
	}
	//最后把没遍历完的链表全部加入新链表
	if(list1 != null) {
		tmp.next = list1;
	}
	if(list2 != null) {
		tmp.next = list2;
	}
	//返回值应该是新链表的第二个节点开始
	return head.next;
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是C语言链表基本操作的代码示例: ```c #include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node *next; }; struct Node* create_node(int data) { struct Node* new_node = (struct Node*) malloc(sizeof(struct Node)); new_node->data = data; new_node->next = NULL; return new_node; } void add_node(struct Node** head, int data) { struct Node* new_node = create_node(data); if (*head == NULL) { *head = new_node; return; } struct Node* current_node = *head; while (current_node->next != NULL) { current_node = current_node->next; } current_node->next = new_node; } void delete_node(struct Node** head, int data) { struct Node* current_node = *head; struct Node* prev_node = NULL; while (current_node != NULL && current_node->data != data) { prev_node = current_node; current_node = current_node->next; } if (current_node == NULL) { return; } if (prev_node == NULL) { *head = current_node->next; } else { prev_node->next = current_node->next; } free(current_node); } void print_list(struct Node* head) { struct Node* current_node = head; while (current_node != NULL) { printf("%d ", current_node->data); current_node = current_node->next; } printf("\n"); } int main() { struct Node* head = NULL; add_node(&head, 5); add_node(&head, 10); add_node(&head, 15); add_node(&head, 20); print_list(head); delete_node(&head, 15); print_list(head); delete_node(&head, 5); print_list(head); return 0; } ``` 以上是一个简单的链表实现,包括了节点创建、添加、删除以及遍历链表并打印数据的操作。请注意,这只是一个示例代码,实际应用时需要根据具体问题进行适当的修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值