链表的应用

链表的面试题

  1. 获取链表中的有效元素个数
  2. 获取链表中倒数第k个元素
  3. 反转链表
  4. 反向遍历链表
  5. 合并两个有序链表
package com.sratct.linkListArray;

import javax.lang.model.element.VariableElement;
import java.util.Stack;

public class LinkList {
    public static void main(String[] args) {
        Node nodeA = new Node(1, "aaa", "AAA");
        Node nodeB = new Node(5, "bbb", "BBB");
        Node nodeC = new Node(8, "ccc", "CCC");
        ListArray listArray = new ListArray();
        listArray.insert(nodeA);
        listArray.insert(nodeB);
        listArray.insert(nodeC);
        Node nodeD = new Node(2, "ddd", "DDD");
        Node nodeE = new Node(5, "eee", "EEE");
        Node nodeF = new Node(9, "fff", "FFF");
        Node nodeG = new Node(10, "ggg", "GGG");
        ListArray listArray1 = new ListArray();
        listArray1.insert(nodeD);
        listArray1.insert(nodeE);
        listArray1.insert(nodeF);
        listArray1.insert(nodeG);
        System.out.println(listArray.mergerList(listArray.getHead(),listArray1.getHead()));
        //  listArray.add(nodeA);
        //    listArray.add(nodeC);
        //     listArray.getList();
//       listArray.delete(nodeC);
//        System.out.println("-------");
//        listArray.update(nodeC);
//        System.out.println("-------");
//        System.out.println(listArray.getNum(listArray.getHead()));

        //  System.out.println(listArray.getNode(listArray.getHead(),1));
      //  System.out.println(listArray.reverseLinkList(listArray.getHead()));

     //   listArray.reversePrint(listArray.getHead());
    }
}


class ListArray {
    // 初始化一个链表,头节点
    private Node head = new Node(0, "", "");

    // 得到头节点
    public Node getHead() {
        return head;
    }

    // 链表中插入元素
    public void insert(Node node) {
        Node temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = node;
    }

    // 遍历链表中元素
    public void getList() {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        Node temp = head;
        while (temp.next != null) {
            System.out.println(temp.next);
            temp = temp.next;
        }
    }

    /**
     * 在指定位置插入元素
     *
     * @param node
     */
    public void add(Node node) {
        Node temp = head;
//         for (int i=0; i<=index-1; i++) {
//             temp =temp.next;
//         }
//         node.next = temp.next;
//         temp.next = node;
        boolean flag = false;
        while (true) {
            if (temp.next == null) { // 到尾了,直接插入
                break;
            } else if (temp.next.no > node.no) {
                break;
            } else if (temp.next.no == node.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            System.out.println("节点已存在");
        } else {
            node.next = temp.next;
            temp.next = node;
        }
    }

    /**
     * 修改链表
     *
     * @param node
     */
    public void update(Node node) {
        if (head.next == null) {
            System.out.println("链表为空");
        }
        Node temp = head.next;

        while (temp.no != node.no) {
            if (temp == null) {
                System.out.println("未找到元素");
                return;
            }
            temp = temp.next;
        }
        temp.bName = node.bName;
        temp.name = node.name;
    }

    /**
     * 删除链表
     */

    public void delete(Node node) {
        Node temp = head;

        while (temp.next != node) {
            if (temp.next == null) {
                System.out.println("未找到");
                return;
            }
            temp = temp.next;
        }
        Node nextNode = temp.next;
        temp.next = nextNode.next;
    }

    /**
     * 求链表的有效节点个数,不算头节点
     */
    public int getNum(Node head) {
        if (head.next == null) {
            return 0;
        }
        Node temp = head.next;
        int length = 0;
        while (temp != null) {
            length++;
            temp = temp.next;
        }
        return length;
    }

    /**
     * 查找单链表中倒数第k个节点
     */
    public Node getNode(Node head, int k) {
        if (head.next == null) {
            return null;
        }
        Node temp = head.next;
        int sum = 0;
        while (temp != null) {
            sum++;
            temp = temp.next;
        }
        Node temp1 = head.next;
        int index = sum - k;  //正数第index个元素
        for (int i = 0; i < index; i++) {
            temp1 = temp1.next;
        }
        return temp1;
    }

    /**
     * 链表的反转
     * 使用辅助链表完成
     * 遍历原链表将将每一个节点插入到辅助链表的第一个位置
     */
    public Node reverseLinkList(Node head) {
        if (head.next == null || head.next.next == null) {
            return head;
        }
        Node temp = head.next;
        Node nextNode = null;  //指向当前节点的下一个节点
        Node reverseArr = new Node(0, "", "");

        while (temp != null) {
            nextNode = temp.next; // 当前节点的下一个节点保存到nextNode中
            temp.next = reverseArr.next;  // 插入到辅助链表的头
            reverseArr.next = temp;
            temp = nextNode;   // temp后移
        }
        head.next = reverseArr.next;
        return head.next;
    }

    /**
     *  链表逆序打印
     *  使用栈的方式
     */
    public void reversePrint(Node head) {
        if (head.next ==null) {
            System.out.println("链表为null");
            return;
        }
        Node temp = head.next;
        Stack<Node> nodeStack = new Stack<>();
        while (temp != null) {
            nodeStack.push(temp);
            temp = temp.next;
        }

        while (nodeStack.size() >0) {
            System.out.println(nodeStack.pop());
        }
    }

    /**
     * 两个有序单链表合并
     */
    public Node mergerList(Node list1,Node list2) {
        if (list1.next ==null && list2.next ==null) {
            return null;
        }
        if (list1.next == null) {
            return list2;
        }
        if (list2 == null) {
            return list1;
        }
        Node temp1 = list1.next;
        Node temp2 = list2.next;
        // 合并后的链表
        Node newNode = new Node(0,"","");
        Node newTemp = newNode;
        // 当两个链表都不为null时
        while (temp1!=null && temp2 != null) {
            if (temp1.no > temp2.no) {
                // 如果链表1的节点大于链表2节点,将链表2节点给插入新链表的尾部
                 newTemp.next = temp2;
                 temp2 = temp2.next;  // 后移
                 newTemp = newTemp.next; // 后移

            } else{
               // 如果链表2的节点大于链表1节点,将链表1节点给插入新链表的尾部
                newTemp.next = temp1;
                temp1 = temp1.next;
                newTemp = newTemp.next;
            }
        }
        
        /**
        循环完后,如果链表1为null那么将链表2的剩余节点直接插入到新链表的尾部,同理,
        若链表2为null则将链表1剩余的节点插入到新链表中
        */
        if (temp1 == null) {
            newTemp.next = temp2;
        } else {
            newTemp.next = temp1;
        }

        return newNode.next;
    }
}


/**
 * 创建节点Node
 */
class Node {
    public int no;
    public String name;
    public String bName;
    public Node next;

    public Node(int no, String name, String bName) {
        this.no = no;
        this.name = name;
        this.bName = bName;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", bName='" + bName + '\'' +
                '}';
    }
}


posted @ 2021-04-08 20:39  撑起一片阳光  阅读(166)  评论(0编辑  收藏  举报