Java模擬(單雙向)循環鏈表圖文說明,有源碼有註釋

單向循環鏈表

前面爲了說明方便,有些是用的貼圖,由於有些圖片較大形成擠壓,看不清點擊看原圖即可,源碼會在後面給出,話不多說,開始吧!

  • 節點類Node
/**
 *  @author AmVilCresx
 * 節點類
 */
public class Node {
    Object element; //數據域
    Node next; // 後繼指針域
    Node previor;// 前驅指針域

    //非頭結點的構造方法
    public Node(Object element) {
        this.element = element;
    }
}
  • 插入鏈表的第一個元素
    FirstrNode

  • 在尾部插入節點元素
    insertRear

  • 在頭部插入節點元素
    insrtHead
  • 在指定位置插入元素節點
    anyWhere

  • 刪除指定位置的節點
    delete

  • 刪除給定的元素節點(註釋做了簡單說明,其它操作跟上面刪除類似)
    delByNode

  • 單向循環鏈表源碼
    複製粘貼開發工具,修改你自己的包名即可運行
public class Node {
    Object element; //數據域
    Node next; // 後繼指針域
    Node previor;// 前驅指針域

    //非頭結點的構造方法
    public Node(Object element) {
        this.element = element;
    }
}
------------------------分割線------------------------------------
package com.avc.link;

/**
 * @author AmVilCresx
 * 模擬單向循環鏈表
 * */
public class CycleLinkList{

    Node head; //頭指針
    Node rear; //尾節點
    Node currentPrior; ////當前節點的前一個節點,下面的刪除和插入要用
    int size; //節點個數

    /**
     * 對空鏈表第一個節點進行插入
     * */
    private void insertFirstNode(Node node) {
        head = node;    //頭指針指向node
        rear = head;    // 尾指針指向head
        head.next = rear;   //鏈接成環狀
        size++; //長度+1
    }   

    /**
     * 在末尾插入
     * */
    public void insertRear(Node node) {
        if(head == null) {
            insertFirstNode(node); // 插入鏈表的第一個元素
        }else {
            node.next = rear.next;  //將帶插入節點的next指向原鏈表rear的next;
            rear.next = node;   // 將原鏈表的rear的next指向node
            rear = node;    // 改變rear的指向 爲node
            size++;     //長度+1
        }   
    }

    /**
     * 頭插法
     * 頭插其實就是和末尾插入一樣的,只不過尾插改變的是尾指針,頭指針不變,頭插改變頭指針,尾指針不變
     * */
    public void insertHead(Node node) {
        if(head == null) {
            insertFirstNode(node);
        }else {
            node.next = rear.next; 
            rear.next=node;
            head=node; // 此處改變的是頭指針head的指向
            size++;
        }
    }


    /**
     * 獲取節點
     * */
    public Node get(int index){
        Node tmp = head;
        int j=0;
        if(index<0 || index>size-1) {
            return null;
        }
        while(j!=index) {
            tmp = tmp.next;
            j++;
        }
        return tmp;
    }

    /**
     * 定位到操作節點的前一個位置
     * */
    public void getLoation(int index) {
        currentPrior = head;
        int j=0;

        while(j<index-1) {//找到要插入的位置前一個位置
            currentPrior = currentPrior.next;
            j++;
        }
        if(index==0) { //如果是第一個節點,則它的前一個節點就是rear節點,上面的while沒處理這種情況
            currentPrior=rear; //手動賦值
            head=head.next; //注意:一定要將head指向下一個節點,不然get的時候會出錯
        }
    }

    /**
     * 在這指定位置進行插入
     * */
    public void insertAnyWhere(int index,Node node) {
        if(index<0 || index > size) {
            throw new RuntimeException("參數非法");
        }

        if(index == 0) { //第一個位置,說明是頭插 
            this.insertHead(node);
        }else if(index == size) { //最後一個位置,說明是,尾插
            this.insertRear(node);
        }else {
            getLoation(index);  //定位到index的前一個位置
            node.next = currentPrior.next; // 將帶插入節點的next指向當前節點(也就是當前節點的前一個節點的下一個節點)
            currentPrior.next=node; // 將前一個節點的next指向node,完成連接
            size++; // 長度+1
        }
    }

    /**
     * 刪除指定位置的節點
     * */
    public Node delete(int index) {
        if(index<0 || index>size-1)
            throw new RuntimeException("參數非法");
        if(isEmpty()) {
            throw new RuntimeException("鏈表爲空,操作失敗");
        }
        Node delNode = null;
        getLoation(index); //定位到index的前一個位置
        delNode = currentPrior.next; //待刪除的節點(當前節點)
        currentPrior.next=delNode.next; // 將當前節點的前驅節點的next指針指向當前節點的next域
        size--; //長度 -1
        return delNode;
    }


    /**
     * 刪除給定的節點,這裏爲了測試方便,默認值相同則是相同的節點,並且不存在element相同的節點
     * */
    public Node deleteByNode(Node node) {
        Node delNode= null;
        if(isEmpty()) {
            throw new RuntimeException("鏈表爲空,操作失敗");
        }
        if(size==1 && node.element == head.element) {
            delete(0);
            head=null;
            return node;
        }
        Node tmp = head; //臨時指針變量
        int count=size;
        while(count>0 && node.element!= tmp.next.element) {
            // 如果小於count,沒走完一圈 或者下個節點的值不等於給定節點的值
            count--;
            tmp = tmp.next;
        }
        if(count==0) {
            throw new RuntimeException("元素不存在,無法刪除");
        }else {
            delNode = tmp.next;
            if(delNode==head) { // 判斷一下,不然get會出錯
                head=delNode.next;
            }
            if(tmp.next==rear) {
                rear=tmp;
            }
            tmp.next=delNode.next; // 改變指針指向
            size--;
        }
        return delNode;
    }

    //鏈表大小
    public int size() {
        return this.size;
    }
    /**
     * 判斷鏈表是否爲空
     * */
    public boolean isEmpty() {
        return size==0;
    }

    public static void main(String[] args) {
        CycleLinkList list = new CycleLinkList();
        /*list.insertRear(new Node(1));
        list.insertRear(new Node(2));
        list.insertRear(new Node(3));
        System.out.println(list.get(1).getElement());*/
        list.insertHead(new Node(1));
        list.insertHead(new Node(2));
        list.insertHead(new Node(3));
        list.insertHead(new Node(4));
        Node ist = new Node(6);
        list.insertRear(ist);
    //  list.insertAnyWhere(1, new Node("insrt"));
        /*System.out.println(list.get(1).element);
        System.out.println("size----"+list.size());
        list.delete(1);
        System.out.println("size----"+list.size());
        System.out.println(list.get(1).element);
        System.out.println(list.get(1).next.element);*/
        System.out.println("size----"+list.size());
        System.out.println(list.get(3).element);
        System.out.println(list.deleteByNode(ist).element);
        System.out.println("size----"+list.size());
        System.out.println(list.get(3).element);

    }
}

雙向循環鏈表

  • 在尾部插入節點元素
    Rear

  • 在頭部插入元素節點
    Head

  • 在指定的位置插入節點
    any

  • 刪除指定位置的節點元素
    del

  • 刪除給定的節點元素
    del2

    • 雙向循環鏈表源碼
package com.avc.link;

/**
 * @author AmVilCresx
 * 模擬雙向循環鏈表
 *
 */
public class CycleBothWayLinkList {

    Node head; //頭指針
    Node rear; //尾節點
    Node current; //當前節點,下面的刪除和插入要用
    int size=0; //節點個數

    /**
     * 插入整個鏈表的第一個節點
     * */
    private void insertFirstNode(Node node ) {
        head=node;
        rear=head;
        head.next=rear; 
        head.previor=rear;// 形成雙向環狀
        size++;
    }

    /**
     * 尾插法
     * */
    public void insertRear(Node node) {
        if(head == null) {
            insertFirstNode(node);
        }else {
            node.next=rear.next;    // 將帶插入節點node的next指向rear的next
            node.previor=rear;  // 將node的前驅指向rear
            rear.next.previor=node; //將rear的next的前驅指向node
            rear.next=node; //將rear的next指向node
            rear=node; //將rear設置爲node
            size++;
        }

    }

    /**
     * 頭插法
     * */
    public void insertHead(Node node) {
        if(head == null) {
            insertFirstNode(node);
        }else {
            node.next=rear.next; // 將帶插入節點node的next指向rear的next
            node.previor=rear; //將node的前驅指向rear
            rear.next.previor=node; //將原來rear的next節點的前驅設置爲node
            rear.next=node; //則rear的next指向node
            head = node; // 改變head的指向
            size++;
        }
    }

    /**
     * 在任意位置插入
     * */
    public void insertAnyWhere(int index, Node node) {
        if(index<0 || index>size) {
            throw new RuntimeException("參數非法!");
        }
        if(index ==0) {
            insertHead(node);
        }else if(index==size) {
            insertRear(node);
        }else {
            getLoation(index); // 因爲是雙向鏈表,所以直接定位到要操作的節點
            node.next = current; //將待插入節點的next指向當期節點
            node.previor=current.previor; //將node的前驅節點設置爲當前節點的前驅節點
            current.previor.next=node; // 再講當前節點的前驅的next指向node
            current.previor=node; // 再將當前節點的前驅節點設置爲node
            size++;
        }
    }

    /**
     * 刪除指定位置的節點
     * */
    public Node deleteNode(int index) {
        if(index<0 || index>size-1)
            throw new RuntimeException("參數非法");
        if(isEmpty()) {
            throw new RuntimeException("鏈表爲空,操作失敗");
        }
        getLoation(index);//找到要插入的位置的當前節點(這裏也可以找要操作的節點的前一個節點,因爲這裏有前驅指針,可不必)
        Node delNode = current;
        current.previor.next=current.next;
        current.next.previor=current.previor;
        size--;
        return delNode;
    }

    /**
     * 刪除給定的節點,這裏爲了測試方便,默認值相同則是相同的節點,並且不存在element相同的節點
     * */
    public Node deleteByGiveNode(Node node) {
        Node delNode= null;
        if(isEmpty()) {
            throw new RuntimeException("鏈表爲空,操作失敗");
        }
        if(size==1 && node.element == head.element) {
            deleteNode(0);
            head=null;
            return node;
        }
        Node tmp = head;
        int count=size;
        while(count>0 && tmp.element != node.element) {
            count--;
            tmp=tmp.next;
        }
        if(count==0) {
            throw new RuntimeException("元素不存在,無法刪除");
        }else {
            delNode = tmp;
            if(delNode==head) {
                head=delNode.next;
            }
            if(delNode==rear) {
                rear=delNode.previor;
            }
            tmp.previor.next=tmp.next;
            tmp.next.previor=tmp.previor;
            size--;
        }       
        return delNode;
    }

    //定位到指定位置
    public void getLoation(int index) {
        current = head;
        int j=0;
        while(j<index) {//找到要插入的位置前一個位置
            current = current.next;
            j++;
        }
        if(index ==0) {
            head = current.next; //改變head的指向
        }
    }

    /**
     * 獲取節點
     * */
    public Node get(int index){
        Node tmp = head;
        int j=0;
        if(index<0 || index>size-1) {
            return null;
        }
        while(j!=index) {
            tmp = tmp.next;
            j++;
        }
        return tmp;
    }

    public boolean isEmpty() {
        return size==0;
    }
    //鏈表大小
    public int size() {
        return this.size;
    }

    /**
     * main函數測試
     * */
    public static void main(String[] args) {
        CycleBothWayLinkList cyl = new CycleBothWayLinkList();
        cyl.insertHead(new Node(1));
        cyl.insertHead(new Node(2));
        cyl.insertHead(new Node(3));
        cyl.insertHead(new Node(4));
        System.out.println("前驅:"+cyl.get(0).previor.element);
        System.out.println("自身:"+cyl.get(0).element);
        System.out.println("後繼:"+cyl.get(0).next.element);
        System.out.println("---------------");
        cyl.insertAnyWhere(0, new Node("insrt"));
        System.out.println("前驅:"+cyl.get(0).previor.element);
        System.out.println("自身:"+cyl.get(0).element);
        System.out.println("後繼:"+cyl.get(0).next.element);
        System.out.println("---------------");
        cyl.deleteNode(0);
        System.out.println("前驅:"+cyl.get(0).previor.element);
        System.out.println("自身:"+cyl.get(0).element);
        System.out.println("後繼:"+cyl.get(0).next.element);
    }
}

有問題請大家留言,批評指正!共勉!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章