Data structure -- Realization of the order table of the linear table

Summary

Linear table is the most basic, simple and commonly used data structure. linear list is a kind of data structure. A linear table is a finite sequence of n data elements with the same characteristics.

Basic concepts

  • For the same linear table, although the values of each data element are different, they must have the same data type;
  • There is a linear or "one-to-one" logical relationship between data elements.
    • The first data element has no precursor, which is called the start node;
    • The last data element has no successor. This data element is called terminal node;
    • In addition to the first and last data elements, other data elements have and only have one precursor and one successor.

Abstract data type of linear table

LinearList=(A0, A1, ..., An-1)

package pers.zhang.linearList;

/**
 * @author zhang
 * @date 2020/1/13 - 16:28
 * Linear table interface, generic parameter T represents data type of data element
 */
public interface LinearList<T> {
    //Judge whether the linear table is empty
    boolean isEmpty();

    //Return linear table length
    int length();

    //Return I (I > = 0) element
    T get(int i);

    //Set the value of the i th element to x
    void set(int i, T x);

    //Insert x as the i-th element
    void insert(int i, T x);

    //Insert x element at the end of linear table
    void append(T x);

    //Delete the i-th element and return the deleted object
    T remove(int i);

    //Delete all elements of linear table
    void removeAll();

    //Find, return the first occurrence of the key element
    T search(T key);
}

Sequential representation and implementation of linear table

Sequential storage structure of linear table

Realization

package pers.zhang.linearList;

import java.util.Arrays;

/**
 * @author zhang
 * @date 2020/1/13 - 16:45
 *
 * The sequential representation of a linear table
 */
public class SeqList<T> implements LinearList<T> {

    //object array
    private Object[] element;

    //Sequence table length
    private int len;

    //Construction method to create a sequence table with the capacity of size
    public SeqList(int size){
        //If size < 0, throw negative group length exception NegativeArraySizeException
        this.element = new Object[size];
        this.len = 0;
    }

    //The default construction method is to create a sequence table with a capacity of 64
    public SeqList(){
        this(64);
    }

    //Sequence table copy
    //Shallow copy construction
//    public SeqList(SeqList<T> list){
//        this.len = list.len;
//        this.element = list.element; / / array is assigned to reference. Two variables share an array. Error!
//    }

    //Deep copy structure
    public SeqList(SeqList<T> list){
        if(list == null)//If list is empty, throw an exception
            throw new NullPointerException();
        this.len = list.len;
        this.element = new Object[list.element.length];//Request an array of the size of the array passed in the list
        for(int i = 0; i < list.len; i++)//Copy array elements, O(n)
            this.element[i] = list.element[i];
        //this.element[i] = new T(list.element[i]); syntax error because Java does not provide the default copy constructor
        //this.element[i] = new Object(list.element[i]); syntax error, because the Object does not provide a copy constructor, and the constructor cannot inherit

    }

    //Deep copy construction, parameter array specifies the initial value of sequence table
    public SeqList(T[] element){
        this.len = element.length;
        this.element = new Object[element.length];//Apply for an array with the size of array length
        for(int i = 0; i < element.length; i++)
            this.element[i] = element[i];
    }

    //Judge whether the sequence table is empty, and return true if it is empty
    @Override
    public boolean isEmpty() {
        return this.len == 0;
    }

    //Length of return sequence table
    @Override
    public int length() {
        return this.len;
    }

    //Returns the i (i > = 0) element. Return null if i < 0 or greater than table length
    @Override
    public T get(int i) {
        if(i >= 0 && i < this.len)
            return (T)this.element[i];//Strong conversion to T type is required, otherwise compilation error
        return null;
    }

    //Set the value of the i (i > = 0) element to X. If i < 0 or greater than the table length, throw the out of range exception of sequence number; if x==null, do not operate
    @Override
    public void set(int i, T x) {
        if(x == null)//Cannot set empty object
            return;
        if(i >= 0 && i < this.len)
            this.element[i] = x;
        else
            throw  new IndexOutOfBoundsException(i + "");//Throw an out of bounds exception
    }

    //Returns the description string of all elements in the sequence table, in the form of "(,)", overriding the toString() method of the Object class
    @Override
    public String toString() {
        String str = "(";
        if(this.len > 0)
            str += this.element[0].toString();
        for(int i = 1; i < this.len; i++)
            str += ", " + this.element[i].toString();
        return str +") ";//Empty table return ()
    }

    //Insert operation of sequence table
    //Insert the i (i > = 0) element with a value of X. If x==null, do not insert
    //If i < 0, insert x as the 0 th element; if i is greater than the table length, insert x as the last element.
    @Override
    public void insert(int i, T x) {
        if(x == null)
            return;
        if(this.len == element.length){//If the array is full, expand first
            Object[] temp = this.element;//temp reference element array
            this.element = new Object[temp.length * 2];//Reapply an array of capacity * 2
            for(int j = 0; i < temp.length; j++)//Copy array elements
                this.element[j] = temp[j];
        }
        //Subscript fault tolerance
        if(i < 0)
            i = 0;
        if(i > this.len)
            i = this.len;
        //Element back shift
        for(int j = this.len - 1; j >= i; j--)
            this.element[j + 1] = this.element[j];
        this.element[i] = x;
        this.len++;
    }

    //Append data at the end of the sequence table
    @Override
    public void append(T x) {
        this.insert(this.len, x);
    }

    //Delete operation of sequence table
    //Delete the i (i > = 0) element and return the deleted object. If i < 0 or i is greater than table length, do not delete and return null
    @Override
    public T remove(int i) {
        if(this.len == 0 || i < 0 || i >= this.len)
            return null;
            //throw new IndexOutOfBoundsException(i + ""); throw out of bounds exception
        T old = (T) this.element[i];
        for(int j = i; j < this.len - 1; j++)//Element move forward, average len/2
            this.element[j] = this.element[j + 1];
        this.element[this.len - 1] = null;//Last set to null
        this.len--;
        return old;
    }

    //Delete all
    @Override
    public void removeAll() {
        this.len = 0;
    }

    //Order table comparison equals method
    //Compare two order tables for equality
    @Override
    public boolean equals(Object obj) {
        if(this == obj)//The same object returns true
            return true;
        if(obj instanceof SeqList){//Subclass objects
            SeqList<T> list = (SeqList<T>) obj;
            if(this.length() == list.length()){//Equal length
                for(int i = 0; i < this.length(); i++)//Compare each element
                    if(!(this.get(i).equals(list.get(i))))
                        return false;
                    return true;
            }
        }
        return false;
    }

    //The key element is used for sequential search, and the first occurrence element is returned. If the search is unsuccessful, - 1 is returned
    //Key can only contain key data items, and the equals() method of class T provides the basis for comparing the equality of objects
    public int indexOf(T key){
        if (key != null)
            for (int i = 0; i < this.len; i++)
                if (this.element[i].equals(key))//Object to compare equality using the equals() method
                    return i;
        return -1;//When empty table, key is empty object or not found
    }

    //Search, return the first key element
    @Override
    public T search(T key) {
        int find = this.indexOf(key);
        return find == -1 ? null : (T)this.element[find];
    }

    //Determine whether the linear table contains key elements
    public boolean contain(T key){
        return this.indexOf(key) >= 0;//If the sequence lookup result is greater than 0, the element exists
    }

    //Delete the first key element
    public void remove(T key){
        this.remove(this.indexOf(key));
    }

    //Return the last position of element key, if not found, return - 1
    public int lastIndexOf(T key){
        if(key != null){
            for(int i = 0; i < this.len - 1; i++)
                if(this.element[i].equals(key))
                    return i;
        }
        return -1;
    }

    //Delete all key elements
    public void removeAll(T key){
        if (key != null)
        {
            int i = 0;
            while (i < this.len)
                if (this.element[i].equals(key))
                    this.remove(i);//Delete element, this.len minus 1, i unchanged
                else i++;
        }
    }

    //Replace the first occurrence of element x with y, O(n)
    public void replace(T x, T y){
        if (x != null && y != null)
        {
            int i = this.indexOf(x);//Find where x first appears
            if (i != -1)
                this.element[i] = y;
        }
    }

    //Replace all elements x with y
    public void replaceAll(T x, T y){
        if (x != null && y != null)
            for (int i= 0; i < this.len; i++)
                if (x.equals(this.element[i]))
                    this.element[i] = y;
    }

    //Get iterator
    public java.util.Iterator<T> iterator(){
        return new SeqIterator();
    }

    //Private inner class, implement iterator interface
    private class SeqIterator implements java.util.Iterator<T>{

        int index = -1;//Current element sequence number
        int succ = 0;//Subsequent element No

        //Returns true if there are subsequent elements
        @Override
        public boolean hasNext() {
            return this.succ < SeqList.this.len;//SeqList.this.len is the member variable of the current instance of the external class
        }

        //Returns a successor element, or null if there is no successor element
        @Override
        public T next() {
            T value = SeqList.this.get(this.succ);//Call member method of current instance of external class SeqList
            if(value != null){
                this.index = this.succ++;
                return value;
            }
            throw new java.util.NoSuchElementException();//Throw an exception without this element
        }

        //Delete the current element of the collection represented by the iterator object
        @Override
        public void remove() {
            if(this.index >= 0 && this.index < SeqList.this.len){
                SeqList.this.remove(this.index);//Call member method of current instance of external class
                SeqList.this.len--;//Delete the index element, length SeqList.this.len-1
                if(this.succ > 0)//(this.index < this.succ)
                    this.succ--;
                this.index = -1;//Settings cannot be deleted continuously
            }else{
                throw new java.lang.IllegalStateException();//Throw invalid status exception
            }
        }
    }
}

Test:

package pers.zhang.linearList;

/**
 * @author zhang
 * @date 2020/1/13 - 18:13
 */
public class SeqList_ex {
    public static Integer[] random(int n)              //Returns an array that produces n random numbers
    {
        Integer[] elements = new Integer[n];
        for (int i=0; i<n; i++)
            elements[i] = new Integer((int)(Math.random()*100));   //Generate random number
        return elements;
    }

    public static void main(String args[])
    {
        //Sequence table
/*        SeqList<String> lista = new SeqList<String>(4);    //Execute default construction method
        for (int i=5; i>=0; i--)
            lista.insert(i, new String((char)('A'+i)+"")); //Capacity expansion
        System.out.println("lista: "+lista.toString());
        SeqList<String> listb = new SeqList<String>(lista);//Execute copy construction method
        System.out.println("listb: "+listb.toString());
        lista.set(3, new String((char)(lista.get(3).charAt(0)+32)+""));
        lista.remove(0);
        lista.remove(3);
        lista.remove(10);                                  //Serial number out of range, not deleted
        System.out.println("lista: "+lista.toString());
        System.out.println("listb: "+listb.toString());
        //Because the copy construction method is implemented as array deep copy and object shallow copy, and because Integer is a constant object, new references another object,
        //The result of the above statement can only show that two sequence table objects have their own arrays, and each array element can refer to different objects,
        //But it can't explain the data modification error caused by referencing the same object
*/
        //Deep copy and comparison are equal
        SeqList<Integer> list1 = new SeqList<Integer>();   //Empty table
        System.out.println("list1: "+list1.toString());
        SeqList<Integer> list2 = new SeqList<Integer>();   //Empty table
        System.out.println("list2: "+list2.toString());
        System.out.println("list1.equals(list2)? "+list1.equals(list2));

        list1 = new SeqList<Integer>(random(5));
        System.out.println("list1: "+list1.toString());
        list2 = new SeqList<Integer>(list1);               //Copy construction method
        System.out.println("list2: "+list2.toString());
        System.out.println("list1.equals(list2)? "+list1.equals(list2));

        System.out.println("list1: "+list1.toString());
        list2.set(0, new Integer(list1.get(0).intValue()+100));
        list2.remove(list2.length()-1);                    //Delete last element
        list2.remove(100);                                 //Serial number out of range, not deleted
        System.out.println("list2: "+list2.toString());
        System.out.println("list1.equals(list2)? "+list1.equals(list2));
    }
}

Result:

The running results of the program are as follows:    
//(1) Light copy
lista: (A, F, B, E, C, D) 
listb: (A, F, B, E, C, D) 
lista: (F, B, e, D) 
Exception in thread "main" java.lang.NullPointerException
	at SeqList.toString(SeqList.java:55)
	at SeqList_ex.main(SeqList_ex.java:30)
 
//(2) Deep copy does not indicate the correctness of the deep copy, because String and Integer are the final variables
lista: (A, F, B, E, C, D) 
listb: (A, F, B, E, C, D) 
lista: (F, B, e, D) 
listb: (A, F, B, E, C, D) 

//Deep copy and comparison are equal
list1: () 
list2: () 
list1.equals(list2)? true
list1: (16, 14, 81, 74, 68) 
list2: (16, 14, 81, 74, 68) 
list1.equals(list2)? true
list1: (16, 14, 81, 74, 68) 
list2: (116, 14, 81, 74) 
list1.equals(list2)? false

*/

/*
//Discussion on generic classes:
//The program debugging is as follows:
        SinglyLinkedList<Object> list3 = new SinglyLinkedList<Object>();
//        SortedSinglyLinkedList<Object> list4 = new SortedSinglyLinkedList<Object>();
                                         //Compilation error. The Object class cannot be used as the actual parameter of E, and does not implement the compatible < E > interface
        SortedSinglyLinkedList<Integer> list4 = new SortedSinglyLinkedList<Integer>();
//        list4.insert(new Object()); / / compilation error, parameter type mismatch
578 original articles published, 1800 praised, 220000 visitors+
His message board follow

Tags: Java

Posted on Mon, 13 Jan 2020 09:33:01 -0500 by mars16