数据结构-链表-单链表实战(逆序、反转、合并...)

查找单链表中倒数第k个节点。
思路:
1.编写一个方法,接收head节点,同时接收一个x
2.x表示是倒数第x个节点
3.先把链表从头到尾遍历,得到链表总长度
4.得到总长度后,我们从链表的第一个开始遍历(总长度-x)个,就可以得到我们需要的节点

public static void main(String[] args){

SingleLinkedListManger sllm = new SingleLinkedListManger();
 System.out.println(getLength(sllm.getHead()));
}
/**
     * 查找单链表中的倒数第k个节点
     * 思路
     * 1.编写一个方法,接受head节点,同时接收一个index
     * 2.index表示是倒数第index个节点
     * 3.先把链表从头到尾遍历,得到链表的总的长度getLength
     * 4.得到size后,我们从链表的第一个开始遍历(size-index)个,就可以得到
     * 5.如果找到了,则返回该节点,否则返回null
     * @param head
     * @param index
     * @return
     */
    public static HeroNode findLastIndexNode(CharacterNode head,int x){
        if (head.next == null){
            return  null;
        }
        //第一次遍历 获取链表长度(节点个数)
        int size = getLength(head);
        //第二次遍历 获取size - index位置,就是我们倒数的第k个节点
        //先做一个index的校验
        if (x <= 0 || x > size){
            return null;
        }
        //定义一个辅助变量,for循环定位到倒数的index
        CharacterNode cur = head.next;
        for (int i = 0; i < size-x; i++) {
          cur  =cur.next;
        }
        return cur;
    }

public static int getLength(CharacterNode head){
        if (head.next == null){
            return 0;
        }
        int length = 0;
        CharacterNode cur = head.next;
        while (cur != null){
            length++;
            cur = cur.next;
        }
        return length;
    }

class SingleLinkedListManger{
    /**
     * 先初始化一个头节点,头节点不要动,不存放具体数据
     */
    private HeroNode head = new HeroNode(0,"","");
    public HeroNode getHead(){
        return head;
    }
    }
class CharacterNode{
    public int id;
    public String name;
    public String nickname;
    public CharacterNode next;
    public CharacterNode pre;
    public CharacterNode(int id,String name,String nickname){
        this.id = id;
        this.name = name;
        this.nickname = nickname;
    }

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

单链表的反转
在这里插入图片描述
思路:
定义一个新的节点reverseHead=new CharacterNode();然后从头到尾遍历原来的链表,每遍历一个节点,就将其取出,放在新的链表reverseHead的最前端,最后将原来链表的头节点的next指向reverseHead的next实现反转。

在这里插入图片描述

 public static void reverseList(CharacterNode head){
        //如果但前链表为空,或者只有一个节点,无需反转,直接返回
        if (head.next == null || head.next.next == null){
            return;
        }

        CharacterNode cur = head.next;
        CharacterNode next = null;
        CharacterNode reverseHead = new CharacterNode(0,"","");
        /**
         * 遍历原来的链表,每遍历一个节点,就将将其取出,并放在新的链表reverseHead的最前端
         */
        while (cur != null){
            //先暂时保存当前节点的下一个节点,因为后面需要使用
            next = cur.next;
            //将cur的下一个节点指向新的链表的最前端
            cur.next =reverseHead.next;
            //将cur连接到新的链表上
            reverseHead.next = cur;
            //让cur后移
            cur = next;
        }
        head.next =reverseHead.next;
    }

单链表逆序
逆序和反转的区别是,逆序是在不该改变链表的结构的条件下进行输出。这种情况下我们可以使用栈这个数据结构,将各个节点压入到栈中,然后利用栈的先进后出的特点,就实现了逆序打印的效果。

 public static void reversePrint(HeroNode head){
        if (head.next == null){
            return;
        }
        //创建一个栈,将各个节点压入栈
        Stack<HeroNode> stack = new Stack<HeroNode>();
        HeroNode cur = head.next;
        //将链表的所有节点压入栈
        while (cur != null){
            stack.push(cur);
            //将cur后移 这样就可以艳如下一个节点
            cur = cur.next;
        }
        /**
         * 出栈
         */
        while (stack.size() > 0){
            System.out.println(stack.pop());
        }
    }

合并两个有序的单链表,合并之后依然有序。
思路:创建一个新的节点,对两个链表的数据进行比较,按照顺序插入。

class ListNode{
    int val;
    ListNode next;
 
    ListNode(int x){
        val = x;
    }
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) return l2;
        if (l2 == null) return l1;
 
        ListNode head = null;
        if (l1.val <= l2.val){
            head = l1;
            head.next = mergeTwoLists(l1.next, l2);
        } else {
            head = l2;
            head.next = mergeTwoLists(l1, l2.next);
        }
        return head;
}

猜你喜欢

转载自blog.csdn.net/amazinga/article/details/106867526