Collection of Java LinkedList Getting Started Series (eight)

Foreword

The previous two sections we detail the ArrayList, ArrayList data structure to achieve first, handwritten, but look at the source code by analyzing the ArrayList built to achieve, on the set of contents as always, we continue to learn this lesson LinkedList collection, we first entry LinkedList data structure, then go to the source to see how LinkedList is implemented, let's get started.

LinkedList entry

LinkedList is built by a double linked list data structure to store data, and is different ArrayList, ArrayList belong to linear structure in the true sense the physical sense, but also a linear list LinkedList, but need to associate node data back and forth manually by us, at the same time it , double-linked list and a single list only has the structure is different, but doubly linked list more than one predecessor node, the other no difference, then in the end what is doubly linked list it? In our daily lives are full of such examples, such as our music player should be regarded as relatively the image, as follows:

Single list custom implementation

Next we come to realize a single list, then transform the single list dual list, we see that as players, but less single-chain precursor nodes, but there are successor nodes (as wrong), so we need to define a node , then on this node to the next node connected with a reference (as in C or C ++ pointer), and the data stored in the current node, we define the following generic node class:

public  class the Node <T> { 

    // current node value 
    public T Data; 

    // successor nodes 
    public the Node Next; 

    public the Node (T Data) {
         the this .data = Data; 
    } 
}

Next is a simple point to define the operation of the node class list and store data, and here we do little, there will be the head node and tail node in the linked list, where we operate by backing it nodes, we upgraded to double-linked list, etc. when again define the end node, the head node and the list has a length of two variables in a single linked list, as follows:

public  class MyLinkedList <T> { 

    // head node 
    Private the Node head; 

    // list element length 
    Private  int length; 

}

Tips: I will not give you a demonstration of drawing, make brain itself, it feels around, then painted himself look at the drawing board or paper to understand, I also drew a lot on paper only hands to write code. First, we need to consider the head node and tail node that is the first player in the song and the last song, and then add the song to specify the location for the song list is formed by the next series, more vivid example was undoubtedly the string we've ever had the string. So then we finished the first song to add to the list of players, then we should think, the head node is added to the first song, the head node can be directly instantiated if not, there is a first Ruoyi the song, we will re-instantiate a song, and then it has added a reference to the first song the next song assigned to the newly added, so there is the following method:

//添加至头结点
public void addToHead(T data) {
        if (head == null) {
            head = new Node(data);
        } else {
            Node temp = head;
            head = new Node(data);
            head.next = temp;
        }
        length++;
}

Well, to add new songs on the first song we have completely buttoned up, and from the list of songs and then we add a song to the last, this time we know swollen last one it is, as long as the next empty, indicating is the last song, which is the basis for judgment, then this point I do not have to explain too much, then there is the following method:

// add the end node to the 
public  void addToTail (T Data) { 
        the Node TEMP = head;
         the while (temp.next =! Null ) { 
            TEMP = temp.next; 
        } 
        temp.next = new new the Node (Data); 
        length ++ ; 
}

Determine a single list right here, we can loop through to find the last one, then add the corresponding song, so when the data is large enough, can be thought of their performance. Next is the most important piece, and we want to add a song at a given song, this time related to index and then add the song to find the corresponding data,

    // added to the specified index element 
    public  void the Add ( int index, T Data) {
         IF (index <0 ) {
             the throw  new new a RuntimeException ( "Illegal index" ); 
        } 
        IF (index> length) {
             the throw  new new a RuntimeException ( "beyond index boundary " ); 
        } 
        IF (head == null || index == 0 ) { 
            addToHead (Data); 
            return ; 
        } 
        // head node 
        the node TEMP = head;
         // the specified index to the next node
        Holder the Node;
         for ( int I = 0;! I <index -. 1 && temp.next = null ; I ++ ) { 
            TEMP = temp.next; 
        } 
        // specified index node when the next node is not inserted 
        Holder = temp.next;
         // the specified index node to be inserted next node i.e. node 
        temp.next = new new the node (Data);
         // the specified inode list of the next node to be inserted to the specified reference node (the node that is to be specified at this time index node is inserted, and then the next node is the node to be inserted) 
        temp.next.next = Holder; 
        length ++ ; 
    }

Next is to find the elements specified index, I will not explain, directly on the code as follows

    // The element index lookup 
    public T Find ( int index) {
         IF (index <0 ) {
             the throw  new new a RuntimeException ( "Illegal index" ); 
        } 
        IF (length == 0 || index> length) {
             the throw  new new a RuntimeException ( " beyond the boundary index " ); 
        } 
        the Node TEMP = head;
         for ( int I = 0; I <index; I ++ ) { 
            TEMP = temp.next; 
        } 
        return (T) temp.data; 
    }

Finally, the old rules override toString method, the print data list, as follows:

    //链表元素大小
    public int size() {
        return length;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        Node temp = head;
        while (temp != null) {
            sb.append(temp.data);
            sb.append(",");
            temp = temp.next;
        }
        if (sb.charAt(sb.length() - 1) == ',') {
            sb.delete(sb.length() - 1, sb.length());
        }
        return sb.toString();
    }

Finally, we contact the player added to the list of songs to be a test, come on you, as follows:

public  class the Main { 

    public  static  void main (String [] args) { 
        MyLinkedList <Integer> = List new new MyLinkedList <> ();
         // add elements 11 to the head node 
        list.addToHead (11 ); 
        System.out.println (List) ; 

        // add an element to the end node 15 
        list.addToTail (15 ); 
        System.out.println (List); 

        // add elements 12 to the head node 
        list.addToHead (12 ); 
        System.out.println (List); 

        // additive element 13 to the head node 
        list.addToHead (13 ); 
        System.out.println (List); 

        //8 the end node to add elements 
        list.addToTail (8 );
         // add elements to the tail node 7 
        list.addToTail (7 ); 
        List.add ( 2,. 9 ); 
        System.out.println (List); 

        // index 2 position of additive elements. 9 
        List.add (2,. 9 ); 
        System.out.println (List); 

        // delete the index of the element 4 
        list.delete (4 ); 
        System.out.println (List); 
    } 
}

Doubly linked list custom implementation 

With the above single list of foreshadowing, then we again achieved a double-linked list is easy, just add a node and the end node precursor linked list it, you go, we add nodes to a predecessor node class as follows:

public  class the Node <T> { 

    // current node value 
    public T Data; 

    // predecessor node 
    public the Node Previous; 

    // successor nodes 
    public the Node Next; 

    public the Node (T Data) {
         the this .data = Data; 
    } 
}

Similarly, we add the end node in the linked list class fields, as follows:

public  class MyLinkedList <T> {
     // head node 
    Private the Node head; 

    // End Node 
    Private the Node tail; 

    // list element length 
    Private  int length; 
}

Likewise, when you add a song to the top, then we also need to initialize the head node, but this time more than a tail node, it does not matter, this time the head node is the end node, we initialize method of packaging a head node and the end node, as follows:

 // initializes head and tail nodes contacts 
    void initHead (T Data) {
         // Initialization of the head node 
        head = new new the Node (Data);
         // this time i.e. the tail node of the head node 
        tail = head; 
}

Then add a song to the head node, but more a precursor nodes, correspondingly more than just a line of code is added to the precursor node is assigned to the first song of the first songs to be added, as follows:

    //添加元素至头结点
    public void addToHead(T data) {
        if (head == null) {
            initHead(data);
        } else {
            Node temp = head;
            head = new Node(data);
            head.next = temp;
            temp.previous = head;
        }
        length++;
    }

When added to the song last one on the list and the single-bit different, singly linked list traversal is directly recycled, where we define the end node, the end node can direct the operation, as follows:

    //添加至尾节点
    public void addToTail(T data) {
        if (size() == 0) {
            initHead(data);
        } else {
            Node temp = tail;
            tail = new Node(data);
            temp.next = tail;
            tail.previous = temp;
        }
        length++;
    }

The next method is to add the core elements of the specified index, in fact, very simple, I will give you a written comment, or do not understand, it is recommended to drawing on paper Kazakhstan.

    // Adds the specified index element 
    public  void the Add ( int index, T Data) {
         IF (index <0 ) {
             the throw  new new a RuntimeException ( "Illegal index" ); 
        } 
        IF (index> length) {
             the throw  new new a RuntimeException ( "index beyond the boundaries " ); 
        } 
        IF (head == null || index == 0 ) { 
            initHead (Data); 
            return ; 
        } 
        // head node 
        the node TEMP = head;
         // definition of the next node node acquires the specified index
        Holder the Node;
         for ( int I = 0;! I <index -. 1 && temp.next = null ; I ++ ) { 
            TEMP = temp.next; 
        } 
        // current node to the next node 
        Holder = temp.next;
         // To added next node 
        temp.next = new new the node (Data);
         // inserted successor nodes for the current node to the next node 
        temp.next.next = Holder;
         // current node to the next node predecessor node is inserted 
        temp.next = .next.previous temp.next; 
        length ++ ; 
    }

Whether to add or delete the most important thing is we need to think clearly, when adding and removing nodes after predecessor and successor nodes point to who put this question to understand, that there is nothing, you go to delete method:

    // delete the specified index element 
    public  void Delete ( int index) {
         IF (index <0 ) {
             the throw  new new a RuntimeException ( "Illegal index" ); 
        } 
        IF (length == 0 || index> length) {
             the throw  new new a RuntimeException ( " beyond the boundary index " ); 
        } 
        the Node TEMP = head;
         for ( int I = 0; I <index - = temp.next. 1 &&! null ; I ++ ) { 
            TEMP = temp.next; 
        } 
        temp.next.next.previous= temp;
        temp.next = temp.next.next;
        length--;
    }

To validate our written code, we print out the predecessor and successor node corresponding to the node, as follows:

    public int size() {
        return length;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        Node temp = head;
        while (temp != null) {
            sb.append(temp.data);
            sb.append(",");
            if (temp.previous != null && temp.next != null) {
                System.out.println(temp.previous.data + "<-(" + temp.data + ")->" + temp.next.data);
            }
            temp = temp.next;
        }
        if (sb.charAt(sb.length() - 1) == ',') {
            sb.delete(sb.length() - 1, sb.length());
        }
        return sb.toString();
    }

Console test data and a single linked list, the results data as follows (of course, we can print a separate corresponding node predecessor and successor nodes to verify is to wide, and here I also verified over, what have any questions):

to sum up

In this section we achieve a single and a double-linked list by hand-written code, is very simple, we analyzed in detail in the next section LinkedList source, thank you for reading, we see the next section

Guess you like

Origin www.cnblogs.com/CreateMyself/p/11455832.html