单向链表增删改查

package LinkedList;

import java.util.Stack;

public class LinkedList {
    public static void main(String[] args) {
        Node node1=new Node(1,"111");
        Node node2=new Node(5,"555");
        Node node3=new Node(8,"888");
        Node node4=new Node(10,"101010");
        SingleLinkedList linkedList=new SingleLinkedList();
        linkedList.addNode(node1);
        linkedList.addNode(node2);
        linkedList.addNode(node3);
        linkedList.addNode(node4);
        System.out.println("第一个链表:");
        linkedList.showList(linkedList.head);

        Node node5=new Node(3,"333");
        Node node6=new Node(4,"444");
        Node node7=new Node(6,"666");
        Node node8=new Node(12,"121212");
        SingleLinkedList linkedList1=new SingleLinkedList();
        linkedList1.addNode(node5);
        linkedList1.addNode(node6);
        linkedList1.addNode(node7);
        linkedList1.addNode(node8);
        System.out.println("第二个链表:");
        linkedList1.showList(linkedList1.head);

        System.out.println("合并两个链表:");
        Node addListById = addListById(linkedList.getHead(), linkedList1.getHead());
        showList(addListById);


//        System.out.println("删除节点前----------------------");
//
//        System.out.println("逆序打印链表---------------------- ");
//        linkedList.rePrintList(linkedList.head);
//
//        System.out.println("反转链表--------------------------");
//        Node node = linkedList.reLinkedList(linkedList.head);
//        showList(node);
//
//        System.out.println("删除节点后----------------------");
//        linkedList.deleteNodeById(6);
//        linkedList.showList();
//        System.out.println("修改节点后-----------------------");
//        Node node=new Node(1,"123");
//        linkedList.updateNode(node);
//        linkedList.showList();
//        linkedList.getNodeById(1);
//        int count = linkedList.getCount();
//        System.out.println(count);
//        System.out.println(linkedList.findLastIndexNode(-1));

    }

    /**
     * 显示链表
     * @param head 链表头节点
     */
    public static void showList(Node head){
        if (head.next==null){
            System.out.println("链表为空,无法遍历");
        }else {
            Node temp=head.next;
            while (temp!=null){
                System.out.println("Node{id="+temp.id+",name="+temp.name+"}");
                temp=temp.next;
            }
        }
    }
    public static Node addListById(Node head1,Node head2){
        if (head1.next==null||head2.next==null){
            return null;
        }else if (head1.next!=null&&head2.next==null){
            return head1;
        }else if (head2.next!=null&&head1.next==null){
            return head2;
        }else{
            Node newNode=new Node(0,"");
            Node cur=newNode;
            Node temp1=head1.next;
            Node temp2=head2.next;
            while (temp1!=null&&temp2!=null){
                if (temp1.id<= temp2.id){
                    cur.next=temp1;
                    temp1=temp1.next;
                    cur=cur.next;
                }else {
                    cur.next=temp2;
                    temp2=temp2.next;
                    cur=cur.next;
                }
            }
            if (temp1!=null){
                cur.next=temp1;
                temp1=temp1.next;
                cur=cur.next;
            }
            if (temp2!=null){
                cur.next=temp2;
                temp2=temp2.next;
                cur=cur.next;
            }
            return newNode.next;
        }
    }
}
class SingleLinkedList{
    //先初始化一个头节点,头节点不要动,不要存放具体数值
    Node head =new Node(0,"");

    public Node getHead() {
        return head;
    }

    /**
     * 把元素添加到链表的最后
     * @param node
     */
    public void addNode(Node node){
        Node temp=head;
        while (true){
            if (temp.next==null){
                temp.next=node;
                break;
            }
            temp=temp.next;
        }
    }

    /**
     * 按照节点id顺序添加节点
     * 思路:
     *      按顺序添加节点,有三种情况
     *      1、链表为空,直接添加
     *      2、节点重复,无法添加
     *      3、找到合适添加节点的位置,添加节点
     *      先设置两个辅助节点,一个是指向头节点的first,一个是指向头节点的下一个节点的second
     *      利用这个两个辅助节点遍历链表,当second.id>node.id时,就是应该插入的位置
     *      这时候:first.next=node,node.next=second
     */
    public void addNodeById(Node node){
        Node first=head;
        Node second=head.next;
        //利用i来标记情况:i=1,表示节点重复,i=2,表示找到添加节点的位置
        int i=0;
        if (second==null){
            //说明链表为空,直接在添加
            first.next=node;
        }else {
            //说明链表不为空
            while (second!=null){
                if (second.id==node.id){
                    i=1;
                    break;
                }
                if (second.id> node.id){
                    i=2;
                    break;
                }
                first=first.next;
                second=second.next;
            }
            if (i==1){
                //说明id重复
                System.out.println("要添加的节点id已经存在,无法重复添加!");
            }else if (i==2){
                //找到合适的位置
                first.next=node;
                node.next=second;
            }else {
                //说明遍历完链表了,但是还没有找到合适的位置,直接在末尾添加
                first.next=node;
            }
        }
    }

    /**
     * 修改节点,修改节点的时候,id不能变,否则就是添加节点了
     * 分为三种情况:
     *      1、链表空,无法修改
     *      2、找不到id号,无法修改
     *      3、找到id号,成功修改
     * @param node
     */
    public void updateNode(Node node){
        Node temp=head.next;
        //用来标识是否找到需要修改的节点,false代表没有找到,true代表找到了,默认为false
        boolean flag=false;
        if (temp==null){
            //说明链表为空,无法修改
            System.out.println("链表为空,无法修改");
        }else {
            //说明链表不为空,需要遍历链表
            while (temp!=null){
                if (temp.id==node.id){
                    flag=true;
                    break;
                }
                temp=temp.next;
            }
            //遍历结束后判断是否找到需要修改的节点
            if (flag){
                temp.name=node.name;
            }else {
                //说明没有找到
                System.out.println("没有找到需要修改的节点!");
            }
        }
    }

    /**
     * 根据id号查询节点信息
     * 分为三种情况:
     *      1、链表为空,无法获取
     *      2、没有这个id号,无法获取
     *      3、找到这个id号,返回节点
     */
    public void getNodeById(int id){
        Node temp=head.next;
        //false表示没有找到这个id,true代表已找到
        boolean flag=false;
        if (temp==null){
            System.out.println("链表为空,无法获取");
        }else {
            while (temp!=null){
                if (temp.id==id){
                    flag=true;
                    break;
                }
                temp=temp.next;
            }
            if (flag){
                //说明找到了
                System.out.println("查找的节点为:node{id="+temp.id+",name="+temp.name+"}");
            }else {
                //说明没有找到
                System.out.println("链表中没有需要查询的数据!");
            }
        }
    }

    /**
     * 根据节点id删除节点,删除节点时需要找到待删除节点的前一个位置,所有是temp.next!=null
     * 分为三种情况:
     *      1、链表为空,无法删除
     *      2、找打不到需要删除的id,无法删除
     *      3、找打需要删除的id,删除节点
     */
    public void deleteNodeById(int id){
        Node temp= head;
        boolean flag=false;
        if (temp.next==null){
            System.out.println("链表为空,无法删除节点!");
        }else {
            //链表不为空,可以删除节点
            while (temp.next!=null){
                if (temp.next.id==id){
                    //说明找到了
                    flag=true;
                    break;
                }
                temp=temp.next;
            }
            if (flag){
                temp.next=temp.next.next;
                System.out.println("删除成功!");
            }else {
                System.out.println("没有找到需要删除的节点,无法删除");
            }
        }
    }

    /**
     * 显示列表
     * @param head 列表的头节点
     */
    public void showList(Node head){
        Node temp=head.next;
        if (temp==null){
            System.out.println("链表为空,无法遍历!");
        }
        while (true){
            if (temp==null){
                break;
            }
            System.out.println("Node{id="+temp.id+",name="+temp.name+"}");
            temp=temp.next;
        }
    }

    /**
     * 返回链表的有效个数,不统计头节点,因为头节点没有数据
     * @return
     */
    public int getCount(){
        Node temp=head.next;
        int ans=0;
        while (temp!=null){
            ans++;
            temp=temp.next;
        }
        return ans;
    }

    /**
     * 查找单链表中的倒数第k个节点
     * @param k
     * @return
     */
    public Node findLastIndexNode(int k){
        int count=0;
        Node temp=head.next;
        while (temp!=null){
            count++;
            temp=temp.next;
        }
        Node cur=head;
        //查找倒数第k个节点,就是正数第count-k+1个
        //如果头节点是有数据的,那么就是count-k次循环
        //对k做一个校验,k不能大于count,也不能小于1
        if (k>count||k<1){
            //k是不能大于count的
            return null;
        }else {
            for (int i = 0; i < count-k+1; i++) {
                cur=cur.next;
            }
            return cur;
        }
    }

    /**
     * 反转链表
     * 思路:先创建一个反转链表的头节点 Node re,然后在利用两个辅助节点遍历链表 Node cur = head.next ,Node next=null
     *      先将cur的下一个节点保存:next=cur.next,方便遍历
     *      然后再将re.next付给cur.next,在将re.next连向cur
     *      这里需要看成指向,而不是赋值
     *      (先把我的给你,在把你的给我)
     * @param head
     * @return
     */
    public Node reLinkedList(Node head){
        if (head.next==null||head.next.next==null){
            return head;
        }
        Node cur=head.next;
        Node next=null;
        Node re=new Node(0,"");
        while (cur!=null){
            next=cur.next;
            cur.next=re.next;
            re.next=cur;
            cur=next;
        }
        head.next=re.next;
        return head;
    }

    /**
     * 从尾到头打印链表
     * 1、先将链表反转,在打印,这样做的问题是会将链表的结构破坏
     * 2、先遍历链表,将链表放入一个栈,然后在弹出栈
     */
    public void rePrintList(Node head){
        if (head.next==null){
            //链表为空
            System.out.println("链表为空,无法逆序打印!");
        }else {
        //链表不为空
            Stack<Node> stack=new Stack<Node>();
            Node temp=head.next;
            //遍历链表
            while (temp!=null){
                //将链表入栈
                stack.add(temp);
                temp=temp.next;
            }
            //出栈
            while (stack.size()>0){
                System.out.println(stack.pop());
            }
        }
    }
}
class Node{
    int id;
    String name;
    Node next;

    public Node() {
    }

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

    public Node(Node next) {
        this.next = next;
    }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值