单链表

package com.asia.dome1;

import java.util.Stack;

/**
 * @author asia
 * @date 2019/12/22
 * @describe:
 */
public class SingleLinkedListDome {
    public static void main(String[] args) {
        HeroNode node1 = new HeroNode(1, "宋江", "及时与");
        HeroNode node2 = new HeroNode(2, "林冲", "豹子头");
        HeroNode node3 = new HeroNode(3, "吴用", "智多星");
        HeroNode node4 = new HeroNode(4, "张议天", "智习");
        HeroNode node5 = new HeroNode(5, "宋江", "及时与");
        HeroNode node6 = new HeroNode(6, "林冲", "豹子头");
        HeroNode node7 = new HeroNode(7, "吴用", "智多星");
        HeroNode node8 = new HeroNode(8, "张议天", "智习");
        HeroNode node9 = new HeroNode(9, "张议天", "智习");
        HeroNode node50 = new HeroNode(10, "张议天", "智习");
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        SingleLinkedList singleLinkedList2 = new SingleLinkedList();
        singleLinkedList.addByOrder(node1);
        singleLinkedList.addByOrder(node8);
        singleLinkedList.addByOrder(node6);
        singleLinkedList.addByOrder(node4);
        singleLinkedList.addByOrder(node9);

        singleLinkedList2.addByOrder(node5);
        singleLinkedList2.addByOrder(node7);
        singleLinkedList2.addByOrder(node50);
        singleLinkedList2.addByOrder(node3);
        singleLinkedList2.addByOrder(node2);
        SingleLinkedList singleLinkedList1 = CombineSingleNode(singleLinkedList, singleLinkedList2);
        singleLinkedList1.list();

        singleLinkedList.update(node4);
        singleLinkedList.deleteNode(1);
        singleLinkedList.reserveList(singleLinkedList.getHead());
        singleLinkedList.list2(singleLinkedList.getHead());
        singleLinkedList.list();

        System.out.println(singleLinkedList.getLength());
        System.out.println(singleLinkedList.fingLastIndexNode(2));
    }
    /**
     * 合并俩个有序的链表,合并之后依然有序
     * @param singleLinkedList
     */
    public static SingleLinkedList  CombineSingleNode(SingleLinkedList  singleLinkedList,SingleLinkedList singleLinkedList2){
        if (singleLinkedList.getHead()==null&&singleLinkedList2.getHead()==null){
            return  null;
        }
        SingleLinkedList singleLinkedList1 = new SingleLinkedList();
        HeroNode  temp=singleLinkedList2.getHead().next;
        HeroNode  cur=singleLinkedList.getHead().next;

        while (true) {
            HeroNode  fit=singleLinkedList1.getHead();
            while (true) {
                if (fit.next == null) {
                    break;
                }
                fit = fit.next;
            }
            if (temp==null&cur!=null){
                fit.next=cur;
                cur=cur.next;
            }else if (cur==null&temp!=null){
                fit.next=temp;
                temp=temp.next;
            }else {
                if (temp.No<cur.No){
                    fit.next=temp;
                    temp=temp.next;
                }else {
                    fit.next=cur;
                    cur=cur.next;
                }
            }
            if (fit.next.next!=null){
                fit.next.next=null;
            }
            if (temp==null&cur==null){
                break;
            }


        }
        return   singleLinkedList1;
    }

}
class  SingleLinkedList{
    //首先初始化一个头节点 , 注意 这个头节点 永远不要使用 ,为了放便找到 节点的头部
    //你比如说 添加节点的时候  而地址 就不知道到了哪里 ,当要显示 遍历的时候 , 就需要从头遍历
    private  HeroNode  head  =  new HeroNode(0,"","");

    public void setHead(HeroNode head) {
        this.head = head;
    }

    private  HeroNode  head2  =  new HeroNode(0,"","");

    public HeroNode getHead() {
        return head;
    }

    /**
     * 无序添加
     * @param node
     */
    public void  addNode(HeroNode node){
        //先用一个辅助变量  指向第一个 数据 防止 head 被移动
        HeroNode temp = head ;
        while (true){
            // 判断当 指针指向 下一个数据为空的时候 ,
            // 暂停循环,意味着 这个链表 达到 最后了
            if (temp.next==null){
                break;
            }
            temp=temp.next; //让当前数据指向下一个数据
        }
        System.out.println(head==temp);
        //到了最后可以直接添加数据
        //让最后的指针指向 新的节点
        temp.next=node;
    }


    /**
     * 顺序添加
     * @param node
     */
    public  void  addByOrder(HeroNode  node){
        //先用一个辅助变量  指向第一个 数据 防止 head 被移动
        HeroNode temp =  head ;
        boolean  flag = false ;
        while (true){
            // 判断当 指针指向 下一个数据为空的时候 ,
            // 暂停循环,意味着 这个链表 达到 最后了
            if (temp.next==null){
                break;
            }
            if (node.No < temp.next.No){
              break;
            }else if (node.No == temp.next.No){
                flag=true;
                break;
            }
            temp=temp.next; //让当前数据指向下一个数据
        }

        if (flag){
            System.out.println("数据已存在");
        }else {
            /*
             千万注意这里的顺序
             一定先连接node 后面的 指针
             在连接前面的指针
             */
            node.next=temp.next;
            temp.next=node;
        }
    }
    //修改节点的数据,根据编号修改
    public void update(HeroNode  node){
       if (head.next==null){
           System.out.println("链表为空");
           return;
       }
        /**
         * 注意这里是从第一个开始找的
         */
       HeroNode temp = head.next;
       boolean flag=false;
       while(true){
           //注意这里是 temp
           if (temp==null){
             break;
           }
           //找到了的情况
           if (temp.No==node.No){
               flag=true;
               break;
           }
           temp=temp.next;
       }
       if (flag){ //找到
           temp.name=node.name;
           temp.nickname=node.nickname;
       }else{  //没有找到
           System.out.println("没有找到");
       }

    }
    //删除节点
    public  void   deleteNode(int no){
        HeroNode  temp =  head ;
        boolean  flag = false ;
        while(true){
            if (temp.next==null){
                break;
            }
            if (temp.next.No==no){
                flag =true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            temp.next=temp.next.next;
        }else {
            System.out.println("没有找到");
        }

    }
    //显示数据
    public void  list(){
        //首先判断链表为空 ,  看下一个数据是否有数据
      if (head.next==null){
          System.out.println("链表为空");
          return;
      }
      //  与上面 添加一样
        HeroNode temp = head.next;
        while (true){
            if (temp==null){
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }
    //获取当前链表的有效个数
    public    int  getLength(){
       if (head.next==null){
           throw  new RuntimeException("链表为空");
       }
        /**
         * 注意: 这里不统计头节点
         */
       HeroNode temp=head.next;
       int length=0;
       while(temp!=null){
         length++;

         temp=temp.next;
       }
       return length;

    }
    //获取到倒数第K个元素 【新浪】
    public  HeroNode  fingLastIndexNode(int  index){
        if (head.next==null){
            throw  new RuntimeException("链表为空");
        }
        /**
         * 思路 : 首先获取 当前的 单链表的总个数 减去 倒数第 k 个元素
         * 就是 正数第(length -size))个 个数
         *
         */
        int  size = getLength();
        //注意这里的index校验
        if (index<=0 || index > size){
          return null;
        }
        HeroNode temp=head.next;
        //循环 size - index 下
        for (int i = 0; i < size-index; i++) {
            temp=temp.next;
        }
        return temp;
    }
    //单链表反转(本人的思路)【腾讯面试题】
    public  void  reserveNode(HeroNode head){
        if (head.next==null || head.next.next==null){
            return;
        }
        int  count=getLength();
        while (true){
            HeroNode temp = head;
            HeroNode cur=head2;
            if (count==0){
                break;
            }
            for (int i = count-1; i >= 0; i--) {
                temp=temp.next;
            }
            count--;
            temp.next=null;
            while (cur.next!=null){
                cur=cur.next;
            }
            cur.next=temp;
        }
        head.next=head2.next;
    }
    //单链表反转2(老师的思路)【腾讯面试题】
    public  void  reserveList(HeroNode head){
        if (head.next==null || head.next.next==null){
            return;
        }
        HeroNode cur = head.next;
        HeroNode next =null; //指向下一个节点

        while (cur!=null){

            next=cur.next; //保留下一个节点

            cur.next=head2.next;

            head2.next=cur;
            cur=next;
        }
        head.next=head2.next;
    }

    /**
     * 逆序遍历链表【百度】
     * @param head
     */
    public  void  list2(HeroNode head){
       if (head.next==null){
           return;
       }
       HeroNode  cur=head;
       while (true) {
           HeroNode  temp=head;
           while (true) {
             if (temp.next.next==null){
              System.out.println(temp.next);
              temp.next=null;
              break;
             }
               temp = temp.next;
           }
           if (temp==head){
               break;
           }
       }
       head=cur;
    }
    /**
     * 逆序遍历链表【百度】
     * @param head
     */
    public  void  reserveListz(HeroNode head){
       if (head.next==null){
           return;
       }
        //使用栈这个数据结构 ,逆序遍历
        Stack<HeroNode>  stack=new Stack<>();
        HeroNode  temp= head.next;
       while (temp!=null){
           stack.push(temp);
           temp=temp.next;
       }
       while (stack.size()>0){
           System.out.println(stack.pop());
       }
    }


}
class  HeroNode{
    public int      No;      //水浒英雄的编号
    public String   name;    //水浒英雄的姓名
    public String   nickname;//水浒英雄的外号
    public HeroNode next;    //下一个节点的地址
    //传入英雄的信息
    public HeroNode(int no, String name, String nickname) {
        No = no;
        this.name = name;
        this.nickname = nickname;
    }
    @Override
    public String toString() {
        return "HeroNode{" +
                "No=" + No +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    } //显示英雄的数据
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值