1将链表反转,再遍历输出,不推荐,会打乱链表原有顺序
2遍历链表,把值压入一个栈,再把栈的数据输出
3用for循环遍历链表,从最后一位开始,逆序输出

package 算法.单向链表和双向链表的创建和遍历;

import java.util.Stack;

public class LinkedListDemo {
    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(4,"林");
      HeroNode node6 = new HeroNode(6,"456");

      LinkList list = new LinkList();
      list.add(node1);
      list.add(node2);
      list.add(node4);
      list.addByNo(node3);

      list.show();

        System.out.println("");

       list.reversePrint(list.getHead());
       list.reversePrint2(list.getHead());
       
    }
}
//创建一个链表类
class LinkList{
  //先初始化一个头节点
    private HeroNode head= new HeroNode(0,"");
    //添加结点
    //如果不考虑编号
    //找到链表的尾指针,指向添加的结点

    public HeroNode getHead() {
        return head;
    }


    public  void  add(HeroNode node){
        HeroNode temp =head;
        while (true){
            if(temp.next==null){
                break;
            }
            temp=temp.next;
        }
        temp.next=node;
    }
    //第二种添加英雄的方式
    //根据排名将英雄加入指定的位置,如果有这个排名。则添加失败
    public void addByNo(HeroNode node){
        //辅助指针指向要添加的位置的上一个结点
        HeroNode temp =head;
        //标志当前的添加的编号是否存在
        boolean flag= false;
        while (true){
            if (temp.next==null){
                //temp已经在链表的最后
                //当前结点指向要添加的结点
                break;
            }
            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;
        }
    }
    //根据no修改结点的信息,no不能修改,否则会打乱编号排序,修改no应该删除结点,再重新添加。
    //根据newHeronode的no值来添加修改即可
    public void update(HeroNode newHeroNode){
        if(this.head.next==null){
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head.next;
        boolean flag = false;
        while(true){
            if(temp==null){
                break;
            }
            if(temp.no==newHeroNode.no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if(flag==true){
            temp.name=newHeroNode.name;
        }else {
            System.out.println("没有找到要修改的结点");
        }
    }
    //根据no删除结点
    public void del(int no){
         HeroNode temp = head;
        while (head==null){
             System.out.println("链表为空,无法删除");
             return;
         }
         while(true){
             if(temp.next==null){//要写在temp.next.no==nod判断语句之前,不然当temp是表尾会发生空指针异常
                 System.out.println("不存在指定删除的结点");
                 break;
             }
             if(temp.next.no==no){

                 temp.next=temp.next.next;
                 break;
             }

             temp=temp.next;
         }

    }
    //遍历链表
    public void show(){
        HeroNode temp = head.next;//本例中头节点不存放数据
         boolean flag=false;//flag标志添加的编号是否存在
        if (head.next==null){
            System.out.println("链表为空");
            return;
        }
        while (true){
            if(temp==null){
             break;
            }
            System.out.println(temp);
            temp=temp.next;
        }
    }
    //输出单链表中倒数第k个结点,输入参数,头节点,倒数第k个参数
    public   HeroNode findK(HeroNode head,int k){
        int length = 0;
        HeroNode temp = head;
        if(head.next==null){
            throw new RuntimeException("单链表为空");
        }
        while (temp.next!=null){
            length++;
            temp=temp.next;
        }
        temp=head.next;
        for (int i = 0; i <length-k ; i++) {
            temp=temp.next;

        }
        return temp;
    }
    //链表反转,传入参数,链表的头结点
    public   void reversetList(HeroNode head){
        if(head.next==null||head.next.next==null){
            return;
        }
        HeroNode cur = head.next;
        HeroNode next=null;
        HeroNode reverseHead=new HeroNode(0,"");
        //遍历链表,每取出一个结点,就放在新结点的最前端
        while (cur!=null){
            //标记cur下一个,第四步用
            next=cur.next;
            //取出的cur进行头插法
            cur.next=reverseHead.next;
            reverseHead.next=cur;
            cur=next;
        }
        head.next=reverseHead.next;
    }
    //逆序输出方法二 栈
    public  void reversePrint(HeroNode head){
        if(head.next==null){
            return;
        }
        Stack<HeroNode> stack = new Stack<>();
        HeroNode cur = head.next;
        while (cur!=null){
            stack.push(cur);
            cur=cur.next;
        }
        while (!stack.empty()){
            System.out.println(stack.peek());
            stack.pop();
        }

    }
    //逆序方法三 for循环
    public void reversePrint2(HeroNode head){
        if(head.next==null){
            return;
        }
        int length=0;
        HeroNode cur = head.next;
        while (cur!=null){
            cur=cur.next;
            length++;
        }

        for (int i = 0; i <length ; i++) {
            HeroNode temp = head;
            int j=0;
            while (j<length-i){
                temp=temp.next;
                j++;
            }
            System.out.println(temp);

        }

    }
}
//结点类
class  HeroNode{
    public int no;
    public  String name;
    public HeroNode next;
    public HeroNode(int no,String name){
        this.no=no;
        this.name=name;

    }


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