package Java_Interview_Book;
import java.util.Hashtable;
class Node{
Node next = null;
int data;
public Node(int data ) {
this.data = data;
}
}
public class LinkList_book {
static Node head = null;
/**
*
* @return 返回结点长度
*/
public static int length() {
int length = 0;
Node tmp = head;
while(tmp != null) {
length++;
tmp = tmp.next;
}
return length;
}
/* *
* @param d :插入的数据插到表尾
*/
public void addNode(int d) {
Node newNode = new Node(d);
if(head == null) {
head = newNode;
return;
}
Node tmp = head;
while(tmp.next != null) {
tmp = tmp.next;
}
tmp.next = newNode;
}
/**
*
* @param index:删除第index个结点
* @return 成功返回true,失败返回false
*/
public static boolean deleteNode(int index) {
if(index < 1 || index > length()) {
return false;
}
if(index == 1) {
head = head.next;
return true;
}
int i = 2;
Node preNode = head;
Node curNode = preNode.next;
while(curNode != null ) {
if(i == index) {
preNode.next = curNode.next;
return true;
}
preNode =curNode;
curNode = curNode.next;
i++;
}
return true;
}
/**
*
* 对链表进行排序
* 输出排序后的头结点
*/
public Node orderList() {
int temp = 0;
Node curNode = head ;
Node nextNode = null;
while(curNode != null) {
nextNode = curNode.next;
while(nextNode != null ) {
if(curNode.data > nextNode.data) {
temp = curNode.data;
curNode.data = nextNode.data;
nextNode.data = temp;
}
nextNode =nextNode.next;
}
curNode = curNode.next;
}
return head;
}
public void printList() {
Node tmp = head;
while(tmp != null) {
System.out.println(tmp.data);
tmp = tmp.next;
}
}
/**
* 从链表中删除重复数据,需要额外空间
* @param head 头结点
*/
public void deleteDuplecate1(Node head) {
Hashtable< Integer, Integer> table = new Hashtable<Integer,Integer>();
Node tmp = head;
Node pre = null;
while (tmp != null) {
if (table.containsKey(tmp.data)) {
pre.next = tmp.next;
}else {
table.put(tmp.data,1);
pre = tmp ;
}
tmp = tmp.next;
}
}
/**
* 不需要额外存储空间
* @param head
*/
public void deleteDuplecate2(Node head) {
Node p = head;
while (p != null) {
Node q = p;
while(q.next != null) {
if (p.data == q.next.data) {
q.next = q.next.next;
}else {
q = q.next;
}
}
p = p.next;
}
}
/**
* 找到单链表中倒数第k个元素
* @param head
* @param k
* @return
*/
public Node findElem(Node head,int k) {
if(k < 1) {
return null;
}
Node p1 = head;
Node p2 = head;
for (int i = 0; i < k-1 && p1 != null; i++) {
p1 = p1.next;
if (p1 == null) {
System.out.println("k不合法");
return null;
}
}
while (p1.next != null) {
p1 = p1.next;
p2 = p2.next;
}
return p2;
}
/**
* 从尾到头输出单链表
* @param pListHead
*/
public void printListReversly(Node pListHead) {
if(pListHead != null) {
printListReversly(pListHead.next);
System.out.println(pListHead.data);
}
}
/**
* 寻找单链表中间结点
* @param head
* @return
*/
public static Node searchMiddleNode(Node head) {
//使用快慢指针,快指针走两步,满指针走一步
Node fastNode = head;
Node slowNode = head;
while(fastNode!=null && fastNode.next!=null && fastNode.next.next!=null) {
fastNode = fastNode.next.next;
slowNode = slowNode.next;
}
return slowNode;
}
/**
* 检测一个链表是否有环
* @param head
* @return
*/
public static boolean hasLoop(Node head) {
//快慢指针,如果快慢指针相遇的话,则有,否则快指针到尾部的话,还没相遇则是无环
Node fastNode = head;
Node slowNode = head;
if(fastNode == null) {
return false;
}
while(fastNode != null && fastNode.next != null) {
fastNode = fastNode.next.next;
slowNode = slowNode.next;
if(fastNode == slowNode) {
return true;
}
}
return !(fastNode == null || fastNode.next == null);
}
/**
* 找到环的入口
* @param head
* @return
* 设环长为r,满指针走了s步,快指针比满指针多走了n圈
* 2s=s+nr;
* 设整个链表长L,入口到相遇点距离为X,起点到换入口为a;
* a=(n-1)r+(L-a-x);
* 在链表头和,相遇点各设一个指针,每次走一步,则必定相遇
*/
public static Node FindLoopPort(Node head) {
//快慢指针初始化
Node fastNode = head;
Node slowNode = head;
while(fastNode != null && fastNode.next != null) {
fastNode = fastNode.next.next;
slowNode = slowNode.next;
if(fastNode == slowNode) {
break;
}
}
//判断到结尾了,还没有环
if(fastNode == null || fastNode.next == null) {
return null;
}
slowNode = head;
while(slowNode != fastNode) {
fastNode = fastNode.next;
slowNode = slowNode.next;
}
return slowNode;
}
/**
* 在不知道头指针情况下删除指定结点
* @param n
* @return
* 如果删除的是尾结点,无法删除,因为删除后无法使其前驱结点的next指针置为空;
* 不是尾结点,通过交换这个结点与其后继结点的值,然后删除后继结点。
*/
public static boolean deleteNode(Node n) {
if(n == null || n.next == null) {
return false;
}
//将n结点和n+1结点的值交换
int temp = n.data;
n.data=n.next.data;
n.next.data =temp;
//删除第n+1个结点
n.next =n.next.next;
return true;
}
/**
* 判断两个链表是否相交
* @param h1
* @param h2
* @return
* 复杂度两个链表相加长度
*/
public static boolean isIntersect(Node h1,Node h2) {
//如果两条链有一条为空,则不相交
if(h1 == null || h2 == null) {
return false;
}
//遍历两个链表,如果尾节点相同,两个链表肯定相交
//找到两个链表尾节点
Node tail1 = h1;
while(tail1.next!=null) {
tail1 = tail1.next;
}
Node tail2 = h2;
while(tail2.next!=null) {
tail2 = tail2.next;
}
return tail1 ==tail2;
}
/**
* 找到两个相交链表的第一个节点
* @param h1
* @param h2
* @return
*/
public static Node getFirstMeetNode(Node h1,Node h2) {
//如果两个链表相交的话,才去找节点
//需要统计两个链表长度,让较长的链表指针先走(链表长度差),然后两个链表指针一起走
//先判断是否相交
//如果两条链有一条为空,则不相交
if(h1 == null || h2 == null) {
return null;
}
//遍历两个链表,如果尾节点相同,两个链表肯定相交
//找到两个链表尾节点
int length1=0;
int length2=0;
Node tail1 = h1;
while(tail1.next!=null) {
tail1 = tail1.next;
length1++;
}
Node tail2 = h2;
while(tail2.next!=null) {
tail2 = tail2.next;
length2++;
}
//不想交则返回空指针
if(tail1 !=tail2) {
return null;
}
//两个指针重新指向链表头,不想重新开辟新结点了,累
tail1 =h1;
tail2 =h2;
if(length1>length2) {
int difference = length1-length2;
while(difference!=0) {
tail1 =tail1.next;
difference--;
}
}else {
int difference = length2-length1;
while(difference!=0) {
tail2 =tail2.next;
difference--;
}
}
//两个指针同时移动
while(tail1 != tail2) {
tail1 =tail1.next;
tail2 =tail2.next;
}
return tail1;
}
public static void main(String[] args) {
LinkList_book list = new LinkList_book();
// System.out.println("----add----");
list.addNode(5);
list.addNode(1);
list.addNode(2);
list.addNode(3);
list.addNode(2);
// list.printList();
// System.out.println("Listlength:" + list.length());
// System.out.println("---delete---");
// list.deleteNode(2);
// list.printList();
// System.out.println("----order----");
// System.out.println("Before");
// list.printList();
// System.out.println("After");
// list.orderList();
// list.printList();
// System.out.println("----deleteDuplecate----");
// Node head =list.head;
// list.deleteDuplecate1(head);
// list.deleteDuplecate2(head);
// list.printList();
// System.out.println("----findElemBackwardsNumberK----");
// Node head =list.head;
// int k = 2;
// Node temp = list.findElem(head, k);
// System.out.println(temp.data);
// System.out.println("---- printListReversly----");
// Node head =list.head;
// list.printListReversly(head);
// System.out.println("---- searchMiddleNode----");
// Node head = list.head;
// Node temp = list.searchMiddleNode(head);
// System.out.println(temp.data);
// System.out.println("---- hasLoop----");
// Node head =list.head;
// boolean result = list.hasLoop(head);
// System.out.println(result);
// System.out.println("---- hasLoop+FindLoopPort----");
// Node head1 = new Node(5);
// Node node2 = new Node(3);
// Node node3 = new Node(1);
// Node node4 = new Node(2);
// Node node5 = new Node(7);
// Node tail1 = new Node(6);
// head1.next = node2;
// node2.next = node3;
// node3.next = node4;
// node4.next = node5;
// node5.next = tail1;
// tail1.next = node3;
// boolean result = hasLoop(head1);
// System.out.println(result);
// Node temp = FindLoopPort(head1);
// System.out.println(temp.data);
// System.out.println("---- 在不知道头指针情况下删除指定结点----");
// Node head1 = new Node(5);
// Node node2 = new Node(3);
// Node node3 = new Node(1);
// Node node4 = new Node(2);
// Node node5 = new Node(7);
// Node tail1 = new Node(6);
// head1.next = node2;
// node2.next = node3;
// node3.next = node4;
// node4.next = node5;
// node5.next = tail1;
// tail1.next = null;
// boolean result = deleteNode(4);
// System.out.println(result);
// Node temp = head1;
// while (temp.next!=null) {
// System.out.println(temp.data);
// temp = temp.next;
// }
// System.out.println("---- isIntersect----");
// Node head1 = new Node(5);
// Node node2 = new Node(3);
// Node node3 = new Node(1);
// Node node4 = new Node(2);
// Node node5 = new Node(7);
// Node tail1 = new Node(6);
// head1.next = node2;
// node2.next = node3;
// node3.next = node4;
// node4.next = node5;
// node5.next = tail1;
// tail1.next = null;
// Node head = list.head;
// boolean result1 = isIntersect(head, head1);
// System.out.println(result1);
// Node head11 = new Node(7);
// Node node21 = new Node(2);
// Node node31 = new Node(1);
// head11.next = node21;
// node21.next = node31;
// node31.next = node4;
// boolean result2 = isIntersect(head11, head1);
// System.out.println(result2);
// System.out.println("---- getFirstMeetNode----");
// Node temp = getFirstMeetNode(head11, head1);
// System.out.println(temp.data);
}
}