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
1. Add:
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 */ public void addLast(int value){ //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; }
③. Head insert
/** * Insert in array header * @param value New element value to be inserted */ public void addFirst(int value){ if(size== data.length){ grow(); } //Insert in array header //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){ System.err.println("add inedx illegal!"); return; } //Determine whether the array is full if(size== data.length){ grow(); } if (index == 0) { addFirst(value); return; } if (index == size) { addLast(value); 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); myArray.addLast(1); myArray.addLast(3); myArray.addLast(5); myArray.addLast(7); System.out.println(myArray); myArray.addFirst(10); System.out.println(myArray); myArray.addIndex(1,22); myArray.addIndex(0,33); myArray.addIndex(7,44); myArray.addIndex(10,55); 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; }
②. Delete header element
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 */ public void addLast(int value){ //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++; } /** * Insert in array header * @param value New element value to be inserted */ public void addFirst(int value){ if(size== data.length){ grow(); } //Insert in array header //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){ System.err.println("add inedx illegal!"); return; } if (index == 0) { addFirst(value); return; } if (index == size) { addLast(value); 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); myArray.addLast(1); myArray.addLast(3); myArray.addLast(5); myArray.addLast(7); System.out.println(myArray); myArray.addFirst(10); System.out.println(myArray); myArray.addIndex(1,22); myArray.addIndex(0,33); myArray.addIndex(7,44); 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
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 Node head;//Address of the first carriage (head node) }
1. Add:
①. Trains and carriages
package seqlist; /** * Trains are spliced by multiple carriages */ public class SingleLinkedList { //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 private Node head; } /** * 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; } }
②. Head insertion
/** * Add an element at the head of the train - add a node for the car * @param val */ public void addFirst(int val){ //Create a new carriage node Node node = new Node(val); //Judge whether the current train is empty if(head==null){ head =node; }else { //There are nodes in the train. The current new carriage should be attached to the head of the train node.next=head; head=node; } size++; }
③. toString method
public String toString(){ String ret=""; //Traverse this class //Walk from the head to the tail of the train //Temporarily store the current header node address Node node =head; 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 */ public void addIndex(int index,int val){ //1. Legality if (index<0|index>size){ System.err.println("add index illegal!"); return ; } //Head insertion if (index==0){ addFirst(val); return; } //2. Insert element Node node = new Node(val); //You need to find the to be inserted Node prev = head; 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 */ public void addLast(int val){ addIndex(size,val); } //Test code SingleLinkedList singleLinkedList=new SingleLinkedList(); singleLinkedList.addLast(1); singleLinkedList.addLast(2); singleLinkedList.addLast(3); singleLinkedList.addIndex(1,10); //1,10,2,3->NULL System.out.println(singleLinkedList);
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 Node node=head; //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)) { Node node=head; 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(); singleLinkedList.addLast(1); singleLinkedList.addLast(2); singleLinkedList.addLast(3); singleLinkedList.addIndex(1,10); //1,10,2,3->NULL System.out.println(singleLinkedList); //2 System.out.println(singleLinkedList.get(2)); //false System.out.println(singleLinkedList.contains(100)); singleLinkedList.set(2,200); System.out.println(singleLinkedList);
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) { //Delete header node from boundary Node temp = head; head = head.next; temp.next = null; size--; } else { //index middle position //Find precursor node Node prev = head; 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) if(head.val==val){ //The head node is the node to be deleted Node temp=head; head=head.next; temp.next=null; size--; }else{ //At this time, the head must not be the node to be deleted Node prev=head; //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){ while(head!=null&&head.val==val){ head=head.next; size--; } if(head==null){ //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 Node prev=head; 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 */ public class SingleLinkedList { //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 private Node head; /** * Add an element at the head of the train - add a node for the car * @param val */ public void addFirst(int val){ //Create a new carriage node Node node = new Node(val); //Judge whether the current train is empty if(head == null){ head =node; }else { //There are nodes in the train. The current new carriage should be attached to the head of the train node.next=head; head=node; } size++; } /** * Insert the element val at any index position in the single list * @param index * @param val */ public void addIndex(int index,int val){ //1. Legality if (index<0|index>size){ System.err.println("add index illegal!"); return ; } //Head insertion if (index==0){ addFirst(val); return; } //2. Insert element Node node = new Node(val); //You need to find the to be inserted Node prev = head; 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 void addLast(int val){ addIndex(size,val); } public String toString(){ String ret=""; //Traverse the train class //Walk from the head to the tail of the train //Temporarily store the current header node address Node node =head; 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 Node node=head; //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)) { Node node=head; 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); // myArray.addLast(1); // myArray.addLast(3); // myArray.addLast(5); // myArray.addLast(7); // System.out.println(myArray); // myArray.addFirst(10); // System.out.println(myArray); // myArray.addIndex(1,22); // myArray.addIndex(0,33); // myArray.addIndex(7,44); // 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 // SingleLinkedList singleLinkedList = new SingleLinkedList(); // singleLinkedList.addFirst(1); // singleLinkedList.addFirst(3); // singleLinkedList.addFirst(5); // System.out.println(singleLinkedList); SingleLinkedList singleLinkedList=new SingleLinkedList(); singleLinkedList.addLast(1); singleLinkedList.addLast(2); singleLinkedList.addLast(3); singleLinkedList.addIndex(1,10); //1,10,2,3->NULL System.out.println(singleLinkedList); //2 System.out.println(singleLinkedList.get(2)); //false System.out.println(singleLinkedList.contains(100)); singleLinkedList.set(2,200); System.out.println(singleLinkedList); } }
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 while(head!=null&&head.val==val){ head=head.next; } if (head == null) { return null; }else{ //The head node must not be the node to be deleted and the linked list is not empty ListNode prev=head; 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; } } } return head; } }
Method 2: using recursive method
//Recursive method public class Num203 { public ListNode removeElements(ListNode head, int val) { if(head==null){ return null; } //Will have Next and subsequent nodes are handled and handed over to removeElements(head.next,val) head.next=removeElements(head.next,val); //Handle the next header node by yourself if (head.val == val) { return head.next; } return head; } }