链表_数据结构

常见算法题

  • 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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值