# Sequential list and linked list

Posted by rsasalm on Tue, 15 Feb 2022 13:20:42 +0100

# 1, Linear table

Linear table: when data is stored, it is stored continuously according to logic and forms a linear structure (feature: all have the concept of index, and the elements with smaller index must be logically arranged before the elements with larger index)

Linear list subset: sequential list, linked list, stack, queue, string

Linear table storage has two structures:
Array based linear table: sequential table (elements are not only logically continuous, but also physically continuous)
Linear list based on linked list: values are logical continuity between elements

# 2, Sequence table

The basic array problem in java: the length of the array is fixed, and only fixed length values can be stored after declaration
Sequential table: array based linear table - dynamic array (dynamically adjusted according to the size of data)

```package seqlist;
//Array based sequential table
public class MyArray {
//The storage element is still in the array
private  int[] data;
//Actual number of dynamic storage elements in the current array
private  int size;
//data.length - the maximum number of elements stored in the array at this time, and size - the actual space used

//The default number size is 10
public MyArray(){
data = new int[10];
}
//The size of the array that the user wants to pass in
public MyArray(int capacity){
data = new int[capacity];
}
}
```

## CURD four operations: add, delete, query and modify

```addFirst(int val):Insert in array header
addLast(int val):Insert at the end of the array
addIndex(int index, int val){}:Insert in the middle of the array
```

### ①. Print

```//Print the contents of the current array
public String toString(){
String ret = "[";
//Traversal data array
for (int i = 0; i < size; i++) {
//When any number is added with String type, it will automatically become String type
ret+=data[i];
if(i!=size-1) {
ret +=",";
}
}
ret+="]";
return ret;
}
```

### ②. Capacity expansion and tail insertion

To add, consider whether the original array is full, if size = = data Length indicates that it is full, and the capacity should be expanded at this time

```    /**
* Insert at the end of the array
* @param value New element value to be inserted
*/
//First judge whether the current array is full
if (size== data.length){
//The current array is full
//The array needs to be expanded
grow();
}
data[size]=value;
size++;
}
private void grow(){
//The original array is data, and then the capacity is expanded to twice the original size Length < < 1, return a new array after capacity expansion
int[] newData=Arrays.copyOf(this.data,this.data.length<<1);
//Point to the new array after capacity expansion
this.data=newData;
}

```

```    /**
* @param value New element value to be inserted
*/
if(size== data.length){
grow();
}
//First, move the original array one unit backward from the last element
for (int size-1 = 0; i>=0 ; i--) {
data[i+1]=data[i];
}
//At this point, data[0] is empty
data[0]=value;
size++;
}
```

### ④. Index insertion

```/**
* Insert anywhere in the array
* @param index Index value passed in
* @param value New element to insert
*/
public void addIndex(int index ,int value){
//Index < 0 / / index > size, which means that the current valid array ensures continuity and judges the legitimacy of the index
if(index<0||index>size){
return;
}
//Determine whether the array is full
if(size== data.length){
grow();
}
if (index == 0) {
return;
}
if (index == size) {
return;
}
else {
//Empty the index position
for (int i = size-1; i >=index ; i--) {
data[i+1]=data[i];
}
data[index]=value;
size++;
}
}
```

### ⑤. Write test code and results

```public class Test {
public static void main(String[] args) {
MyArray myArray = new MyArray(3);
System.out.println(myArray);
System.out.println(myArray);
System.out.println(myArray);
}
}
```

## 2. Find

```boolean contains(int value):Check whether the current array exists
int get (int index):Get the corresponding position according to the index
int getByValue(int value):Find elements in the current array value Corresponding subscript index
```

### ①.int getByValue(int value)

```/**
* Find the index subscript corresponding to the value value in the array
* @param value
* @return
*/
public int getByValue(int value){
//Traversal array
for (int i = 0; i <size ; i++) {
if(data[i]==value){
return i;
}
}
//At this time, the cycle has not been found
return -1;
}
```

### ②.boolean contains(int value)

```/**
* Check whether value exists
* @param value
* @return
*/
public  boolean contains(int value){
int index=getByValue(value);
if(index==-1){
return false;
}
return true;
}
```

### ③.int get (int index)

```/**
* Query elements by index
* @param  index Index value
* @return
*/
public int get(int index){
//Judge legitimacy
if(index<0||index>=size){
System.err.println("get index illegal!");
return -1;
}
return data[index];
}
```

### ④. Test code and results

```        System.out.println(myArray);
System.out.println(myArray.contains(7));
System.out.println(myArray.getByValue(22));
System.out.println(myArray.get(3));
```

## 3. Change

```Modify the original element according to the index
int set (int index,int newValue): Modify the specified index location element to newValue，Return the element value before modification
```

### ①.int set (int index,int newValue)

``` /**
* Modify the element at the specified index position to newValue and return the element value before modification
* @param index
* @param newValue
* @return
*/
public int set(int index,int newValue){
//Judge legitimacy
if(index<0||index>=size) {
System.err.println("get index illegal!");
return -1;
}else{
int oldValue=data[index];
data[index]=newValue;
return oldValue;
}
}
```

### ②. Test code and results

```        System.out.println(myArray);
//[33,10,22,1,3,5,7,44]
System.out.println(myArray.set(1,100));
System.out.println(myArray);
```

## 4. Delete

``` void removeFirst():Delete header element
void removeLast():Delete tail element
void removeIndex(int index):According to index index Delete element
void removeValueOnce(int value):Delete the value of the first element in the array value Element of
void removeValueAll(int value):Delete all values in the array value Element of
```

### ①. Deletes the element at the specified location

```/**
* Deletes the element at the specified index location
* @param index
*/
public  void removeIndex(int index){
if(index<0||index>=size) {
System.err.println("remove index illegal!");
return;
}
//In order to ensure that data[i+1] still does not cross the boundary, the judgment condition is I < size-1
for (int i = index; i <size-1 ; i++) {
data[i]=data[i+1];
}
size--;
//Delete the last position element of the original array
data[size]=0;
}
```

```    public void removeFirst(){
removeIndex(0);
}
```

### ③. Delete tail element

```   public void removeLast(){
removeIndex(size-1);
}
```

### ④. Delete the element whose value is value once

```   public void removeValueOnce(int value){
for (int i = 0; i <size ; i++) {
if(value==data[i]){
//At this time, the index corresponding to i is the first element with value
removeIndex(i);
return;
}
}

}
```

### ⑤. Delete all elements with value

```public void removeValueAll(in value){
for (int i = 0; i <size; i++) {
//Use while when deleting elements repeatedly
//i!= size in extreme cases, all the following and current elements are deleted
while(value==data[i]&&i!=size){
//At this time, the index corresponding to i is the first element with value
removeIndex(i);
return;
}
}
}
```

### ⑥. Test code and results

```myArray.removeFirst();
myArray.removeLast();
myArray.removeIndex(1);
System.out.println(myArray);
```

## summary

1.MyArray - wrap the array to make it have the function of dynamic capacity expansion
2. When using the println method to output an object, you need to implement toString() in the class where the object is located and set an object - > string
3. Member variable initialization: construction method
4. Dynamic array: ① disadvantages: delete and add O(N) in the header. Capacity expansion: O(N) capacity expansion is a very time-consuming operation. Space complexity: O(N) ② advantages: find the element O(N) according to the index
5. Complete code

```package seqlist;

import com.sun.media.sound.RIFFInvalidDataException;

import java.util.Arrays;

//Array based sequential table
public class MyArray {
//The storage element is still in the array
private  int[] data;
//The number of elements actually stored in the current dynamic array
private  int size;
//data.length - the maximum number of elements stored in the array at this time, and size - the actual space used

//The default number size is 10
public MyArray(){
data = new int[10];
}
//The size of the array that the user wants to pass in
public MyArray(int capacity){
data = new int[capacity];
}

/**
* Insert at the end of the array
* @param value New element value to be inserted
*/
//First judge whether the current array is full
if (size== data.length){
//The current array is full
//The array needs to be expanded
grow();
}
data[size]=value;
size++;
}

/**
* @param value New element value to be inserted
*/
if(size== data.length){
grow();
}
//First, move the original array one unit backward from the last element
for (int i=size-1; i>=0; i--) {
data[i+1]=data[i];
}
//At this point, data[0] is empty
data[0]=value;
size++;
}

/**
* Insert anywhere in the array
* @param index Index value passed in
* @param value New element to insert
*/
public void addIndex(int index ,int value){
//Determine whether the array is full
if(size== data.length){
grow();
}
//Index < 0 / / index > size, which means that the current valid array ensures continuity and judges the legitimacy of the index
if(index<0||index>size){
return;
}
if (index == 0) {
return;
}
if (index == size) {
return;
}
else {
//Empty the index position
for (int i = size-1; i >=index ; i--) {
data[i+1]=data[i];
}
data[index]=value;
size++;
}
}

//Print the contents of the current array
public String toString(){
String ret = "[";
//Traversal data array
for (int i = 0; i < size; i++) {
//When any number is added with String type, it will automatically become String type
ret += data[i];
if(i!=size-1) {
ret +=",";
}
}
ret+="]";
return ret;
}

private void grow(){
//The original array is data, and then the capacity is expanded to twice the original size Length < < 1, return a new array after capacity expansion
int[] newData=Arrays.copyOf(this.data,this.data.length<<1);
//Point to the new array after capacity expansion
this.data=newData;
}

/**
* Find the index subscript corresponding to the value value in the array
* @param value
* @return
*/
public int getByValue(int value){
//Traversal array
for (int i = 0; i <size ; i++) {
if(data[i]==value){
return i;
}
}
//At this time, the cycle has not been found
return -1;
}

/**
* Check whether value exists
* @param value
* @return
*/
public  boolean contains(int value){
int index=getByValue(value);
if(index==-1){
return false;
}
return true;
}

/**
* Query elements by index
* @param  index Index value
* @return
*/
public int get(int index){
//Judge legitimacy
if(index<0||index>=size){
System.err.println("get index illegal!");
return -1;
}
return data[index];
}

/**
* Modify the element at the specified index position to newValue and return the element value before modification
* @param index
* @param newValue
* @return
*/

public int set(int index,int newValue){
//Judge legitimacy
if(index<0||index>=size) {
System.err.println("get index illegal!");
return -1;
}else{
int oldValue=data[index];
data[index]=newValue;
return oldValue;
}
}

/**
* Deletes the element at the specified index location
* @param index
*/
public  void removeIndex(int index){
if(index<0||index>=size) {
System.err.println("remove index illegal!");
return;
}
//In order to ensure that data[i+1] still does not cross the boundary, the judgment condition is I < size-1
for (int i = index; i <size-1 ; i++) {
data[i]=data[i+1];
}
size--;
//Delete the last position element of the original array
data[size]=0;
}

public void removeFirst(){
removeIndex(0);
}

public void removeLast(){
removeIndex(size-1);
}

public void removeValueOnce(int value){
for (int i = 0; i <size ; i++) {
if(value==data[i]){
//At this time, the index corresponding to i is the first element with value
removeIndex(i);
return;
}
}

}

public void removeValueAll(int value){
for (int i = 0; i <size; i++) {
//Use while when deleting elements repeatedly
//i!= size in extreme cases, all the following and current elements are deleted
while((value==data[i]) && (i!=size)){
//At this time, the index corresponding to i is the first element with value
removeIndex(i);
return;
}
}
}
}

```
```package seqlist;

public class Test {
public static void main(String[] args) {
MyArray myArray = new MyArray(3);
System.out.println(myArray);
System.out.println(myArray);
System.out.println(myArray);
//[33,10,22,1,3,5,7,44]

//        System.out.println(myArray.contains(7));
//        //2
//        System.out.println(myArray.getByValue(22));
//        //1
//        System.out.println(myArray.get(3));

//        System.out.println(myArray.contains(7));
//        System.out.println(myArray.getByValue(22));
//        System.out.println(myArray.get(3));

myArray.removeFirst();
myArray.removeLast();
myArray.removeIndex(1);
System.out.println(myArray);
}
}
```

Linked list: logically continuous, multiple nodes are linked by mounting, and physically discontinuous. Analogy: Train
The structure of the train: it is traversed from the beginning to the end of the train

Carriage: a class that specifically stores elements

```class Node{
int data;//Specific storage data
Node next;//Store the address of the next car
}
```

Train: it's a series of carriages put together
Single list: you can only traverse from the head to the tail

```//Single linked list - Trains
class SingList{
int size;//Number of cars
}
```

### ①. Trains and carriages

```package seqlist;

/**
* Trains are spliced by multiple carriages
*/
//Number of nodes in the carriage of the current train (actually the number of specific elements)
private  int size;
//The locomotive of the current train
}

/**
* The carriage class of a train. Only one element can be saved in a carriage
*/
class Node{
//Store specific data
int val;
//Save the address of the next carriage
Node next;
public  Node (int val){
this.val=val;
}
}
```

``` /**
* Add an element at the head of the train - add a node for the car
* @param val
*/
//Create a new carriage node
Node node = new Node(val);
//Judge whether the current train is empty
}else {
//There are nodes in the train. The current new carriage should be attached to the head of the train
}
size++;
}
```

### ③. toString method

```    public String toString(){
String ret="";
//Traverse this class
//Walk from the head to the tail of the train
while(node!=null){
ret+=node.val;
ret+="->";
//Continue to access the next node;
node=node.next;
}
//Indicates that you have reached the end
ret+="NULL";
return ret;
}
```

### ④. Insert anywhere

```/**
* Insert the element val at any index position in the single list
* @param index
* @param val
*/
//1. Legality
if (index<0|index>size){
return ;
}
if (index==0){
return;
}
//2. Insert element
Node node = new Node(val);
//You need to find the to be inserted
for (int i = 0; i < index-1; i++) {
prev=prev.next;
}
//At this time, prev points to the precursor node at the position to be inserted
node.next=prev.next;
prev.next=node;
size++;
}
```

### ⑤. Tail interpolation

```    /**
* Insert elements at the end of a single list
* @param index
* @param val
*/
}

//Test code
//1,10,2,3->NULL
```

## 2. Find:

```get(int index):return index Element value of position//Legitimacy, index < 0 | index > = size
contains(int value):The query value is value Does the element of exist in the single linked list
```

### ①. Judge legitimacy

```    /**
* Judge whether the index entered by the user is legal (change, check, delete and use)
* @param index
* @return
*/
private boolean rangeCheck(int index){
if (index < 0||index>=size) {
return false;
}
return true;
}
```

### ②. get(int index) method

``` public int get(int index){
if (rangeCheck(index)){
//index legal
//Traverse the linked list from the node to the index position
//Specifies the number of steps to take
for (int i = 0; i < index; i++) {
node =node.next;
}
return node.val;
}else{
System.err.println("get index illegal!");
return -1;
}
}
```

### ②. contains(int value) method

``` /**
* Judge whether there are nodes with value val in the current linked list
* @param val
* @return
*/
public boolean contains(int val){
for (Node temp= head; temp!=null ; temp=temp.next) {
if(temp.val==val){
return true;
}
}
return false;
}
```

## 3. Change:

```set(int index,int newValue):modify index The value of the location is newValue//Legitimacy Ә < index Ә
```

### ①. set(int index,int newValue) method

```  /**
* Change the node value of the single linked list index to newVal
* @param index
* @param newVal
* @return
*/
public int set(int index,int newVal){
if (rangeCheck(index)) {
for (int i = 0; i <index ; i++) {
node=node.next;
}
int oldVal= node.val;
node.val=newVal;
return oldVal;
}else{
System.err.println("set index illegal!");
return -1;
}
}
```

### ②. Test code

```  SingleLinkedList singleLinkedList=new SingleLinkedList();
//1,10,2,3->NULL
//2
//false
```

## 4. Delete:

```removeIndex(int index)；//Delete index node
removeValueOnce(int value);//Delete the first node with value in the single linked list
removeValueAll(int value);//Delete all nodes with value in the single linked list
```

In the insertion and deletion of a single linked list, you need to find the precursor node. Only the head node has no precursor node, so it needs special treatment

### ①. removeIndex(int index) code

```public void removeIndex(int index){
//Legitimacy
if(rangeCheck(index)) {
if (index == 0) {
temp.next = null;
size--;
} else {
//index middle position
//Find precursor node
for (int i = 0; i < index - 1; i++) {
prev = prev.next;
}
//Node to be deleted
Node cur = prev.next;
prev.next = cur.next;
cur.next = null;
size--;
}
}else{
System.err.println("remove index illegal!");
}
}

public void removeFirst(){
removeIndex(0);
}

public  void removeLast(){
removeIndex(size-1);
}

```

### ②. removeValueOnce(int value) code

``` /**
* Delete the element to be deleted that appears for the first time in the linked list
* @param val
*/
public void removeValueOnce(int val){
//Traverse the linked list and find the node with value val
//Find the deleted node (the precursor should be found for normal deletion, only the head node has no precursor)
//The head node is the node to be deleted
temp.next=null;
size--;
}else{
//At this time, the head must not be the node to be deleted
//Judge whether the next node of the precursor is equal to val
//You can judge which reference is not empty according to which reference you use
while(prev.next!=null) {//There is a null pointer problem
if (prev.next.val == val) {
Node cur=prev.next;
prev.next=cur.next;
cur.next=null;
size--;
return;
}
prev=prev.next;
}
}
}

```

### ③. removeValueAll(int value) code

``` public void removeIndexAll(int val){
size--;
}
//At this time, all the values in the linked list are val
return ;
}else{
//At this time, the head must not be the node to be deleted, and there are nodes in the linked list
while(prev.next!=null){
if (prev.next.val == val) {
Node cur=prev.next;
prev.next=cur.next;
cur.next=null;
size--;
}else{
//Only ensure prev The next is not a node to be deleted before the prev point can be moved
//prev must not be the node to be deleted
prev=prev.next;
}
}
}
}
```

## 4. Complete code:

```package seqlist;

import java.rmi.ServerError;

/**
* Trains are spliced by multiple carriages
*/
//Number of nodes in the carriage of the current train (actually the number of specific elements)
private  int size;
//The locomotive of the current train

/**
* Add an element at the head of the train - add a node for the car
* @param val
*/
//Create a new carriage node
Node node = new Node(val);
//Judge whether the current train is empty
}else {
//There are nodes in the train. The current new carriage should be attached to the head of the train
}
size++;
}

/**
* Insert the element val at any index position in the single list
* @param index
* @param val
*/
//1. Legality
if (index<0|index>size){
return ;
}
if (index==0){
return;
}
//2. Insert element
Node node = new Node(val);
//You need to find the to be inserted
for (int i = 0; i < index-1; i++) {
prev=prev.next;
}
//At this time, prev points to the precursor node at the position to be inserted
node.next=prev.next;
prev.next=node;
size++;
}

/**
* Insert elements at the end of a single list
* @param in dex
* @param val
*/
}

public String toString(){
String ret="";
//Traverse the train class
//Walk from the head to the tail of the train
while(node!=null){
ret+=node.val;
ret+="->";
//Continue to access the next node;
node=node.next;
}
//Indicates that you have reached the end
ret+="NULL";
return ret;
}

/**
* Judge whether the index entered by the user is legal (change, check, delete and use)
* @param index
* @return
*/
private boolean rangeCheck(int index){
if (index < 0||index>=0) {
return false;
}
return true;
}

public int get(int index){
if (rangeCheck(index)){
//index legal
//Traverse the linked list from the node to the index position
//Specifies the number of steps to take
for (int i = 0; i < index; i++) {
node =node.next;
}
return node.val;
}else{
System.err.println("get index illegal!");
return -1;
}
}

/**
* Judge whether there are nodes with value val in the current linked list
* @param val
* @return
*/
public boolean contains(int val){
for (Node temp= head; temp!=null ; temp=temp.next) {
if(temp.val==val){
return true;
}
}
return false;
}

/**
* Change the node value of the single linked list index to newVal
* @param index
* @param newVal
* @return
*/
public int set(int index,int newVal){
if (rangeCheck(index)) {
for (int i = 0; i <index ; i++) {
node=node.next;
}
int oldVal= node.val;
node.val=newVal;
return oldVal;
}else{
System.err.println("set index illegal!");
return -1;
}
}

}

/**
* The carriage class of a train. Only one element can be saved in a carriage
*/
class Node{
//Store specific data
int val;
//Save the address of the next carriage
Node next;

public  Node (int val){
this.val=val;
}
}
```
```package seqlist;

public class Test {
public static void main(String[] args) {
//        MyArray myArray = new MyArray(3);
//        System.out.println(myArray);
//        System.out.println(myArray);
//        System.out.println(myArray);
//        //[33,10,22,1,3,5,7,44]

//        System.out.println(myArray.contains(7));
//        //2
//        System.out.println(myArray.getByValue(22));
//        //1
//        System.out.println(myArray.get(3));

//        System.out.println(myArray.contains(7));
//        System.out.println(myArray.getByValue(22));
//        System.out.println(myArray.get(3));

//        myArray.removeFirst();
//        myArray.removeLast();
//        myArray.removeIndex(1);
//        System.out.println(myArray);

//        The users are trains

//1,10,2,3->NULL
//2
//false

}
}
```

# 3, Exercises

Give you a head node of the linked list and an integer val. please delete all nodes in the linked list that meet the requirements Val = = Val node and returns a new header node.

Method 1: conventional solution

```package leetcode;

/**
* LeetCode Question no. 203-
* Delete all nodes in the linked list Val = = Val node and returns a new header node
*/
public class Num203 {
public ListNode removeElements(ListNode head, int val) {
//The head node is the node to be deleted
}
return null;
}else{
//The head node must not be the node to be deleted and the linked list is not empty
while(prev.next!=null){
if(prev.next.val==val){
ListNode cur=prev.next;
prev.next=cur.next;
}else{
//Only when prev next. val!= val
prev=prev.next;
}
}
}
}
}

```

Method 2: using recursive method

```  //Recursive method
public class Num203 {
public ListNode removeElements(ListNode head, int val) {