Data Structure in Algorithms-Linear Table Explanation

Posted by sys4dm1n on Wed, 14 Aug 2019 09:27:50 +0200

Preface

  • Pass through the front Data Structure and Algorithmic Leader Now that we know some of the concepts and importance of data structures, let's summarize the related content of linear tables today. Of course, I share with you my understanding.
  • In fact, to be honest, many people may still be confused about the differences and links between linear lists, sequential lists and linked lists!

    • Linear table: Logical structure is the relationship between exposed data, regardless of how the underlying implementation.
    • Sequence List and Link List: Physical structure, which implements a structure on the actual physical address of the structure. For example, sequence tables are implemented with arrays. The linked list uses pointers to complete the main work. Different structures differ in different scenarios.
    • For java, we all know the List interface type, which is the logical structure, because it encapsulates a series of methods and data of a linear relationship. The specific implementation is actually related to the physical structure of the content. For example, the content storage of sequential tables uses arrays, and then a get, set, and add method is based on arrays, while the linked list is based on pointers. When we consider data relations in objects, we need to consider the properties of pointers. Pointer pointing and value.

Next, a graph is used to analyze the relationship between linear tables. There may be some inaccuracies, but they can be referred to, and examples will be given later based on this figure.
Insert a picture description here

Basic Architecture of Linear Table

  • For a linear table. Regardless of how it is implemented, we should have the same function name and implementation effect. You can also feel the design of some structures. For example, List's Array List and LinkedList. Map HashMap and current HashMap have the same interface api, but the underlying design implementation is definitely different.
  • Therefore, based on the object-oriented programming thinking, we can write a linear table as an interface, and the specific implementation of the sequence list and linked list can inherit the interface method, improve the readability of the program.
  • It is also important to remember that the linear tables implemented when learning data structures and algorithms are fixed types (int). With the progress of knowledge, we should use generics to achieve more reasonable. The specific design of the interface is as follows:
package LinerList;
public interface ListInterface<T> {    
    void Init(int initsize);//Initialization table
    int length();
    boolean isEmpty();//Is it empty?
    int ElemIndex(T t);//Find the number
    T getElem(int index) throws Exception;//Obtain data based on index
    void add(int index,T t) throws Exception;//Insert data according to index
    void delete(int index) throws Exception;
    void add(T t) throws Exception;//Tail insertion
    void set(int index,T t) throws Exception;
    String toString();//Convert to String output    
}

Sequence table

  • Sequential tables are implemented based on arrays, so some methods are based on the characteristics of arrays. The basic attributes of a sequence table should be an array of data and a length.
  • It is also important to note that the size of the initialization array, you can fix the size, but for the sake of availability, if the memory is not enough, it will be doubled. Of course, this is likely to be a waste of space.
  • Some basic forehead methods will not be mentioned, the following focuses on some beginners easily confused concepts and methods to achieve. Here the list is compared to a group of people sitting on the bench.

insert

add(int index,T t)

  • Where index is the insertion number position and t is the insertion data

  • According to the picture, you can understand the insertion operation very well. When an index is inserted, all the elements behind it are moved one bit back. You can see the bloated operation during insertion. So this is also the worst performance of the sequence table, frequent insertion, deletion.

delete

  • Similarly, deletion is also very resource-intensive. The principle is similar to insertion, but people go, empty behind a small bench people need to move forward.



Other operations

  • Other operations are simple. For example, if you get data getElem(int index) by number, you can return it directly according to data coordinates. a[index], while other operations can be directly manipulated by traversing arrays.

linked list

  • I think that the watch should be something that many people feel very winding about, and that's probably because of the pointer. Many people say that java has no pointer. In fact, java also has invisible pointer. It just can't be used directly.
  • Pointer data relationships are often more abstract than arrays. For the pointer field, you can just treat it as an object, but this object points to another object of the same level. For this relationship, you can compare it to every person class. Every person class has a husband (wife), and this husband and wife is also a real object, it can be understood that this is more like a logical agreement relationship, rather than a rigid relationship.

  • Pointer you can think of as brain memory. The list above says it's ordered because each bench (array) has a number, and we can determine the position based on this. For a linked list, you can think of it as a group of people standing on the playground. And his operation is slightly different, the following for some more special and important to summarize.

Basic structure

For linear tables, we only need a data array and length to represent basic information. For linked lists, we need a node(head header node), and length. Of course, this node is also a structure.

class node<T>{
    T data;//Results of nodes
    node next;//Next connected node
    public node(){}
    public node(T data)
    {
        this.data=data;
    }
    public node(T data, node next) {
        this.data = data;
        this.next = next;
    } 
}

Of course, this node has data domain and pointer domain. Data field is to store real data, and pointer field is to store the next node's pointer. Therefore, compared with sequential tables, linked lists occupy more resources when full arrays are used, because they need to store pointers to occupy resources.

insert

add(int index,T t)
Where index is the insertion number position and t is the insertion data
Join the insertion of a node, according to index to find the insertion of the first node is called pre. Then the operation flow is as follows

  1. The operation of node.next=pre.next is as follows: 1, which links the insertion nodes. At this point, node.next and pre.next are identical.
  2. pre.next=node because we want to insert node, and node chain can replace next of preitself. Then point the pre directly to the node. That would be equivalent to inserting a node into the original list.


Leading Node and Non-Leading Node


Many people don't know what a lead node is and what a no-lead node is. The leading node is that the head node does not put data, and item 0 starts from the one behind the head. The head node is the 0th place in the linked list without the head node.
Main differences:

  • The main difference between the leading node and the non-leading node is the insertion and deletion of the first place, especially the first insertion. The lead node needs to traverse the element more than once because its first head node is the head node, and there is no data (it can be regarded as the locomotive of a train). It is convenient to insert the leading node in the first place. Because insertion number 0 is also behind the head.
  • The list without leading nodes needs special consideration. Because inserting number 0 is actually before inserting head. Suppose you have a head, insert a node. The specific operation is as follows:

  1. node.next=head; (node points to head, node is the chain we want)
  2. head=node; (Many people don't understand that node is the first node in the longest chain after insertion, head is behind him, and head in the list usually means the first node, so head does not mean the second node, directly "=" node. In this way, both head and node represent the linked list of operations completed. But only head was exposed. So head can only point to the first node! )

Insertion tail

  • When inserting the tail, it should be noted that the next of the tail is null. Can't compare with inserting normal position!

delete


Remove by index: delete(int index)

  • Find the node node of the index. node.next=node.next.nex

Remove (expand) by tail: deleteEnd()

  • I haven't written this method, but I'll tell you about it. The idea of deleting from the end is as follows:

    1. Declare a node as head.
    2. When node.next! = When null, node=node.next points to the next
    3. When node.next==null. The last one when describing this node. You can node=null. The next next of the node's predecessor, pre, is null. This node is deleted.

Header deletion (header node):

  • Lead node deletion and general deletion has been. Direct head. next (first element) = head. next. next (second element)
  • So head.next points directly to the second element. The first one was deleted.

Header deletion (no header node)

  • We know that the first one without the lead node is the real element of inventory. It's also easy to delete nodes without taking the lead. Just move the head to the second place. That is: head=head.next

Other

  • For other operations, the main time is to combine search. The search for a single linked list starts with the head. Then another node team=head or head.next. Then use this node to constantly wait for the next it points to to find what we need, that is, while {team=team.next} is similar.
  • Different tutorials and linear tables written by people are not the same. Here we only give a sample to learn how to use, but not a standard. I hope you will look at it.
  • In the implementation, the linked list with the leading nodes is used, because it is more convenient to manage and does not need a lot of if else.

code implementation

Sequence table

package LinerList;

public class seqlist<T> implements ListInterface<T> {
    private Object[] date;//Array Storage Data
    private int lenth;
    public seqlist() {//The initial size defaults to 10
        Init(10);
    }

    public void Init(int initsize) {//Initialization
        this.date=new Object[initsize];
        lenth=0;        
    }
    public int length() {        
        return this.lenth;
    }

    public boolean isEmpty() {//Is it empty?
        if(this.lenth==0)
            return true;
        return false;
    }

    /*
     * * @param t    
     * Returns the same result, with -1 false
     */
    public int ElemIndex(T t) {
        // TODO Auto-generated method stub
        for(int i=0;i<date.length;i++)
        {
            if(date[i].equals(t))
            {
                return i;
            }
        }
        return -1;
    }

    /*
     *Get the number of elements
     */
    public T getElem(int index) throws Exception {
        // TODO Auto-generated method stub
        if(index<0||index>lenth-1)
            throw new Exception("value out of range");
        return (T) date[index];
    }
    
    public void add(T t) throws Exception {//Tail insertion
         add(lenth,t);
    }

    /*
     *Insert by number
     */
    public void add(int index, T t) throws Exception {
        if(index<0||index>lenth)
            throw new Exception("value out of range");
        if (lenth==date.length)//Capacity expansion
        {
            Object newdate[]= new Object[lenth*2];
            for(int i=0;i<lenth;i++)
            {
                newdate[i]=date[i];
            }
            date=newdate;
        }
        for(int i=lenth-1;i>=index;i--)//Move back after the element
        {
            date[i+1]=date[i];
        }
        date[index]=t;//Insert elements
        lenth++;//Sequence table length + 1
        
    }

    public void delete(int index) throws Exception {
        if(index<0||index>lenth-1)
            throw new Exception("value out of range");
        for(int i=index;i<lenth;i++)//After index, the element moves forward
        {
            date[i]=date[i+1];
        }
        lenth--;//Length-1    
    }

    @Override
    public void set(int index, T t) throws Exception {
        if(index<0||index>lenth-1)
            throw new Exception("value out of range");
        date[index]=t;
    }
    public String  toString() {
        String vaString="";
        for(int i=0;i<lenth;i++)
        {
            vaString+=date[i].toString()+" ";
        }
        return vaString;
        
    }
}

linked list

package LinerList;

class node<T>{
    T data;//Results of nodes
    node next;//Next connected node
    public node(){}
    public node(T data)
    {
        this.data=data;
    }
    public node(T data, node next) {
        this.data = data;
        this.next = next;
    }
   
}
public class Linkedlist<T> implements ListInterface<T>{

    node head;
    private int length;
    public Linkedlist() {
        head=new node();
        length=0;
    }
    public void Init(int initsize) {
        head.next=null;
        
    }

    public int length() {
        return this.length;
    }

    
    public boolean isEmpty() {
        if(length==0)return true;
        else return false;
    }

    /*
     * Get the element number
     */
    public int ElemIndex(T t) {
        node team=head.next;
        int index=0;
        while(team.next!=null)
        {
            if(team.data.equals(t))
            {
                return index;
            }
            index++;
            team=team.next;
        }
        return -1;//If not found
    }

    @Override
    public T getElem(int index) throws Exception {
        node team=head.next;
        if(index<0||index>length-1)
        {
            throw new Exception("value out of range");
        }
        for(int i=0;i<index;i++)
        {
            team=team.next;
        }
        return (T) team.data;
    }


    public void add(T t) throws Exception {
        add(length,t);
        
    }
    //Insertion of the lead node, the first and last operation
    public void add(int index, T value) throws Exception {
        if(index<0||index>length)
        {
            throw new Exception("value out of range");
        }
        node<T> team=head;//team finds the current location node
        for(int i=0;i<index;i++)
        {
             team=team.next;
        }
        node<T>node =new node(value);//Create a new node
        node.next=team.next;//Next pointer to the front of index
        team.next=node;//Make yourself an index position    
        length++;
    }
    

    @Override
    public void delete(int index) throws Exception {
        if(index<0||index>length-1)
        {
            throw new Exception("value out of range");
        }
        node<T> team=head;//team finds the current location node
        for(int i=0;i<index;i++)//Mark the previous node of team
        {
             team=team.next;
        }
        //The team.next node is the node we want to delete
        team.next=team.next.next;
        length--;
    }

    @Override
    public void set(int index, T t) throws Exception {
        // TODO Auto-generated method stub
        if(index<0||index>length-1)
        {
            throw new Exception("value out of range");
        }
        node<T> team=head;//team finds the current location node
        for(int i=0;i<index;i++)
        {
             team=team.next;
        }
        team.data=t;//Assign values, other values remain unchanged
        
    }

    public String toString() {
        String va="";
        node team=head.next;
        while(team!=null)
        {
            va+=team.data+" ";
            team=team.next;
        }
        return va;
    }

}

Tests and results

package LinerList;
public class test {
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("Linear table test:");
        ListInterface<Integer>list=new seqlist<Integer>();
        list.add(5);
        list.add(6);
        list.add(1,8);
        list.add(3,996);
        list.add(7);
        System.out.println(list.ElemIndex(8));
        System.out.println(list.toString());
        list.set(2, 222);
        System.out.println(list.toString());
        list.delete(4);
        System.out.println(list.toString());
        System.out.println(list.length());    
        
        System.out.println("Link list test:");
        list=new Linkedlist<Integer>();
        list.add(5);
        list.add(6);
        list.add(1,8);
        list.add(3,996);
        list.add(7);
        System.out.println(list.ElemIndex(8));
        System.out.println(list.toString());
        list.set(2, 222);
        System.out.println(list.toString());
        list.delete(4);
        System.out.println(list.toString());
        System.out.println(list.length());    
    }
}

Output:

Linear table test:
1
5 8 6 996 7
5 8 222 996 7
5 8 222 996
4
Link list test:
1
5 8 6 996 7
5 222 6 996 7
5 222 6 996
4

summary

  • Here is just a simple implementation, the basic method of implementation. Linked lists are also single-linked lists. The degree of perfection can also be optimized. If there are any mistakes, please correct them.
  • Single linked list queries are slow because they need to be traversed from scratch. If tail is frequently manipulated, you can consider that not only head is tailed in the list. The query speed of sequential table is fast, but insertion is time-consuming and laborious. Practical application is selected according to demand!
  • Arraylist and LinkedList in java are the representatives of the two approaches, but LinkedList uses bidirectional linked list optimization, and jdk's api has done a lot of optimization. So we don't need to make wheels, we can use them directly, but they are still of great learning value.
  • If you do not understand or do not understand, you can contact and discuss. The author opens the door of his public number to welcome visitors at any time! Next will continue to share shipments! If you feel good, you can give a compliment and pay attention to a wave of public numbers (a well-prepared reply to the data structure):bigsai

Topics: Java Programming JDK