算法实现----链表(一)

本文深入探讨了链表的各种操作,包括打印两个有序链表的公共部分,删除单链表和双链表中倒数第K个节点,删除链表中间节点及特定位置节点,以及如何反转单向链表和双向链表,提供了丰富的代码实例。

打印两个有序链表的公共部分

要求:打印两个有序链表的公共部分
给定两个有序链表的头指针head1和head2,打印两个链表的公共部分

public class PrintCommon {

	public static void main(String[] args) {
		Node node1 = new Node(1);
		node1.next = new Node(5);
		node1.next.next = new Node(8);
		
		Node node2 = new Node(3);
		node2.next = new Node(5);
		node2.next.next = new Node(6);
		node2.next.next.next = new Node(8);
		
		printCommonPart(node1, node2);
	}
	/*要求:打印两个有序链表的公共部分
	 *    给定两个有序链表的头指针head1和head2,打印两个链表的公共部分
	 */
	public static void printCommonPart(Node head1,Node head2) {
		while(head1 != null && head2 != null) {
			if(head1.value == head2.value) {
				System.out.println(head1.value);
				head1 = head1.next;
				head2 = head2.next;
			}else if(head1.value > head2.value) {
				head2 = head2.next;
			}else {
				head1 = head1.next;
			}
		}
	}

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

在单链表和双链表中删除倒数第K个节点

要求:分别实现两个函数,一个可以删除单链表中倒数第K个节点,一个可以删除双链表中倒数第K个节点。
复杂度要求:时间复杂度O(n),空间复杂度O(1)

public class RemoveLastKthNode {
	
	/*要求:分别实现两个函数,一个可以删除单链表中倒数第K个节点,一个可以删除双链表中倒数第K个节点。
	 *		时间复杂度O(n),空间复杂度O(1) 
	 */
	public static void main(String[] args) {
		/*Node node1 = new Node(3);
		node1.next = new Node(5);
		node1.next.next = new Node(6);
		node1.next.next.next = new Node(8);
		Node newNode = removeLastKthNode(node1,4);
		while(newNode != null){
			System.out.println(newNode.value);
			newNode = newNode.next;
		}*/
		DoubleNode head = new DoubleNode(3);
		DoubleNode head2 = new DoubleNode(6);
		DoubleNode head3 = new DoubleNode(7);
		DoubleNode head4 = new DoubleNode(8);
		head.pre = null;
		head.next = head2;
		head2.pre = head;
		head2.next = head3;
		head3.pre = head2;
		head3.next = head4;
		head4.pre = head3;
		head4.next = null;
		DoubleNode newDoubleNode = removeLastKthDoubleNode(head,2);
		
	}
	
	public static Node removeLastKthNode(Node head,int k) {
		if(k < 1 || head == null ) {
			return head;
		}
		Node cur = head;
		while(cur != null) {
			cur = cur.next;
			k--;
		}
		if(k == 0) {
			return head.next;
		}else if(k < 0) {
			cur = head;
			k++;
			while(k != 0) {
				cur = cur.next;
				k++;
			}
			cur.next = cur.next.next;
		}
		
		return head;
	}
	
	public static DoubleNode removeLastKthDoubleNode(DoubleNode head,int k) {
		DoubleNode cur = head;
		while(cur != null) {
			cur = cur.next;
			k--;
		}
		if(k == 0) {
			head.next.pre = null;
			return head.next;
		}else if(k < 0) {
			cur = head;
			while(k != 0) {
				k++;
				cur = cur.next;
			}
			cur.pre.next = cur.next;
			if(cur.next != null) {
				cur.next.pre = cur.pre;
			}
		}
		return head;
	}
	
}

//单链表
class Node{
	public Node next;
	public int value;
	
	public Node(int value) {
		this.value = value;
	}
}
//双向链表
class DoubleNode{
	public DoubleNode next;
	public DoubleNode pre;
	public int value;
	
	public DoubleNode(int value) {
		this.value = value;
	}
}

删除链表的中间节点和a/b处的节点

public class RemoveMidNode {
	
	/*要求:
	 *   给定链表的头节点head,实现删除链表的中间节点的函数(偶数个数节点时,删除前一个节点)
	 * 例如:1>2     	 删除节点1
	 * 	   1>2>3             删除节点2
	 * 	   1>2>3>4       删除节点2
	 * 进阶问题:
	 *   给定链表的头节点head,整数a和整数b,实现删除位于a/b处节点的函数
	 * 例如:1>2>3>4>5,假设a/b的值为r
	 * 如果r为0,不删除任何节点;
	 * 如果r在区间(0,1/5]上,删除节点1;
	 * 如果r在区间(1/5,2/5]上,删除节点1;
	 * 如果r在区间(2/5,3/5]上,删除节点1;
	 * 如果r在区间(3/5,4/5]上,删除节点1;
	 * 如果r在区间(4/5,1]上,删除节点1;
	 * 如果r大于1,不删除任何节点。
	 * */
	public static void main(String[] args) {
		Node node1 = new Node(3);
		Node node2 = new Node(6);
		Node node3 = new Node(9);
		Node node4 = new Node(7);
		Node node5 = new Node(8);
		node1.next = node2;
		node2.next = node3;
		node3.next = node4;
		node4.next = node5;
		node5.next = null;
//		Node newNode = removeMidNode(node1);
		Node newNode = removeByRatio(node1, 3, 5);
		while(newNode != null) {
			System.out.println(newNode.value);
			newNode = newNode.next;
		}
	}
	public static Node removeMidNode(Node head) {
		if(head == null || head.next == null) {
			return head;
		}
		if(head.next.next == null) {
			return head.next;
		}
		Node slow = head;
		Node quick = head.next.next;
		while(quick.next != null && quick.next.next != null) {
			quick = quick.next.next;
			slow = slow.next;
		}
		slow.next = slow.next.next;
		return head;
	}
	public static Node removeByRatio(Node head, int a, int b) {
		if(a > b || a < 1 || head == null) {
			return head;
		}
		int count = 0;
		Node cur = head;
		while(cur != null) {
			count++;
			cur = cur.next;
		}
		
		int n = (int) Math.ceil((double)(count*a)/b);
		if(n == 1) {
			return head.next;
		}
		cur = head;
		while(n != 2) {
			cur = cur.next;
			n--;
		}
		cur.next = cur.next.next;
		return head;
	}

}

反转单向链表和双向链表

public class ReverseLinked {
	
	/*要求: 反转单向链表和双向链表,时间复杂度为O(N),空间复杂度为O(1)
	 */
	public static void main(String[] args) {
		/*Node node1 = new Node(3);
		Node node2 = new Node(6);
		Node node3 = new Node(9);
		Node node4 = new Node(7);
		Node node5 = new Node(8);
		node1.next = node2;
		node2.next = node3;
		node3.next = node4;
		node4.next = node5;
		node5.next = null;
		Node newNode = reverseLinked(node1);
		while(newNode != null){
			System.out.println(newNode.value);
			newNode = newNode.next;
		}*/
		
		DoubleNode head = new DoubleNode(3);
		DoubleNode head2 = new DoubleNode(6);
		DoubleNode head3 = new DoubleNode(7);
		DoubleNode head4 = new DoubleNode(8);
		head.pre = null;
		head.next = head2;
		head2.pre = head;
		head2.next = head3;
		head3.pre = head2;
		head3.next = head4;
		head4.pre = head3;
		head4.next = null;
		DoubleNode newDoubleNode = reverseDoubleLinked(head);
		
		while(newDoubleNode != null) {
			System.out.print(newDoubleNode.value );
			if(newDoubleNode.pre != null) {
				System.out.print("  pre:"+newDoubleNode.pre.value);
			}else {
				System.out.print("  pre:"+newDoubleNode.pre);
			}
			if(newDoubleNode.next != null) {
				System.out.print("  next:"+newDoubleNode.next.value);
			}else {
				System.out.print("  next:"+newDoubleNode.next);
			}
			newDoubleNode = newDoubleNode.next;
			System.out.println();
		}
		
	}
	
	//反转单向链表
	public static Node reverseLinked(Node head) {
		if(head == null || head.next == null) {
			return head;
		}
		Node pre = null;
		Node next = null;
		while(head != null){
			next = head.next;
			head.next = pre;
			pre = head;
			head = next;
		}
		return pre;
	}
	
	//反转双向链表
	public static DoubleNode reverseDoubleLinked(DoubleNode head) {
		if(head == null || head.next == null) {
			return head;
		}
		DoubleNode pre = null;
		DoubleNode next = null;
		while(head != null) {
			next = head.next;
			head.next = pre;
			head.pre = next;
			pre = head;
			head = next;
		}
		return pre;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值