链表简单介绍

本文详细讲解了单双向链表的反转方法,并提供了一个查找两个有序链表公共部分的高效算法,注重时间复杂性和空间效率。

单链表

节点结构

Class Node<V>{ 
	V value; 
	Node next;
}

双链表

节点结构

Class Node<V>{ 
	V value; 
	Node next; Node last;
}

如果牵扯到换头的操作,要有返回值,因为head=f(head)。如果没有就不需要返回值。

反转单向链表和双向链表

【题目】 分别实现反转单向链表和反转双向链表的函数
【要求】 如果链表长度为N,时间复杂度要求为O(N),额外空间复杂度要求为O(1)

单向链表

	public static class Node {
		public int value;
		public Node next;

		public Node(int data) {
			this.value = data;
		}
	}

	public static Node reverseList(Node head) {
		Node pre = null;
		Node next = null;
		while (head != null) {
			next = head.next;
			head.next = pre;
			pre = head;
			head = next;
		}
		return pre;
	}

双向链表 

	public static class DoubleNode {
		public int value;
		public DoubleNode last;
		public DoubleNode next;

		public DoubleNode(int data) {
			this.value = data;
		}
	}

	public static DoubleNode reverseList(DoubleNode head) {
		DoubleNode pre = null;
		DoubleNode next = null;
		while (head != null) {
			next = head.next;
			head.next = pre;
			head.last = next;
			pre = head;
			head = next;
		}
		return pre;
	}

打印两个有序链表的公共部分
【题目】 给定两个有序链表的头指针head1和head2,打印两个链表的公共部分。
【要求】 如果两个链表的长度之和为N,时间复杂度要求为O(N),额外空间复
杂度要求为O(1)

思路:双指针,两个指针指着两个链表,谁的值小谁移动,相等共同移动,谁小谁移动,有一个越界就停。

	public static class Node {
		public int value;
		public Node next;
		public Node(int data) {
			this.value = data;
		}
	}

	public static void printCommonPart(Node head1, Node head2) {
		while (head1 != null && head2 != null) {
			if (head1.value < head2.value) {
				head1 = head1.next;
			} else if (head1.value > head2.value) {
				head2 = head2.next;
			} else {
				System.out.print(head1.value + " ");
				head1 = head1.next;
				head2 = head2.next;
			}
		}
	}

### Java链表的数据结构介绍及使用方法 #### 1. 链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含两个部分:数据域和指针域。数据域用于存储数据元素,指针域用于指向下一个节点。链表的节点在内存中可以是不连续的,通过指针将节点串联起来。与数组相比,链表在插入和删除操作上效率更高,因为不需要移动大量元素。 #### 2. 单链表的定义与实现 单链表是最基本的链表形式,每个节点只包含一个指向下一个节点的指针。在 Java 中,可以通过定义一个节点类来实现单链表,例如: ```java class ListNode { int val; ListNode next; ListNode(int val) { this.val = val; this.next = null; } } ``` 该类定义了一个整型数据元素 `val` 和一个指向下一个节点的引用 `next`。通过该类可以构建一个简单的单链表结构 [^1]。 #### 3. 双向链表的实现 双向链表是一种更复杂的链表形式,每个节点包含两个指针,一个指向前一个节点,另一个指向后一个节点。这样可以实现双向遍历。例如,在 Java 中,双向链表的构造方法可以如下所示: ```java public class TwoWayLinkList { private Node head; private Node last; private int N; public TwoWayLinkList() { this.head = new Node(null, null, null); this.last = null; this.N = 0; } } ``` 该构造方法初始化了头节点和尾节点,并将链表的长度设置为 0 [^2]。 #### 4. 链表的基本操作 链表支持多种基本操作,包括插入、删除、查找等。以插入操作为例,可以在指定索引位置插入一个新节点: ```java public void addIndex(int index, int data) { if (index < 0 || index > size()) { throw new ListIndexOutOfBoundsException("链表的index位置不合法"); } if (index == 0) { addFirst(data); return; } if (index == size()) { addLast(data); return; } ListNode node = new ListNode(data); ListNode cur = findIndex(index); node.next = cur; cur.prev.next = node; node.prev = cur.prev; cur.prev = node; } ``` 该方法首先检查索引的合法性,然后根据索引位置选择插入方式。如果索引为 0,则调用 `addFirst` 方法进行头插入;如果索引等于链表长度,则调用 `addLast` 方法进行尾插入;否则,在指定位置插入新节点 [^3]。 #### 5. 链表的合并操作 链表可以进行合并操作,将两个链表合并为一个新的链表。例如,以下代码展示了如何将两个链表合并为一个有序链表: ```java public ListNode mergeTwoLists(ListNode hb) { ListNode ha = this.head; ListNode headNew = new ListNode(555); ListNode tmpH = headNew; while (ha != null && hb != null) { if (ha.val <= hb.val) { tmpH.next = ha; tmpH = tmpH.next; ha = ha.next; } else { tmpH.next = hb; tmpH = tmpH.next; hb = hb.next; } } if (ha != null) { tmpH.next = ha; } if (hb != null) { tmpH.next = hb; } return headNew.next; } ``` 该方法通过遍历两个链表,比较节点值的大小,将较小的节点添加到新链表中,直到其中一个链表被遍历完,然后将剩余部分直接添加到新链表中 [^4]。 #### 6. 链表操作的封装与复用 为了提高代码的复用性,可以使用接口来封装链表的基本操作。例如,定义一个接口,包含 `addFirst`、`addLast` 等方法,然后在具体的链表类中实现这些方法。这样可以避免重复代码,并提高代码的可维护性 [^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值