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: