JAVA处理链表经典问题
- 定义链表节点Node
class Node { private int Data;// 数据域 private Node Next;// 指针域 public Node(int Data) { // super(); this.Data = Data; }
get/set方法省略
}
- 创建链表数据
public static Node getNode() { Node head = new Node(0); Node node1 = new Node(1); Node node2 = new Node(2); Node node3 = new Node(3); Node node4 = new Node(4); head.setNext(node1); node1.setNext(node2); node2.setNext(node3); node3.setNext(node4); node4.setNext(node2); return head; }
- 判断单向链表是否有环 采用快慢步长法。令两个指针p和q分别指向头结点,p每次前进一步,q每次前进两步,如果p和q能重合,则有环。可以这么理解,这种做法相当于p静止不动,q每次前进一步,所有肯定有追上p的时候
// 判断链表是否有环 public static boolean loop(Node head) { Node slow = head; Node fast = head; // 如果链表为空或者只有一个节点当作链表有环 while (slow != null && slow.getNext() != null) { slow = slow.getNext(); fast = fast.getNext().getNext(); if (slow == fast) { return true; } } return false; }
2.翻转链表
/** * 递归,在反转当前节点之前先反转后续节点 */ public static Node Reverse1(Node head) { // head看作是前一结点,head.getNext()是当前结点,reHead是反转后新链表的头结点 if (head == null || head.getNext() == null) { return head;// 若为空链或者当前结点在尾结点,则直接还回 } Node reHead = Reverse1(head.getNext());// 先反转后续节点head.getNext() head.getNext().setNext(head);// 将当前结点的指针域指向前一结点 head.setNext(null);// 前一结点的指针域令为null; return reHead;// 反转后新链表的头结点 }
3.求单向链表(有环)求环的入口
// 从碰撞点 x 前进 a 步即为连接点。 从 x 点和从起点同步前进,第一个碰撞点就是连接点。 public static Node findLoopPort(Node head) { Node slow = head; Node fast = head; while (slow != null && slow.getNext() != null) { slow = slow.getNext(); fast = fast.getNext().getNext(); if (slow == fast) { break; } } if (slow == null || slow.getNext() == null) { return null; } fast = head; while (slow != fast) { slow = slow.getNext(); fast = fast.getNext(); } System.out.println("环的连接点是" + slow.getData()); return slow; }