數據結構-鏈表-單鏈表實戰(逆序、反轉、合併...)

查找單鏈表中倒數第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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章