【數據結構】單鏈表的java實現

單向鏈表是一種線性表,實際上是由節點(Node)組成的,一個鏈表擁有不定數量的節點。其數據在內存中存儲是不連續的,它存儲的數據分散在內存中,每個結點只能也只有它能知道下一個結點的存儲位置。由N各節點(Node)組成單向鏈表,每一個Node記錄本Node的數據及下一個Node。向外暴露的只有一個頭節點(Head),我們對鏈表的所有操作,都是直接或者間接地通過其頭節點來進行的。

這裏寫圖片描述

Java代碼1

import lianbiao.MyLink.Node;

public class SingleList {

    //  由於類中的靜態方法不能直接調用動態方法,所以將Node內部類修飾爲靜態類
    public static class Node{
        public int data;
        public Node next;

        public Node(){}

        public Node(int data){
            this.data = data;
            this.next = null;
        }

        public int getData() {
            return this.data;
        }

        public void setData(int data) {
            this.data = data;
        }

        public Node getNext() {
            return this.next;
        }

        public void setNext(Node next) {
            this.next = next;
        }       

    }

    //對頭結點的初始化,如果不初始化,將會空指針異常,無法進行以下Node temp=head; temp.next的操作 
    public Node head = new Node(2);

    //count用來統計鏈表的長度
    public int count;

    public SingleList(){}

    /**
     * 統計鏈表中結點的個數
     * @return
     */
    public int size(){
        return this.count;
    }

    /**
     * 判斷鏈表是否爲空
     * @return
     */
    public boolean isEmpty(){
        return this.head == null ? true : false;
    }


    /**
     * 增加一個結點
     * @param node
     * 在鏈表的最後插入新的結點
     * 將原本最後一個結點的next指向新結點
     */
    public void addNode(Node node){
        //一個移動的指針(把頭結點看做一個指向結點的指針)      
        Node temp=head;

        //遍歷單鏈表,直到遍歷到最後一個則跳出循環
        while(temp.next != null){
            //往後移一個結點,指向下一個結點。
            temp=temp.next;
        }
        //temp爲最後一個結點,將其next指向新結點
        temp.next=node;
        //統計結點的個數       
        count++;
    }

    /**
     * 在指定位置插入結點
     * @param index
     * @param node
     */
    public void insertNodeByIndex(int index,Node node){
        if(index<1 || index>this.count){
            System.out.println(count);
            System.out.println("插入的位置不合理");
            return ;
        }

        //記錄我們遍歷到第幾個結點了,也就是記錄位置。
        int length = 1; 

        //可移動的指針
        //我們的temp代表的是當前位置的前一個結點。
        //前一個結點        當前位置        後一個結點
        //temp    temp.next     temp.next.next

        Node temp = head;

        //遍歷單鏈表
        while(head.next != null){

            //判斷是否到達指定位置
            if(index == length){ 
                //結點插入操作
                node.next = temp.next;            
                temp.next = node; 
                count++;
                return;
            }
            length++;
            temp = temp.next;
        } 
    }

    /**
     * 刪除某個位置的結點
     * @param index
     */
    public void deleteNodeByIndex(int index){
        if(index<1 || index>=this.count){
            System.out.println("給定的位置不合理");
            return ;
        }

        int length=1;
        Node temp = head;
        while(temp.next != null){
            if(index == length){
                //結點刪除操作
                temp.next = temp.next.next;
                count--;
                return;
            }
            length++;
            temp = temp.next;
        }
    }

    /**
     * 某個數據是否在鏈表中 
     * @param data
     * @return
     */
    public boolean isContain(int data){
        //flag爲函數標記,用來表示函數執行的結果
        boolean flag=false;

        //temp爲頭結點  tail爲頭結點的下一個結點      
        Node temp=head;
        Node tail=head.next;

        if(temp == null){
            System.out.println("該鏈表是空鏈表!");
            flag = false;
        }
        else{
            while(tail != null){
                if(tail.data==data){
                    flag = true;
                    break;
                }
                temp = tail;
                tail = tail.next;
            }
        }       
        return flag;
    }

    public void print(){
        Node temp=head.next;
        System.out.print("鏈表遍歷結果爲:  ");
        while(temp != null){
            System.out.print(temp.data+" ");
            temp = temp.next;
        }
        System.out.println();
    }   

    public static void main(String[] args) {

        SingleList list = new SingleList();
        /*SingleList.Node nodes = new Node(7)是對鏈表頭結點的初始化操作
        初始化值的大小不影響最終的函數運行結果
        如果不進行初始化操作,nodes爲null,無法調用鏈表的長度,添加結點等函數操作*/
        SingleList.Node nodes = new Node(7);
        System.out.println(list.isEmpty());
        System.out.println("鏈表的長度爲:"+list.size());
        System.out.println("==================");

        SingleList.Node nodes1 = new Node(2);
        SingleList.Node nodes2 = new Node(2);
        SingleList.Node nodes3 = new Node(6);

        list.addNode(nodes);
        list.insertNodeByIndex(1, nodes1);
        list.insertNodeByIndex(5, nodes2);
        System.out.println(list.isEmpty());
        System.out.println("鏈表的長度爲:"+list.size());
        System.out.println("==================");

        list.addNode(nodes3);
        System.out.println(list.isEmpty());
        System.out.println("鏈表的長度爲:"+list.size());
        System.out.println("==================");

        list.deleteNodeByIndex(4);
        System.out.println(list.isEmpty());
        System.out.println("鏈表的長度爲:"+list.size());
        System.out.println("==================");

        list.print();
        System.out.println("鏈表中是否存在2這個元素:"+list.isContain(2));
        System.out.println("鏈表中是否存在5這個元素:"+list.isContain(5));
        System.out.println("鏈表中是否存在6這個元素:"+list.isContain(6));      
    }
}


程序運行結果:
false
鏈表的長度爲:0
==================
2
插入的位置不合理
false
鏈表的長度爲:2
==================
false
鏈表的長度爲:3
==================
給定的位置不合理
false
鏈表的長度爲:3
==================
鏈表遍歷結果爲:  2 7 6 
鏈表中是否存在2這個元素:true
鏈表中是否存在5這個元素:false
鏈表中是否存在6這個元素:true

Java代碼2

import lianbiao.SingleList.Node;

public class MyLink {
    //定義鏈表頭結點
    Node head = null; 

    static class Node {

        // 節點的引用,指向下一個節點
        Node next = null;
        // 節點的對象,即數據域
        int data;
        Node(){}

        public Node(int data) {
            this.data = data;
        }
    }

    /**
     * 增加一個結點
     * @param d
     */
    public void addNode(int d) {
        // 實例化一個節點
        Node newNode = new Node(d);
        if (head == null) {
            head = newNode;
            return;
        }

        //一個移動的指針(把頭結點看做一個指向結點的指針)
        Node tmp = head;
        while (tmp.next != null) {
            tmp = tmp.next;
        }

        //temp爲最後一個結點,將其next指向新結點
        tmp.next = newNode;
    }

    public void insertNodeByIndex(int index,Node node){
        if (index < 1 || index > length()) {
            System.out.println("插入的位置不合理");
            return ;
        }

        int i=1;
        Node preNode = head;
        Node curNode = preNode.next;
        //遍歷單鏈表
        while(curNode != null){

            //判斷是否到達指定位置
            if(i == index){ 
                //結點插入操作
                node.next = curNode;            
                preNode.next = node;
                return;
            }
            preNode = curNode;
            curNode = curNode.next;
            i++;
        } 
    }

    /**
     * @param index:刪除第index個節點
     * @return
     */
    public boolean deleteNode(int index) {
        if (index < 1 || index > length()) {
            return false;
        }


        if (index == 1) {
            head = head.next;
            return true;
        }

        //i表示第i個位置
        int i = 1;
        Node preNode = head;
        Node curNode = preNode.next;

        //循環遍歷尋找第i個結點的位置
        while (curNode != null) {
            if (i == index) {
                preNode.next = curNode.next;
                return true;
            }
            preNode = curNode;
            curNode = curNode.next;
            i++;
        }
        return false;
    }

    /**
     * 鏈表長度
     * @return 返回節點長度
     */
    public int length() {
        int length = 0;
        Node tmp = head;
        while (tmp != null) {
            length++;
            tmp = tmp.next;
        }
        return length;
    }

    /**
     * 某個數據是否在鏈表中 
     * @param data
     * @return
     */
    public boolean isContain(int data){
        //flag爲函數標記,用來表示函數執行的結果
        boolean flag=false;

        //temp爲頭結點  tail爲頭結點的下一個結點      
        Node temp=head;
        Node tail=head.next;

        if(temp == null){
            System.out.println("該鏈表是空鏈表!");
            flag = false;
        }
        else{
            while(tail != null){
                if(tail.data==data){
                    flag = true;
                    break;
                }
                temp = tail;
                tail = tail.next;
            }
        }       
        return flag;
    }

    /**
     * 打印鏈表
     */
    public void printList() {
        Node tmp = head;
        while (tmp != null) {
            System.out.print(tmp.data+" ");
            tmp = tmp.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        MyLink list = new MyLink();
        System.out.println("鏈表的長度爲:" + list.length());
        System.out.println("================");

        list.addNode(5);
        list.addNode(3);
        list.addNode(1);
        list.addNode(2);
        list.addNode(55);
        list.addNode(36);
        System.out.println("鏈表的長度爲:" + list.length());
        System.out.println("頭結點的數據域爲:" + list.head.data);
        System.out.print("鏈表打印結果爲:");        
        list.printList();

        System.out.println("================");
        list.deleteNode(4);
        System.out.print("After deleteNode(4):");
        System.out.print("鏈表打印結果爲:");
        list.printList();

        System.out.println("================");
        //如果不使用list.insertNodeByIndex(3, new Node(25))代碼,Node內部類將不用定義爲靜態內部類
        list.insertNodeByIndex(3, new Node(25));
        System.out.println("鏈表的長度爲:" +list.length());
        System.out.print("鏈表打印結果爲:");
        list.printList();

        System.out.println("================");
        System.out.println("鏈表是否包含數據域爲25的結點:"+list.isContain(25));
        System.out.println("鏈表是否包含數據域爲10的結點:"+list.isContain(10));
    }
}

程序運行結果:
鏈表的長度爲:0
================
鏈表的長度爲:6
頭結點的數據域爲:5
鏈表打印結果爲:5 3 1 2 55 36 
================
After deleteNode(4):鏈表打印結果爲:5 3 1 2 36 
================
鏈表的長度爲:6
鏈表打印結果爲:5 3 1 25 2 36 
================
鏈表是否包含數據域爲25的結點:true
鏈表是否包含數據域爲10的結點:false
發佈了101 篇原創文章 · 獲贊 139 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章