常见算法题
- 1.单链表反转
- 2.链表中环的检测
- 3.两个有序的链表的合并
- 4.删除链表倒数第n个结点
- 5.求链表的中间结点
package example.com.Algorithm;
import org.junit.Test;
/**
* ================================================
* 作 者:zhoujianan
* 版 本:v1.0
* 创建日期:2020/5/27
* 描 述:
* 修订历史:
* ================================================
*/
public class LinkList {
public static class Node {
Node next;
int data;
public Node(int data) {
this.data = data;
}
}
public static Node printNode(Node node) {
if (node != null && node.next == null) {
System.out.print(node.data);
System.out.println("");
return null;
}
System.out.print(node.data + " => ");
return printNode(node.next);
}
/**
*
* @param index 数值的下标
* @param n 创建node的个数
* @param isOrder 是否是正序
* @return
*/
public Node createNodeList(int index, int n, boolean isOrder){
if (n <= 0) {
return null;
}
Node node = new Node(index);
if (isOrder) {
node.next = createNodeList(++index, --n, isOrder);
}else {
node.next = createNodeList(--index, --n, isOrder);
}
return node;
}
/************************************* 单链表的反转 ****************************************/
public Node reverse(Node node) {
Node cur = node;
Node pre = null;
while (cur != null) {
Node next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
@Test
public void reverseTest() {
Node node1 = createNodeList(1, 5,true);
printNode(node1);
Node reverse = reverse(node1);
System.out.println("\n");
printNode(reverse);
}
/************************************* 链表中环的检测 ****************************************/
public boolean checkCircle(Node list) {
if (list == null) {
return false;
}
Node fast = list.next;
Node slow = list;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (fast == slow) {
return true;
}
}
return false;
}
@Test
public void checkCircleTest() {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node2;
boolean isExitCircle = checkCircle(node1);
System.out.println("isExitCircle "+ isExitCircle);
}
/************************************* 两个升序或者降序的链表的合并 ****************************************/
@Test
public void mergeOrderLinkListTest( ) {
Node list1 = createNodeList(4, 11,true);
Node list2 = createNodeList(0, 5,true);
printNode(list1);
printNode(list2);
Node mergeNode = mergeLinkList(list1, list2);
printNode(mergeNode);
}
//递归方式 合并从大到小的数据
public Node mergeLinkList(Node l1, Node l2) {
Node soldier = new Node(0); //利用哨兵结点简化实现难度
Node p = soldier;
while ( l1 != null && l2 != null ){
if (l1.data < l2.data) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
if (l1 != null) { p.next = l1; }
if (l2 != null) { p.next = l2; }
return soldier.next;
}
/************************************* 删除链表中倒数第n个节点 ****************************************/
@Test
public void deleteCuntDownNodeTest() {
Node node1 = createNodeList(10,10,false);
printNode(node1);
Node node = deleteCuntDownNodeStandard(node1, 9);
printNode(node);
}
public Node deleteCuntDownNodeStandard(Node list, int k) {
int i = 1;
Node fast = list;
while (fast != null && i < k) {
fast = fast.next;
++i;
}
if (fast == null) {
return fast;
}
Node slow = list;
Node prev = null;
while (fast.next != null) {
fast = fast.next;
prev = slow;
slow = slow.next;
}
if (prev == null) {
list = list.next;
}else {
prev.next = prev.next.next;
}
return list;
}
public Node deleteCountDownNodeByMyself(Node node, int n) {
if (n < 0) {
System.out.println("删除节点不合法");
return null;
}
if (node == null) {
System.out.println("node == null");
return null;
}
int count = 0;
Node a = node;
while (node != null) {
node = node.next;
count++;
}
if (n > count) {
System.out.println("查找超出下标");
return null;
}
int deleteIndex = count - n;
count = 0;
Node pre;
node = a;
while (node != null) {
if (deleteIndex == 0) {
return a.next;
}
pre = node;
count++;
if (count == deleteIndex) {
pre.next = node.next.next;
return a;
}
node = node.next;
}
return a;
}
/************************************* 求链表的中间节点 ****************************************/
@Test
public void findMiddleNodeTest() {
Node node = createNodeList(10,10,true);
printNode(node);
Node middleNode = findMiddleNode(node);
System.out.println("findMiddleNodeTest: " + middleNode.data);
}
public Node findMiddleNode(Node list) {
if (list == null) {
return list;
}
Node fast = list;
Node slow = list;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
public Node findMiddleNodeBySelf(Node node) {
int count = 0;
Node n = node;
while (n != null) {
n = n.next;
count++;
}
int middle = count / 2;
System.out.println("middle: " + middle);
int i = 0;
Node m = node;
while (m != null) {
i++;
if (i == middle) {
return m;
}
m = m.next;
}
return null;
}
}