单链表 计算有效节点的个数 ,查找倒数第几个节点 ,反转链表

1.定义节点

class HeroNode {
    public int no;
    public String name;
    public String nickname;
    public HeroNode next;

    public HeroNode(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
    }

}

2.单链表

class SingleLinkedList {
    //先初始化一个头节点,不用于存放具体的数据
    private HeroNode head = new HeroNode(0, "", "");

    public HeroNode getHead() {
        return head;
    }

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

   
    /*思路:在考虑节点的编号顺序时,
     * 1.首先找到添加节点的位置,通过辅助变量(指针), 遍历得到
     * 2.新节点.next=temp.next
     * 3.temp.next=新节点*/
    public void addByOrder(HeroNode node) {
        //因为头节点不能变,需要使用辅助节点,temp寻找添加节点的前一个节点
        HeroNode temp = head;
        boolean flag = true; //若链表中已经存在需要插入的节点,则flag为false
        //寻找temp的位置
        while (true) {
            if (temp.next == null) { //temp的下一个节点为空,则遍历完成,停止遍历
                break;
            }
            if (temp.next.no > node.no) {   // temp的下一个节点编号大于插入的节点编号,则已经找到temp的位置
                break;
            } else if (temp.next.no == node.no) {  //链表中存在此编号,则flag变为false
                flag = false;
                break;
            }
            //上述情况均不满足时,仍旧需要遍历
            temp = temp.next;
        }
        //寻找到temp的位置之后,进行添加操作
        if (!flag) {//链表中存在此编号
            System.out.println("链表存在此数据" + node);
        } else {
            node.next = temp.next;
            temp.next = node;
        }
    }


    public void list() {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head;
        while (temp.next != null) {
            temp = temp.next;
            System.out.println(temp);
        }
    }
}

3.反转单链表

/*1.链表:以节点的形式进行存储
 * 2.每个节点包含data域 next域
 * 3.链表的节点不一定是连续存储
 * 4.链表分为带头节点的链表和不带头节点的链表    */

/*单链表(带头节点)
 * head节点 :不存放数据,表示单链表的头next*/
public class SingleLinkedListDemo {
    public static void main(String[] args) {
        HeroNode hero1 = new HeroNode(1, "松江", "da");
        HeroNode hero2 = new HeroNode(2, "无用", "dd");
        HeroNode hero3 = new HeroNode(3, "陆金一", "dc");
        HeroNode hero4 = new HeroNode(4, "林冲", "dd");
        SingleLinkedList singleLinkedList = new SingleLinkedList();

     /*   singleLinkedList.add(hero1);
        singleLinkedList.add(hero3);
        singleLinkedList.add(hero2);
        singleLinkedList.add(hero4);*/
        singleLinkedList.addByOrder(hero4);
        singleLinkedList.addByOrder(hero1);
        singleLinkedList.addByOrder(hero3);
        singleLinkedList.addByOrder(hero2);
        singleLinkedList.list();

    /*    HeroNode newh3 = new HeroNode(3, "金一", "fc");
        singleLinkedList.update(newh3);
        singleLinkedList.list();*/
     /*   singleLinkedList.delete(4);
        singleLinkedList.delete(2);
        singleLinkedList.delete(1);
        singleLinkedList.delete(3);
        singleLinkedList.list();
        int length = getLength(singleLinkedList.getHead());
        System.out.println(length);*/
/*        HeroNode lastIndexNode = findLastIndexNode(singleLinkedList.getHead(), 4);
        System.out.println(lastIndexNode);*/
/*reverseList1(singleLinkedList.getHead());*/
reverseList2(singleLinkedList.getHead());
singleLinkedList.list();
    }

    //单链表的反转
    /*思路:遍历链表,将对象存放到数组中,反向*/
    public static void reverseList1(HeroNode head){
        if(head.next==null||head.next.next==null){  //链表为空 或者链表仅仅存在一个元素时,直接返回
            return;
        }
        //定义一个新的指针变量
        HeroNode temp=head.next;
        HeroNode next=null; //指向当前指针变量的下一个节点
        HeroNode reverseHead=new HeroNode(0,"","");
        //遍历原来的链表,每遍历一个元素,将其放在链表的最前端
        while (temp!=null){
            next=temp.next;  //保存当前指针的下一个节点
            temp.next=reverseHead.next;
            reverseHead.next=temp;  //将新加入的节点放入链表中
            temp=next;

        }
        head.next=reverseHead.next;
    }

    public static  void reverseList2(HeroNode head){
        if(head.next==null||head.next.next==null){
            return;
        }
        //特殊 插入第一个节点
        HeroNode temp=head.next; //插入的节点变量
        HeroNode next=null;  //保存插入的下一个节点
        //链表取出第一个节点
        next=head.next.next; //从第二个节点开始的有效节点
        head.next.next=null;  //第一个节点即为尾节点 ,其next属性的值为空
        temp=next;  //从第二个节点开始,采用循环操作
        while (temp!=null){
            next=temp.next; //保存当前插入节点的下一个节点,相当于去除取出的节点
            temp.next=head.next;  //temp的下一个节点为 head的下一个节点
            head.next=temp; //头节点的下一个节点为temp
            temp=next;
        }
    }

    //查找第倒数index个节点
    public static HeroNode findLastIndexNode(HeroNode head, int index) {
        if (head.next == null) {
            System.out.println("链表为空");
        }
        //链表不为空时,计算当前链表的长度
        int size = getLength(head);
        //校验输入的index参数是否合法
        if (index <= 0 || index > size) {
            System.out.println("输入的参数不合法");
            return null;
        }
        HeroNode temp = head.next;
        for (int i = 0; i < size - index; i++) {
            temp = temp.next;
        }
        return temp;
    }

    //在计算单链表有效节点个数时,应去除头节点
    public static int getLength(HeroNode head) {
        if (head.next == null) {
            return 0;
        }
        HeroNode temp = head.next;  //指针从第一个有效节点开始
        int length = 0;
        while (temp != null) {
            length++;
            temp = temp.next;
        }
        return length;
    }
}

你可能感兴趣的:(单链表)