Summary of basic knowledge of 60000 word data structure (including written examination and interview exercises)

Posted by johnie on Sat, 25 Dec 2021 23:01:16 +0100

catalogue

preface

1, Time complexity and space complexity

1. Algorithm efficiency

2. Time complexity

① Concept of time complexity

② Asymptotic representation of large O

③ Common time complexity calculation examples

3. Spatial complexity

2, Linear list (single linked list and double linked list)

1. Concept

2. Sequence table

① Concept

② Interface implementation

③ Create sequence table

④ Print sequence table

⑤ Gets the effective length of the sequence table

⑥ Add element in pos position

⑦ Judge whether to find the corresponding position of an element. If not, return - 1

⑧ Get the element of pos position and set / update the element of pos position to value

⑨ Delete the keyword key that appears for the first time

3. Linked list

① Concept

② Implementation of linked list

③ Create node

④ Create linked list and print linked list

⑤ Find out whether the keyword key is included, whether the key is in the single linked list, and get the length of the single linked list

⑥ head insertion method and tail insertion method

⑦ Find the address of the node at index-1 and insert the element

⑧ Find the precursor of the keyword to be deleted and delete the node whose keyword is key for the first time

⑨ Delete all nodes with the value of key

⑩ clear the linked list

4. Bidirectional linked list

① Implementation of linked list

② Construct nodes and linked lists

③ Print the linked list and calculate the length of the linked list

④ Query key

⑤ Head insertion

⑥ Tail interpolation

⑦ Find insert node

⑧ Insert element

⑨ Delete element

⑩ Empty linked list

5. Written test exercises

① Reverse a single linked list

② Given a non empty single linked list with head node, return the intermediate node of the linked list

③ Input a linked list and output the penultimate node in the linked list

④ Delete multiple duplicate values in the linked list

⑤ Palindrome structure of linked list

⑥ Merge two linked lists

⑦ Enter two linked lists and find their first common node

⑧ Determine whether a linked list has a ring

⑨ Find the first node of a linked list

3, Stack and queue

1. Stack

① Concept

② Stack operation

③ Implementation of stack

④ Implement mystack

2. Queue

① Concept

② Implementation of queue

③ Implement myqueue

4, Binary tree

1. Tree

① Concept

② Basic concepts of tree

2. Binary tree

① Concept

② Two special binary trees

③ Properties of binary tree

① Traversal of binary tree

② Preorder traversal

③ middle order traversal

④ Postorder traversal

3. Binary search tree

① Concept

② Action - find

③ Operation - insert

④ operation - delete

⑤ Performance analysis

4. Written test exercises

① Preorder traversal of binary tree

② Order traversal in binary tree

③ Postorder traversal of binary tree

④ Check whether the two trees are the same

⑤ Maximum depth of binary tree

⑥ A subtree of another tree

⑦ Judge whether a tree is a balanced binary tree

⑧ Symmetric binary tree

⑨ Binary tree image

5, Priority queue (heap)

1. Sequential storage of binary tree

① Storage mode

② Subscript relation

③ Binary tree sequential traversal

2. Reactor

① Concept

② Operation - downward adjustment

③ Pile building (taking pile building as an example)

3. Heap application - priority queue

① Concept

② Internal principle

③ Queue

④ Out of queue (highest priority)

⑤ Return to the first element of the queue (highest priority)

4. Heap sorting

6, Sort

1. Concept

① Sort

② Stability

2. Detailed sorting

① Direct insert sort

② Hill sort

③ Direct selection sort

④ Heap sort

⑤ Bubble sorting

⑥ Quick sort

⑦ Merge sort

7, List

1. Introduction to ArrayList

① Construction of ArrayList

② ArrayList common operations

③ Traversal of ArrayList

8, Map and Set

1. Search

① Concept and scenario

② Model

2. Use of Map

① Description of Map

② About map Description of entry

③ Description of common methods of Map

3. Use of Set

① Description of common methods

② Use case of TreeSet

preface

As a difficult subject to learn, data structure is also a subject that we as programmers must firmly grasp in the future. We should draw more pictures and write more code in order to gain something. This blog can be used as an entry-level teaching. There will be diagrams and detailed code in it. The summary content represents our personal point of view, There are some data structure contents that are not summarized, but enough to learn as a beginner of data structure, as well as detailed explanations of written test questions of various large factories. The content of this blog is long and it is recommended to collect it. If you think this blog is good, please praise and collect it. It's not easy to make it and don't talk too much nonsense. Let's learn it!!!

1, Time complexity and space complexity

1. Algorithm efficiency

There are two kinds of algorithm efficiency analysis: the first is time efficiency and the second is space efficiency. Time efficiency is called time complexity, and space efficiency is called space complexity. Time complexity mainly measures the running speed of an algorithm, while space complexity mainly measures the additional space required by an algorithm. In the early stage of computer development, the storage capacity of the computer is very small. So I care about the degree of space. However, with the rapid development of computer industry, the storage capacity of computer has reached a high level. Therefore, we no longer need to pay special attention to the spatial complexity of an algorithm.

2. Time complexity

① Concept of time complexity

Definition of time complexity: in computer science, the time complexity of an algorithm is a function that quantitatively describes the running time of the algorithm. In theory, the time spent in the execution of an algorithm cannot be calculated. You can only know when you put your program on the machine and run it. But do we need every algorithm to be tested on the computer? Yes, it can be tested on the computer, but it is very troublesome, so there is the analysis method of time complexity. The time spent by an algorithm is directly proportional to the execution times of the statements in it. The execution times of the basic operations in the algorithm is the time complexity of the algorithm.

② Asymptotic representation of large O

void func1(int N){
   int count = 0;
   for (int i = 0; i < N ; i++) {
       for (int j = 0; j < N ; j++) {
           count++;
       }
   }
   for (int k = 0; k < 2 * N ; k++) {
       count++;
   }
   int M = 10;
  while ((M--) > 0) {
       count++;
   }
  System.out.println(count);
}

Please calculate how many times func1 basic operations have been performed?

Number of basic operations performed by Func1:

N = 10 F(N) = 130

N = 100 F(N) = 10210

N = 1000 F(N) = 1002010

In fact, when we calculate the time complexity, we do not have to calculate the exact execution times, but only the approximate execution times. Here, we use the asymptotic representation of large O.

Big O notation: a mathematical symbol used to describe the asymptotic behavior of a function.

Derivation of large O-order method:

1. Replace all addition constants in the run time with constant 1.

2. In the modified run times function, only the highest order term is retained.

3. If the highest order term exists and is not 1, the constant multiplied by this item is removed. The result is large O-order.

After using the progressive representation of large O, the time complexity of Func1 is:

O(N^2)

N = 10 F(N) = 100

N = 100 F(N) = 10000

N = 1000 F(N) = 1000000

From the above, we can find that the progressive representation of big O removes those items that have little impact on the results, and succinctly represents the execution times. In addition, the time complexity of some algorithms has the best, average and worst cases:

Worst case: maximum number of runs of any input scale (upper bound)

Average case: expected number of runs of any input scale

Best case: minimum number of runs of any input scale (lower bound)

In practice, we usually focus on the worst-case operation of the algorithm, so the time complexity of searching data in the array is O(N)

③ Common time complexity calculation examples

void func2(int N) {
    int count = 0;
    for (int k = 0; k < 2 * N ; k++) {
    count++;
}
    int M = 10;
    while ((M--) > 0) {
    count++;
}
    System.out.println(count);
}

void func3(int N, int M) {
     int count = 0;
for (int k = 0; k < M; k++) {
     count++;
}
for (int k = 0; k < N ; k++) {
     count++;
}
     System.out.println(count);
}

void func4(int N) {
   int count = 0;
   for (int k = 0; k < 100; k++) {
   count++;
}
   System.out.println(count);
}

void bubbleSort(int[] array) {
   for (int end = array.length; end > 0; end--) {
       boolean sorted = true;
       for (int i = 1; i < end; i++) {
           if (array[i -1] > array[i]) {
       Swap(array, i - 1, i);
               sorted = false;
           }
       }
       if (sorted == true) {
           break;
       }
   }
}

int binarySearch(int[] array, int value) {
   int begin = 0;
   int end = array.length - 1;
   while (begin <= end) {
       int mid = begin + ((end-begin) / 2);
       if (array[mid] < value)
           begin = mid + 1;
       else if (array[mid] > value)
           end = mid - 1;
       else
           return mid;
   }
   return -1;
}

long factorial(int N) {
 return N < 2 ? N : factorial(N-1) * N;
}

// Computing the time complexity of fibonacci recursive fibonacci?
int fibonacci(int N) {
 return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
}

3. Spatial complexity

Space complexity is a measure of the amount of storage space temporarily occupied by an algorithm during operation. Space complexity is not how many bytes the program occupies, because it doesn't make much sense, so space complexity is the number of variables. The calculation rules of spatial complexity are basically similar to the practical complexity, and the large O asymptotic representation is also used.

// Calculate the spatial complexity of bubbleSort?
void bubbleSort(int[] array) {
for (int end = array.length; end > 0; end--) {
     boolean sorted = true;
     for (int i = 1; i < end; i++) {
         if (array[i - 1] > array[i]) {
             Swap(array, i - 1, i);
             sorted = false;
         }
     }
     if (sorted == true) {
         break;
     }
 }
}

A constant number of extra spaces are used, so the space complexity is O(1)

// How to calculate the spatial complexity of fibonacci?
int[] fibonacci(int n) {
long[] fibArray = new long[n + 1];
fibArray[0] = 0;
fibArray[1] = 1;
for (int i = 2; i <= n ; i++) {
  fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
 }
return fibArray;
}

N spaces are opened up dynamically, and the space complexity is O(N)

// The time complexity of computing Factorial recursive Factorial?
long factorial(int N) {
 return N < 2 ? N : factorial(N-1)*N;
}

Recursively called N times, opened up N stack frames, and each stack frame uses a constant space. Space complexity is O(N)

2, Linear list (single linked list and double linked list)

1. Concept

linear list is a finite sequence of n data elements with the same characteristics. linear list is a data structure widely used in practice. Common linear lists include sequential list, linked list, stack, queue and string

A linear table is logically a linear structure, that is, a continuous straight line. However, the physical structure is not necessarily continuous. When the linear table is stored physically, it is usually stored in the form of array and chain structure.

2. Sequence table

① Concept

Sequential table is a linear structure in which data elements are stored in sequence with a storage unit with continuous physical addresses. Generally, array storage is used. Complete the addition, deletion, query and modification of data on the array.

The sequence table can generally be divided into:

Static sequential table: use fixed length array storage.

Dynamic sequential table: use dynamic array storage.

The static sequence table is suitable for scenarios where you know how much data needs to be stored

The fixed length array of static sequence table leads to large N, waste of space and insufficient space

In contrast, the dynamic sequential table is more flexible and dynamically allocates space according to needs.

② Interface implementation

class SeqList {
    // Print sequence table
    public void display() {
        
    }
    // Add new element in pos position
    public void add(int pos, int data) {
        
    }
    // Determines whether an element is included
    public boolean contains(int toFind) {
        
        return true; 
    }
    // Find the location of an element
    public int search(int toFind) {
        return -1; 
        
    }
    // Gets the element of the pos location
    public int getPos(int pos) { 
        return -1; 
    
    }
    // Set the element of pos position to value
    public void setPos(int pos, int value) {
        
        
    }
    //Delete the keyword key that appears for the first time
    public void remove(int toRemove) {
        
    }
    // Get sequence table length
    public int size() {
        return 0; 
    
    }
    // Empty sequence table
    public void clear() {
        
    }
}

③ Create sequence table

    public int[] elem;
    public int usedSize;//Number of valid data
 
    public MyArrayList() {
        this.elem = new int[10];
    }

④ Print sequence table

 // Print sequence table
    public void display() {
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(this.elem[i]+" ");
        }
        System.out.println();
    }

⑤ Gets the effective length of the sequence table

// Gets the valid data length of the sequence table
    public int size() {
        return this.usedSize;
    }

⑥ Add element in pos position

 

public boolean isFull() {
        return this.usedSize == this.elem.length;
    }
    // Add new element in pos position
    public void add(int pos, int data) {
        if(pos < 0 || pos > usedSize) {
            System.out.println("pos Illegal location!");
            return;
        }
        if(isFull()) {
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        //3,
        for (int i = this.usedSize-1; i >= pos ; i--) {
            this.elem[i+1] = this.elem[i];
        }
        this.elem[pos] = data;
        this.usedSize++;
    }
public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(0,1);
        myArrayList.add(1,2);
        myArrayList.add(2,3);
        myArrayList.add(3,4);
        myArrayList.display();
}

⑦ Judge whether to find the corresponding position of an element. If not, return - 1

  // Determines whether an element is included
    public boolean contains(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if(this.elem[i] == toFind) {
                return true;
            }
        }
        return false;
    }
 public int search(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if(this.elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }

⑧ Get the element of pos position and set / update the element of pos position to value

 public int getPos(int pos) {
        if(pos < 0 || pos >= this.usedSize) {
            System.out.println("pos Illegal location");
            return -1;//So let's explain here that exceptions can be thrown in the later stage of business processing
        }
        if(isEmpty()) {
            System.out.println("Sequence table is empty!");
            return -1;
        }
        return this.elem[pos];
    }
public boolean isEmpty() {
        return this.usedSize==0;
    }
 public void setPos(int pos, int value) {
        if(pos < 0 || pos >= this.usedSize) {
            System.out.println("pos Illegal location");
            return;
        }
        if(isEmpty()) {
            System.out.println("Sequence table is empty!");
            return;
        }
        this.elem[pos] = value;
    }

⑨ Delete the keyword key that appears for the first time

 public void remove(int toRemove) {
        if(isEmpty()) {
            System.out.println("Sequence table is empty!");
            return;
        }
        int index = search(toRemove);
        if(index == -1) {
            System.out.println("There are no numbers you want to delete!");
            return;
        }
        for (int i = index; i < this.usedSize-1; i++) {
            this.elem[i] = this.elem[i+1];
        }
        this.usedSize--;
        //this.elem[usedSize] = null;  If there is a reference data type in the array.
    }
public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(0,1);
        myArrayList.add(1,2);
        myArrayList.add(2,3);
        myArrayList.add(3,4);
        myArrayList.remove(3);
        myArrayList.display();
 
    }

3. Linked list

① Concept

Linked list is a discontinuous storage structure in physical storage structure. The logical order of data elements is realized through the reference link order in the linked list.

Linked list classification

② Implementation of linked list

// 1. Implementation of headless one-way acyclic linked list
public class SingleLinkedList {
     //Head insertion
 
}
     public void addFirst(int data){
     //Tail interpolation
}
     public void addLast(int data){
     //Insert at any position, and the first data node is subscript 0
 
}
     public boolean addIndex(int index,int data){
     //Find out whether the keyword is included and whether the key is in the single linked list
 
}
     public boolean contains(int key){
     //Delete the node whose keyword is key for the first time
 
}
     public void remove(int key){
     //Delete all nodes with the value of key
 
}
     public void removeAllKey(int key){
     //Get the length of the single linked list
 
}
     public int size(){
 
}
     public void display(){
 
}
     public void clear(){
 
}
 }

③ Create node

 public ListNode head;//Header reference of linked list
lass ListNode {
    public int val;
    public ListNode next;//null
 
    public ListNode(int val) {
        this.val = val;
    }

④ Create linked list and print linked list

 public void createList() {
        ListNode listNode1 = new ListNode(12);
        ListNode listNode2 = new ListNode(23);
        ListNode listNode3 = new ListNode(34);
        ListNode listNode4 = new ListNode(45);
        ListNode listNode5 = new ListNode(56);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        listNode3.next = listNode4;
        listNode4.next = listNode5;
        //listNode5.next = null;
        this.head = listNode1;
    }
public void display() {
        //this.head.next != null
        ListNode cur = this.head;
        while (cur != null) {
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }
  public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        //myLinkedList.createList();
        myLinkedList.addLast(12);
        myLinkedList.addLast(23);
        myLinkedList.addLast(34);
        myLinkedList.addLast(45);
        myLinkedList.addLast(56);
        myLinkedList.display();
 
       
    }

⑤ Find out whether the keyword key is included, whether the key is in the single linked list, and get the length of the single linked list

public boolean contains(int key){
        ListNode cur = this.head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }
  public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        //myLinkedList.createList();
        myLinkedList.addLast(12);
        myLinkedList.addLast(23);
        myLinkedList.addLast(34);
        myLinkedList.addLast(45);
        myLinkedList.addLast(56);
        myLinkedList.display();
        boolean flg = myLinkedList.contains(56);
 
    }
public int size(){
        int count = 0;
        ListNode cur = this.head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }
public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        //myLinkedList.createList();
        myLinkedList.addLast(12);
        myLinkedList.addLast(23);
        myLinkedList.addLast(34);
        myLinkedList.addLast(45);
        myLinkedList.addLast(56);
        System.out.println(myLinkedList.size());
        
    }

⑥ head insertion method and tail insertion method

//Head insertion
    public void addFirst(int data){
        ListNode node = new ListNode(data);
        node.next = this.head;
        this.head = node;
        /*if(this.head == null) {
            this.head = node;
        }else {
            node.next = this.head;
            this.head = node;
        }*/
    }
 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        //myLinkedList.createList();
        myLinkedList.addLast(12);
        myLinkedList.addLast(23);
        myLinkedList.addLast(34);
        myLinkedList.addLast(45);
        myLinkedList.addLast(56);
        myLinkedList.addFirst(10);
        myLinkedList.display();
    }

  //Tail interpolation
    public void addLast(int data){
        ListNode node = new ListNode(data);
        if(this.head == null) {
            this.head = node;
        }else {
            ListNode cur = this.head;
            while (cur.next != null) {
                cur = cur.next;
            }
            //cur.next == null;
            cur.next = node;
        }
    }
 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        //myLinkedList.createList();
        myLinkedList.addLast(12);
        myLinkedList.addLast(23);
        myLinkedList.addLast(34);
        myLinkedList.addLast(45);
        myLinkedList.addLast(56);
        myLinkedList.addLast(90);
        myLinkedList.display();
    }

⑦ Find the address of the node at index-1 and insert the element

 public ListNode findIndex(int index) {
        ListNode cur = this.head;
        while (index-1 != 0) {
            cur = cur.next;
            index--;
        }
        return cur;
    }

//Insert at any position, and the first data node is subscript 0
    public void addIndex(int index,int data){
        if(index < 0 || index > size()) {
            System.out.println("index Illegal location!");
            return;
        }
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = findIndex(index);
        ListNode node = new ListNode(data);
        node.next = cur.next;
        cur.next = node;
    }
public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        //myLinkedList.createList();
        myLinkedList.addLast(12);
        myLinkedList.addLast(23);
        myLinkedList.addLast(34);
        myLinkedList.addLast(45);
        myLinkedList.addLast(56);
        myLinkedList.addLast(90);
        myLinkedList.addIndex(2,20);
        myLinkedList.display();
    }

⑧ Find the precursor of the keyword to be deleted and delete the node whose keyword is key for the first time

 public ListNode searchPerv(int key) {
        ListNode cur = this.head;
        while (cur.next != null) {
            if(cur.next.val == key) {
                return cur;
            }
            cur = cur.next;
        }
        return null;
    }

//Delete the node whose keyword is key for the first time
    public void remove(int key){
        if(this.head == null) {
            System.out.println("The single linked list is empty and cannot be deleted!");
            return;
        }
        if(this.head.val == key) {
            this.head = this.head.next;
            return;
        }
        ListNode cur = searchPerv(key);
        if(cur == null) {
            System.out.println("There is no node you want to delete!");
            return;
        }
        ListNode del = cur.next;
        cur.next = del.next;
    }
  public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        //myLinkedList.createList();
        myLinkedList.addLast(12);
        myLinkedList.addLast(23);
        myLinkedList.addLast(34);
        myLinkedList.addLast(45);
        myLinkedList.addLast(56);
        myLinkedList.addLast(90);
        myLinkedList.remove(23);
        myLinkedList.display();
    }

⑨ Delete all nodes with the value of key

//Delete all nodes with the value of key
    public ListNode removeAllKey(int key){
        if(this.head == null) return null;
        ListNode prev = this.head;
        ListNode cur = this.head.next;
        while (cur != null) {
            if(cur.val == key) {
                prev.next = cur.next;
                cur = cur.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        //Final processing head
        if(this.head.val == key) {
            this.head = this.head.next;
        }
        return this.head;
    }
public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        //myLinkedList.createList();
        myLinkedList.addLast(12);
        myLinkedList.addLast(23);
        myLinkedList.addLast(23);
        myLinkedList.addLast(23);
        myLinkedList.addLast(56);
        myLinkedList.addLast(90);
        myLinkedList.removeAllKey(23);
        myLinkedList.display();
    }

⑩ clear the linked list

 public void clear(){
        //this.head == null
        while (this.head != null) {
            ListNode curNext = head.next;
            this.head.next = null;
            this.head = curNext;
        }
    }

4. Bidirectional linked list

① Implementation of linked list

public class DoubleLinkedList {
     //Head insertion
     public void addFirst(int data){
 
}
     //Tail interpolation
     public void addLast(int data){
 
}
     //Insert at any position, and the first data node is subscript 0
     public boolean addIndex(int index,int data){
 
}
     //Find out whether the keyword is included and whether the key is in the single linked list
     public boolean contains(int key){
 
}
     //Delete the node whose keyword is key for the first time
     public void remove(int key){
 
}
     //Delete all nodes with the value of key
     public void removeAllKey(int key){
 
}
     //Get the length of the single linked list
     public int size(){
 
}
     public void display(){
 
}
     public void clear(){
 
}
}

② Construct nodes and linked lists

 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
       
    }
    public ListNode head;//Point to the head node of the bidirectional linked list
    //public ListNode head = new ListNode(-1);// Point to the head node of the bidirectional linked list
    public ListNode last;//It points to the tail node

③ Print the linked list and calculate the length of the linked list

public void display() {
        //The printing method is the same as that of single linked list
        ListNode cur = this.head;
        while (cur != null) {
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }
/Get the length of the single linked list
    public int size() {
        int count = 0;
        ListNode cur = this.head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

④ Query key

 public boolean contains(int key){
        ListNode cur = this.head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

⑤ Head insertion

//Head insertion
    public void addFirst(int data) {
        ListNode node = new ListNode(data);
        if(this.head == null) {
            this.head = node;
            this.last = node;
        }else {
            node.next = this.head;
            this.head.prev = node;
            this.head = node;
        }
    }
 public static void main(String[] args) {
 
 
          MyLinkedList myLinkedList = new MyLinkedList();
          myLinkedList.addFirst(12);
          myLinkedList.addFirst(23);
          myLinkedList.addFirst(34);
          myLinkedList.addFirst(45);
          myLinkedList.addFirst(56);
          myLinkedList.display();
}

⑥ Tail interpolation

 

   //Tail interpolation
    public void addLast(int data){
        ListNode node = new ListNode(data);
        if(this.head == null) {
            this.head = node;
            this.last = node;
        }else {
            this.last.next = node;
            node.prev = this.last;
            this.last = node;
        }
    }
 public static void main(String[] args) {
 
         MyLinkedList myLinkedList = new MyLinkedList();
         myLinkedList.addLast(12);
         myLinkedList.addLast(23);
         myLinkedList.addLast(34);
         myLinkedList.addLast(45);
         myLinkedList.addLast(56);
         myLinkedList.display();
}

⑦ Find insert node

 public ListNode searchIndex (int index) {
        ListNode cur = this.head;
        while (index != 0) {
            cur = cur.next;
            index--;
        }
        return cur;
    }

⑧ Insert element

  //Insert at any position, and the first data node is subscript 0
    public void addIndex(int index,int data){
        ListNode node = new ListNode(data);
        if(index < 0 || index > size()) {
            System.out.println("index Illegal location!");
            return;
        }
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = searchIndex(index);
        node.next = cur.prev.next;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }
 public static void main(String[] args) {
 
         MyLinkedList myLinkedList = new MyLinkedList();
         myLinkedList.addLast(12);
         myLinkedList.addLast(23);
         myLinkedList.addLast(34);
         myLinkedList.addLast(45);
         myLinkedList.addLast(56);
         myLinkedList.display();
         myLinkedList.addIndex(3,99);
         myLinkedList.display();
     }

⑨ Delete element

//Delete the node whose keyword is key for the first time
    public void remove(int key){
        ListNode cur = this.head;
        while (cur != null) {
            if(cur.val == key) {
                if(cur == head) {
                    head = head.next;
                    if(head != null) {
                        head.prev = null;
                    }else {
                        last = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    if(cur.next != null) {
                        //Middle position
                        cur.next.prev = cur.prev;
                    }else {
                        last = last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }
 public static void main(String[] args) {
 
 
         MyLinkedList myLinkedList = new MyLinkedList();
         myLinkedList.addLast(12);
         myLinkedList.addLast(23);
         myLinkedList.addLast(34);
         myLinkedList.addLast(45);
         myLinkedList.addLast(56);
         myLinkedList.display();
         myLinkedList.remove(23);
         myLinkedList.display();
     }

⑩ Empty linked list

public void clear() {
        while (head != null) {
            ListNode curNext = head.next;
            head.next = null;
            head.prev = null;
            head = curNext;
        }
        last = null;
    }

5. Written test exercises

① Reverse a single linked list

public ListNode reverseList() {
        if(this.head == null) {
            return null;
        }
        ListNode cur = this.head;
        ListNode prev = null;
 
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.next = prev;
            prev = cur;
            cur = curNext;
        }
        return prev;
    }

② Given a non empty single linked list with head node, return the intermediate node of the linked list

 

public ListNode middleNode() {
        if(head == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            if(fast == null) {
                return slow;
            }
            slow = slow.next;
        }
        return slow;
    }

③ Input a linked list and output the penultimate node in the linked list

 

 public ListNode findKthToTail(int k) {
        if(k <= 0 || head == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while (k-1 != 0) {
            fast = fast.next;
            if(fast == null) {
                return null;
            }
            k--;
        }
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

④ Delete multiple duplicate values in the linked list

//Delete all nodes with the value of key
    public ListNode removeAllKey(int key){
        if(this.head == null) return null;
        ListNode prev = this.head;
        ListNode cur = this.head.next;
        while (cur != null) {
            if(cur.val == key) {
                prev.next = cur.next;
                cur = cur.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        //Final processing head
        if(this.head.val == key) {
            this.head = this.head.next;
        }
        return this.head;
    }

⑤ Palindrome structure of linked list

 public boolean chkPalindrome(ListNode A) {
        // write code here
        if(head == null) return true;
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        //slow goes to the middle position - "reverse"
 
        ListNode cur = slow.next;
        while(cur != null) {
            ListNode curNext = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curNext;
        }
        //Reverse complete
        while(head != slow) {
            if(head.val != slow.val) {
                return false;
            }
            if(head.next == slow) {
                return true;
            }
            head = head.next;
            slow = slow.next;
        }
        return true;
    }

⑥ Merge two linked lists

public static ListNode mergeTwoLists(ListNode headA, ListNode headB) {
        ListNode newHead = new ListNode(-1);
        ListNode tmp = newHead;
        while (headA != null && headB != null) {
            if(headA.val < headB.val) {
                tmp.next = headA;
                headA = headA.next;
                tmp = tmp.next;
            }else {
                tmp.next = headB;
                headB = headB.next;
                tmp = tmp.next;
            }
        }
        if(headA != null) {
            tmp.next = headA;
        }
        if(headB != null) {
            tmp.next = headB;
        }
        return newHead.next;
    }

⑦ Enter two linked lists and find their first common node

 

 public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null || headB == null) {
            return null;
        }
 
        ListNode pl = headA;
        ListNode ps = headB;
        int lenA = 0;
        int lenB = 0;
        while (pl != null) {
            lenA++;
            pl = pl.next;
        }
        //pl==null
        pl = headA;
        while (ps != null) {
            lenB++;
            ps = ps.next;
        }
        //ps==null
        ps = headB;
        int len = lenA-lenB;//Difference step
        if(len < 0) {
            pl = headB;
            ps = headA;
            len = lenB-lenA;
        }
        //1. pl always points to the longest list and ps always points to the shortest list. 2. Find the difference len step
 
        //pl step len
        while (len != 0) {
            pl = pl.next;
            len--;
        }
        //Walk together until you meet
        while (pl != ps) {
            pl = pl.next;
            ps = ps.next;
        }
        return pl;
    }

⑧ Determine whether a linked list has a ring

 

 public boolean hasCycle() {
        if(head == null) return false;
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {
                return true;
            }
        }
        return false;
    }

⑨ Find the first node of a linked list

 

 public ListNode detectCycle(ListNode head) {
        if(head == null) return null;
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {
                break;
            }
        }
        if(fast == null || fast.next == null) {
            return null;
        }
        fast = head;
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
        return fast;
    }

3, Stack and queue

1. Stack

① Concept

In our software applications, stack, a last in first out data structure, is very common. For example, when you use the browser to surf the Internet, no matter what browser has a "back" button. After you click it, you can load the viewed web pages in reverse order.

Many similar software, such as word, Photoshop and other document or image editing software, also use stack to realize the operation. Of course, the specific implementation of different software will be very different, but the principle is actually the same

A stack is a linear table that is restricted to insertion and deletion only at the end of the table

Stack: a special linear table that allows insertion and deletion of elements only at a fixed end. One end for data insertion and deletion is called the top of the stack, and the other end is called the bottom of the stack. The data elements in the stack follow the principle of Last In First Out LIFO (Last In First Out).

② Stack operation

Stack pressing: the stack insertion operation is called stack entering / stack pressing / stack entering, and the input data is at the top of the stack.

Stack out: stack deletion is called stack out. The output data is at the top of the stack.

③ Implementation of stack

Push

 public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        int ret = stack.push(4);
        System.out.println(ret);
    }

Out of stack

  public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        int ret1 = stack.pop();
        int ret2 = stack.pop();
        System.out.println(ret1);
        System.out.println(ret2);
    }

Get stack top element

 public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        int ret1 = stack.pop();
        int ret2 = stack.pop();
        int ret3 = stack.peek();
        System.out.println(ret1);
        System.out.println(ret2);
        System.out.println(ret3);
    }

Determine whether the stack is empty

  public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        int ret1 = stack.pop();
        int ret2 = stack.pop();
        int ret3 = stack.peek();
        System.out.println(ret1);
        System.out.println(ret2);
        System.out.println(ret3);
        stack.pop();
        boolean flag = stack.empty();
        System.out.println(flag);
    }

④ Implement mystack

public class MyStack<T> {
    private T[] elem;//array
    private int top;//Currently, the subscript of the data element can be stored - "stack top pointer"
 
    public MyStack() {
        this.elem = (T[])new Object[10];
    }
 
    /**
     * Stack operation
     * @param item Stacked elements
     */
    public void push(T item) {
        //1. Determine whether the current stack is full
        if(isFull()){
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        //2,elem[top] = item  top++;
        this.elem[this.top++] = item;
    }
 
    public boolean isFull(){
        return this.elem.length == this.top;
    }
 
    /**
     * Out of stack
     * @return Out of stack elements
     */
    public T pop() {
        if(empty()) {
            throw new UnsupportedOperationException("Stack is empty!");
        }
        T ret = this.elem[this.top-1];
        this.top--;//Really changed the value of top
        return ret;
    }
 
    /**
     * Get the top element of the stack, but do not delete it
     * @return
     */
    public T peek() {
        if(empty()) {
            throw new UnsupportedOperationException("Stack is empty!");
        }
        //this.top--;// Really changed the value of top
        return this.elem[this.top-1];
    }
    public boolean empty(){
        return this.top == 0;
    }
}
public static void main(String[] args) {
        MyStack<Integer> myStack = new MyStack<>();
        myStack.push(1);
        myStack.push(2);
        myStack.push(3);
        System.out.println(myStack.peek());
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
        System.out.println(myStack.empty());
        System.out.println("============================");
        MyStack<String> myStack2 = new MyStack<>();
        myStack2.push("hello");
        myStack2.push("word");
        myStack2.push("thank");
        System.out.println(myStack2.peek());
        System.out.println(myStack2.pop());
        System.out.println(myStack2.pop());
        System.out.println(myStack2.pop());
        System.out.println(myStack2.empty());
 
    }

2. Queue

① Concept

For customer service calls such as China Mobile, China Unicom and China Telecom, there are always a few customer service personnel compared with customers. When all customer service personnel are busy, customers will be asked to wait until a customer service personnel is free, so that the customer who waits first can connect the phone. Here, all customers who currently dial customer service calls are queued.

In the operating system and customer service system, a data structure is applied to realize the first in first out queuing function just mentioned, which is queue.
A queue is a linear table that only allows insertion at one end and deletion at the other

Queue: a special linear table that only allows inserting data at one end and deleting data at the other end. The queue has a first in first out FIFO(First In First Out) into the queue: the end at which inserting is called Tail/Rear out of the queue: the end at which deleting is called Head/Front

 

② Implementation of queue

Join the team

 public static void main(String[] args) {
        Deque<Integer> queue = new LinkedList<>();
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        
    }

Out of the team

  public static void main(String[] args) {
        Deque<Integer> queue = new LinkedList<>();
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        System.out.println(queue.poll());
        System.out.println(queue.poll());
 
    }

Get team leader element

public static void main(String[] args) {
        Deque<Integer> queue = new LinkedList<>();
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println("-----------------");
        System.out.println(queue.peek());
    }

③ Implement myqueue

class Node {
    private int val;
    private Node next;
    public int getVal() {
        return val;
    }
    public void setVal(int val) {
        this.val = val;
    }
    public Node getNext() {
        return next;
    }
    public void setNext(Node next) {
        this.next = next;
    }
    public Node(int val) {
        this.val = val;
    }
}
public class MyQueue {
    private Node first;
    private Node last;
    //Join the team
    public void offer(int val) {
        //The tail interpolation method needs to judge whether it is the first insertion
        Node node = new Node(val);
        if(this.first == null) {
            this.first = node;
            this.last = node;
        }else {
            this.last.setNext(node);//last.next = node;
            this.last = node;
        }
    }
    //Out of the team
    public int poll() {
        //1 judge whether it is empty
        if(isEmpty()) {
            throw new UnsupportedOperationException("The queue is empty!");
        }
        //this.first = this.first.next;
        int ret = this.first.getVal();
        this.first = this.first.getNext();
        return ret;
    }
    //Get the team header element but don't delete it
    public int peek() {
        //Do not move first
        if(isEmpty()) {
            throw new UnsupportedOperationException("The queue is empty!");
        }
        return this.first.getVal();
    }
    //Is the queue empty
    public boolean isEmpty() {
        return this.first == null;
    }
}
 public static void main(String[] args) {
        MyQueue myQueue = new MyQueue();
        myQueue.offer(1);
        myQueue.offer(2);
        myQueue.offer(3);
        System.out.println(myQueue.peek());
        System.out.println(myQueue.poll());
        System.out.println(myQueue.poll());
        System.out.println(myQueue.poll());
        System.out.println(myQueue.isEmpty());
       
    }

4, Binary tree

1. Tree

① Concept

Tree is a non-linear data structure. It is a set with hierarchical relationship composed of n (n > = 0) finite nodes. It is called tree because it looks like an upside down tree, that is, it has roots facing up and leaves facing down. It has the following characteristics:

There is a special node, called the root node, which has no precursor node

Except for the root node, the other nodes are divided into m (M > 0) disjoint sets T1, T2 Tm, where each set Ti (1 < = I < = m) is a subtree similar to the tree. The root node of each subtree has only one precursor, and can have 0 or more successors
Trees are recursively defined.

② Basic concepts of tree

Node degree: the number of subtrees contained in a node is called the degree of the node

Tree degree: the degree of the largest node in a tree is called the degree of the tree

Leaf node or terminal node: a node with a degree of 0 is called a leaf node

Parent node or parent node: if a node has children, the node is called the parent node of its children

Child node or child node: the root node of the subtree contained in a node is called the child node of the node

Root node: a node in a tree without parent nodes

Node hierarchy: defined from the root, the root is the first layer, and the child nodes of the root are the second layer, and so on

Height or depth of the tree: the maximum level of nodes in the tree

2. Binary tree

① Concept

A binary tree is a finite set of nodes. The set is either empty or composed of a root node and two binary trees called left subtree and right subtree.

Characteristics of binary tree:

1. Each node has at most two subtrees, that is, the binary tree does not have nodes with a degree greater than 2.

2. The subtree of a binary tree can be divided into left and right, and the order of its subtrees cannot be reversed. Therefore, a binary tree is an ordered tree.

② Two special binary trees

1. Full binary tree: a binary tree. If the number of nodes in each layer reaches the maximum, the binary tree is a full binary tree. In other words, if the number of layers of a binary tree is K and the total number of nodes is, it is a full binary tree.

2. Complete binary tree: complete binary tree is a highly efficient data structure. Complete binary tree is derived from full binary tree. A binary tree with depth K and n nodes is called a complete binary tree if and only if each node corresponds to the nodes numbered from 1 to n in the full binary tree with depth K. It should be noted that full binary tree is a special complete binary tree.

③ Properties of binary tree

1. If the specified number of layers of the root node is 1, there are at most 2 ^ (i-1) (I > 0) nodes on layer I of a non empty binary tree

2. If the depth of the binary tree with only the root node is specified as 1, the maximum number of nodes of the binary tree with depth K is 2 ^ k-1 (k > = 0)

3. For any binary tree, if the number of leaf nodes is n0 and the number of non leaf nodes with degree 2 is n2, then n0 = n2 + 1

4. The depth k of a complete binary tree with n nodes is rounded on log2(n+1)

3. Binary tree traversal

① Traversal of binary tree

Traversal means that each node in the tree is accessed once and only once along a search route. The operation of the access node depends on the specific application problem (for example, print the node content and add 1 to the node content). Traversal is one of the most important operations on a binary tree and the basis of other operations on a binary tree.

When traversing a binary tree, if there is no agreement, everyone traverses it in their own way, and the results are chaotic. If the agreement is made according to some rules, everyone must have the same traversal result for the same tree. If N represents the root node, L represents the left subtree of the root node, and R represents the right subtree of the root node, there are the following traversal methods according to the order of traversing the root node:


1. NLR: Preorder Traversal (also known as Preorder Traversal) - access the root node -- > the left subtree of the root -- > the right subtree of the root.

 2. LNR: inorder traversal -- left subtree of root -- > root node -- > right subtree of root.

3. LRN: postorder traversal -- left subtree of root -- > right subtree of root -- > root node.

Since the accessed node must be the root of a subtree, N(Node), L(Left subtree) and R(Right subtree) can be interpreted as the root, the left subtree of the root and the right subtree of the root. NLR, LNR and LRN are also called first root traversal, middle root traversal and second root traversal respectively.

Note: among the three types of traversal, only the access root node prints. For each type of traversal, when accessing each node, there must be three different traversal methods until the traversal reaches null, return to the root node and continue to complete the traversal!!! For example, for preorder traversal, every time I visit a node, I have to perform the three steps of asking the root node -- > the left subtree of the root -- > the right subtree of the root. The middle order and post order traversal are the same.
 

Taking the following binary tree as an example, the next step is to explain it in detail

② Preorder traversal

graphic

code analysis

We use enumeration to create this binary tree

public TreeNode createTree() {
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');
        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        C.left = F;
        C.right = G;
        E.right = H;
        return A;
    }
// Preorder traversal
    void preOrderTraversal(TreeNode root){
        if(root == null) {
            return;
        }
        System.out.print(root.val+" ");
        preOrderTraversal(root.left);
        preOrderTraversal(root.right);
    }

DeBug analysis

③ Medium order traversal

graphic

// Medium order traversal
    void inOrderTraversal(TreeNode root){
        if(root == null) {
            return;
        }
        inOrderTraversal(root.left);
        System.out.print(root.val+" ");
        inOrderTraversal(root.right);
    }

DeBug analysis

④ Postorder traversal

graphic

 // Postorder traversal
    void postOrderTraversal(TreeNode root){
        if(root == null) {
            return;
        }
        postOrderTraversal(root.left);
        postOrderTraversal(root.right);
        System.out.print(root.val+" ");
    }

DeBug analysis

3. Binary search tree

① Concept

Binary search tree is also called binary sort tree. It is either an empty tree * * or a tree with the following properties Binary tree:

If its left subtree is not empty, the values of all nodes on the left subtree are less than those of the root node

If its right subtree is not empty, the values of all nodes on the right subtree are greater than those of the root node

Its left and right subtrees are also binary search trees

② Action - find

Binary search tree The lookup for is similar to the dichotomy lookup

public Node search(int key) {
        Node cur = root;
        while (cur != null) {
            if(cur.val == key) {
                return cur;
            }else if(cur.val < key) {
                cur = cur.right;
            }else {
                cur = cur.left;
            }
        }
        return null;
    }

③ Operation - insert

  public boolean insert(int key) {
        Node node = new Node(key);
        if(root == null) {
            root = node;
            return true;
        }
 
        Node cur = root;
        Node parent = null;
 
        while(cur != null) {
            if(cur.val == key) {
                return false;
            }else if(cur.val < key) {
                parent = cur;
                cur = cur.right;
            }else {
                parent = cur;
                cur = cur.left;
            }
        }
        //parent
        if(parent.val > key) {
            parent.left = node;
        }else {
            parent.right = node;
        }
 
        return true;
    }

④ operation - delete

The deletion operation is complex, but it is easy to understand its principle

Set the node to be deleted as cur and the parent node of the node to be deleted as parent

1. cur.left == null

1. If cur is root, then root = cur right

2. cur is not root, but cur is parent Left, then parent left = cur. right

3. cur is not root, but cur is parent Right, then parent right = cur. right


 

 

2. cur.right == null

1. If cur is root, then root = cur left

2. cur is not root, but cur is parent Left, then parent left = cur. left

3. cur is not root, but cur is parent Right, then parent right = cur. left

The second case is the same as the first case, but in the opposite direction. There is no drawing here

3. cur.left != null && cur.right != null

The replacement method needs to be used for deletion, that is, find the first node in the middle order in its right subtree (with the smallest key), fill its value into the deleted node, and then deal with the deletion of the node

When we delete when the left and right subtrees are not empty, deleting the node will destroy the tree structure. Therefore, we use the scapegoat method to solve the problem. The actual deletion process is still the above two cases, and the nature of search binary tree is used here


public void remove(Node parent,Node cur) {
        if(cur.left == null) {
            if(cur == root) {
                root = cur.right;
            }else if(cur == parent.left) {
                parent.left = cur.right;
            }else {
                parent.right = cur.right;
            }
        }else if(cur.right == null) {
            if(cur == root) {
                root = cur.left;
            }else if(cur == parent.left) {
                parent.left = cur.left;
            }else {
                parent.right = cur.left;
            }
        }else {
            Node targetParent =  cur;
            Node target = cur.right;
            while (target.left != null) {
                targetParent = target;
                target = target.left;
            }
            cur.val = target.val;
            if(target == targetParent.left) {
                targetParent.left = target.right;
            }else {
                targetParent.right = target.right;
            }
        }
    }
 
  public void removeKey(int key) {
        if(root == null) {
            return;
        }
        Node cur = root;
        Node parent = null;
        while (cur != null) {
            if(cur.val == key) {
                remove(parent,cur);
                return;
            }else if(cur.val < key){
                parent = cur;
                cur = cur.right;
            }else {
                parent = cur;
                cur = cur.left;
            }
        }
    }

⑤ Performance analysis

Both insert and delete operations must be searched first. The search efficiency represents the performance of each operation in the binary search tree.

For a binary search tree with n nodes, if the search probability of each element is equal, the average search length of the binary search tree is a function of the depth of the node in the binary search tree, that is, the deeper the node, the more comparisons.

However, for the same key set, if the insertion order of each key is different, binary search trees with different structures may be obtained

In the optimal case, the binary search tree is a complete binary tree, and its average comparison times are:

In the worst case, the binary search tree degenerates into a single branch tree, and its average comparison times are:

4. Written test exercises

① Preorder traversal of binary tree

 

  void preOrderTraversal(TreeNode root){
        if(root == null) {
            return;
        }
        System.out.print(root.val+" ");
        preOrderTraversal(root.left);
        preOrderTraversal(root.right);
    }

② Order traversal in binary tree

 

void inOrderTraversal(TreeNode root){
        if(root == null) {
            return;
        }
        inOrderTraversal(root.left);
        System.out.print(root.val+" ");
        inOrderTraversal(root.right);
    }

③ Postorder traversal of binary tree

 

 
    void postOrderTraversal(TreeNode root){
        if(root == null) {
            return;
        }
        postOrderTraversal(root.left);
        postOrderTraversal(root.right);
        System.out.print(root.val+" ");
    }

④ Check whether the two trees are the same

 

   public boolean isSameTree(TreeNode p,TreeNode q){
        if(p == null && q != null){
            return  false;
        }
        if(p != null && q == null){
            return  false;
        }
        if(p == null && q ==null){
            return true;
        }
        if(p.val != q.val){
            return false;
        }
        return  isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
        
    }




⑤ Maximum depth of binary tree

 

  public int maxDepth(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftHeight =  maxDepth(root.left);
        int rightHeight = maxDepth(root.right);
        return Math.abs(leftHeight-rightHeight > 0? leftHeight + 1: rightHeight + 1);
    }

⑥ A subtree of another tree

 

     public boolean isSameTree(TreeNode p,TreeNode q){
        if(p == null && q != null){
            return  false;
        }
        if(p != null && q == null){
            return  false;
        }
        if(p == null && q ==null){
            return true;
        }
        if(p.val != q.val){
            return false;
        }
        return  isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
        
    }
 
 
    public boolean isSubtree(TreeNode root, TreeNode suBroot){
        if(root == null && suBroot == null){
            return true;
        }
        if(isSameTree(root,suBroot)){
            return true;
        }
        if(isSubtree(root.right,suBroot)){
            return true;
        }
        if(isSubtree(root.left,suBroot)){
            return true;
        }
        return false;
    }

⑦ Judge whether a tree is a balanced binary tree

 

 

 

public int maxDepth(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftHeight =  maxDepth(root.left);
        int rightHeight = maxDepth(root.right);
        return Math.abs(leftHeight-rightHeight > 0? leftHeight + 1: rightHeight + 1);
    }
 
    public boolean isBalanced(TreeNode root) {
        if(root == null) {
            return true;
        }
        int leftHeight =  maxDepth(root.left);
        int rightHeight = maxDepth(root.right);
        return
                Math.abs(leftHeight-rightHeight) < 2 && isBalanced(root.left) && isBalanced(root.right);
    }

 
    public int hight(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftHeight = hight(root.left);
        int rightHeight = hight(root.right);
        if(leftHeight >= 0 && rightHeight >= 0 && Math.abs(leftHeight-rightHeight) <= 1){
            return Math.max(leftHeight,rightHeight)+1;
        }else{
            return -1;
        }
    }
    public boolean isBalanced2(TreeNode root) {
        return hight(root) >= 0;
    }

⑧ Symmetric binary tree

 public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree){
        if(leftTree != null && rightTree == null){
            return false;
        }
        if(leftTree == null && rightTree != null){
            return false;
        }
        if(leftTree == null && rightTree == null){
            return true;
        }
        if(leftTree.val != rightTree.val){
            return false;
        }
        return isSymmetricChild(leftTree.left,rightTree.right) &&
                isSymmetricChild(leftTree.left,rightTree.right);
    }
    public boolean isSymmetric(TreeNode root){
        if(root == null){
            return true;
        }
        return isSymmetricChild(root.left,root.right);
    }

⑨ Binary tree image

 

 

public TreeNode Mirror(TreeNode pRoot){
        if(pRoot == null){
            return pRoot;
        }
        if(pRoot.left == null && pRoot.right == null){
            return pRoot;
        }
        TreeNode tmp = pRoot.left;
        pRoot.left = pRoot.right;
        pRoot.right = tmp;
        
        if(pRoot.left != null){
            Mirror(pRoot.left);
            return pRoot;
        }
        if(pRoot.right != null){
            Mirror(pRoot.right);
            return pRoot;
        }
        return pRoot;
        
    }

5, Priority queue (heap)

1. Sequential storage of binary tree

① Storage mode

Use the array to save the binary tree structure, that is, the binary tree is put into the array by sequence traversal. Generally, it is only suitable for representing complete binary trees, because incomplete binary trees will waste space. The main use of this approach is the representation of the heap.

② Subscript relation

If the subscript of the parent is known, then:

Left subscript = 2 * parent + 1;

Right subscript = 2 * parent + 2;

If the child subscript is known, then:

Parent subscript = (child - 1) / 2;

③ Binary tree sequential traversal

// level traversal 
    void levelOrderTraversal(TreeNode root) {
        if(root == null) {
            return;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode top = queue.poll();
            System.out.print(top.val+" ");
            if(top.left != null) {
                queue.offer(top.left);
            }
            if(top.right!=null) {
                queue.offer(top.right);
            }
        }
        System.out.println();
    }

2. Reactor

① Concept

1. Heap logic is a complete binary tree

2. The heap is physically stored in an array

3. If the value of any node is greater than the value of the node in its subtree, it is called large heap, or large root heap, or maximum heap

4. On the contrary, it is a small heap, or a small root heap, or a minimum heap

② Operation - downward adjustment

Premise:

The left and right subtrees must be a heap before they can be adjusted.

explain:

1. array represents the array of storage heap

2. size represents the number of heap data in the array

3. index represents the subscript of the position to be adjusted

4. left stands for index left subscript

5. right stands for index right subscript

6. min represents the minimum value of index and the child's subscript

Process (taking small heap as an example):

If I index is already a leaf node, the whole adjustment process ends

1. Judge whether there are children in the school

2. Because the heap is a complete binary tree, if there is no left child, there must be no right child, so judge whether there is a left child

3. Because the storage structure of the heap is an array, judge whether there is a left child, that is, judge whether the left child subscript is out of bounds, that is, left > = size is out of bounds

II determine left or right, who is the youngest child of index min

1. If the right child does not exist, min = left

2. Otherwise, compare the values of array[left] and array[right], and select the smaller value as min

Ⅲ compare the value of array[index] with the value of array[min]. If array[index] < = array[min], the nature of the heap is met and the adjustment is completed

IV. otherwise, exchange the values of array[index] and array[min]

Ⅴ then, because the nature of the heap at the Min position may be destroyed, take min as an index and repeat the above process downward

Downward adjustment takes the binary tree traversed by sequence as an example


 

public void adjustDown(int root,int len){
        int parent = root;
        int child = 2*parent + 1;
        while(child < len){
            if (child + 1 < len && this.elem[child] < this.elem[child + 1] ){
                child++;
            }
            if(this.elem[child] > this.elem[parent]){
                int tmp = this.elem[parent];
                this.elem[parent] = this.elem[child];
                this.elem[child] = tmp;
                parent = child;
                child = 2*parent + 1;
            }else{
                break;
            }
        }
    }

③ Pile building (taking pile building as an example)

Next, we give an array, which can be logically regarded as a complete binary tree, but it is not a heap. Now we build it into a heap through an algorithm. The left and right subtrees of the root node are not heaps. How can we adjust them? Here, we start from the subtree of the penultimate non leaf node to the tree of the root node.

//Build a pile
    public void creatHeap(int[] array){
        for (int i = 0; i < array.length;i++){
            this.elem[i] = array[i];
            suedSize++;
        }
        for (int parent = (array.length - 1 - 1) / 2;parent >= 0;parent--){
            adjustDown(parent,this.suedSize);
        }

3. Heap application - priority queue

① Concept

In many applications, we usually need to process the objects according to the priority. For example, we first process the objects with the highest priority, and then process the objects with the second highest priority. The simplest example is that when playing games on the mobile phone, if there is an incoming call, the system should give priority to the incoming call. In this case, our data structure should provide two basic operations, one is to return the highest priority object, and the other is to add a new object. This data structure is called priority queue

② Internal principle

There are many ways to implement priority queues, but the most common is to build them using heaps.

③ Queue

Process (for example):

1. First put the array in the tail insertion mode

2. Compare its value with that of its parents. If the value of its parents is large, it meets the nature of the heap and the insertion ends

3. Otherwise, exchange the value of its and parent position, and repeat steps 2, 3 and 4 Up to the root node

public void adjustUp(int child){
        int parent = (child - 1) / 2;
        while(child>0){
            if(this.elem[child] > this.elem[parent]){
                int tmp = this.elem[parent];
                this.elem[parent] = this.elem[child];
                this.elem[child] = tmp;
                child = parent;
                parent = (child - 1) / 2;
            }else {
                break;
            }
        }
    }
public void push(int val) {
        if (isFull()) {
            this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);
            this.elem[this.suedSize] = val;
            this.suedSize++;
            adjustUp(this.suedSize - 1);
 
        }
    }

④ Out of queue (highest priority)

In order to prevent the structure of the heap from being damaged, the top element of the heap is not deleted directly, but replaced with the last element of the array, and then readjusted into the heap by adjusting downward

 public boolean isEmpty(){
        return this.suedSize == 0;
    }
 public void pop(){
        if(isEmpty()){
            return;
        }
        int tmp = this.elem[0];
        this.elem[0] = this.elem[this.suedSize-1];
        this.elem[this.suedSize-1] = tmp;
        this.suedSize--;
        adjustDown(0,this.suedSize);
    }

⑤ Return to the first element of the queue (highest priority)

public int peek(){
        if(isEmpty()){
            return -1;
        }
        return this.elem[0];
    }
  public boolean isFull(){
        return this.suedSize == this.elem.length;
    }

4. Heap sorting

 /**
     * You must create a lot first
     *      Adjust each tree
     * Start heap sort:
     *     First exchange and then adjust until 0 subscript.
     */
 
    public void heapSort(){
        int end = this.suedSize-1;
        while (end > 0){
            int tmp = this.elem[0];
            this.elem[0] = this.elem[end];
            this.elem[end] = tmp;
            adjustDown(0,end);
            end--;
 
        }
 
    }

6, Sort

1. Concept

① Sort

Sorting is the operation of arranging a string of records incrementally or decrementally according to the size of one or some keywords. In the normal context, if sorting is mentioned, it usually refers to ascending order (non descending order). In the normal sense, sorting refers to in place sort.

② Stability

If the sorting algorithm can ensure that the relative position of two equal data does not change after sorting, we call the algorithm a stable sorting algorithm

Or we say that the sort without jump is also a stable sort

2. Detailed sorting

① Direct insert sort

The whole interval is divided into

               1. Ordered interval

               2. Disordered interval

Select the first element of the unordered interval each time and insert it at the appropriate position in the ordered interval

 

 public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        insertSort(array);
        System.out.println(Arrays.toString(array));
    }
  /**
     * Time complexity:
     *        Best: O (n) - > the data is ordered
     *        Worst case: O (n ^ 2) - > unordered data
     * Space complexity: O(1)
     * Stability: stable sorting
     * @param array
     */
public static void insertSort(int[] array) {
        for(int i = 1;i < array.length;i++) {//n-1
            int tmp = array[i];
            int j = i-1;
            for(; j >= 0;j--) {//n-1
                if(array[j] > tmp) {
                    array[j+1] = array[j];
                }else{
                    //array[j+1] = tmp;
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

② Hill sort

Hill ranking method is also known as reduced incremental method. The basic idea of hill sorting method is to select an integer first, divide all records in the file to be sorted into groups, divide all records with distance into the same group, and sort the records in each group. Then, take and repeat the above grouping and sorting. When arrival = 1, all records are arranged in a unified group.

1. Hill sort is the optimization of direct insertion sort.

2. When gap > 1, it is pre sorted to make the array closer to order. When gap == 1, the array is close to ordered, which will be very fast. In this way, the optimization effect can be achieved as a whole. We can compare the performance test after implementation.


 

   /**
     * Time complexity: not easy to calculate between n^1.3 - n^1.5
     * Space complexity: O(1)
     * Stability: unstable sorting
     *      Tip: if there is no jumping exchange in the process of comparison, it is stable
     * @param array
     *
     *
     * @param array Sorted array
     * @param gap   Interval per group - number of groups
     */
    public static void shell(int[] array,int gap) {
        for (int i = gap; i < array.length; i++) {
            int tmp = array[i];
            int j = i-gap;
            for (; j >= 0; j -= gap) {
                if(array[j] > tmp) {
                    array[j+gap] = array[j];
                }else {
                    break;
                }
            }
            array[j+gap] = tmp;
        }
    }
public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        shell(array,5);
        System.out.println(Arrays.toString(array));
    }

③ Direct selection sort

Each time, the largest (or smallest) element is selected from the unordered interval and stored at the end (or front) of the unordered interval until all data elements to be sorted are arranged.

public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        selectSort(array);
        System.out.println(Arrays.toString(array));
    }
  /**
     * Time complexity:
     *      Best: O(N^2)
     *      Worst case: O(N^2)
     * Space complexity: O(1)
     * Stability: unstable
     * @param array
     */
    public static void selectSort(int[] array) {
        for (int i = 0; i < array.length; i++) {
            for (int j = i+1; j < array.length; j++) {
                if(array[j] < array[i]) {
                    int tmp = array[i];
                    array[i] = array[j];
                    array[j] = tmp;
                }
            }
        }
    }

④ Heap sort

The basic principle is also selective sorting, but instead of using traversal to find the maximum number of unordered intervals, it selects the maximum number of unordered intervals through the heap.

Note: a lot should be built in ascending order; In descending order, small piles should be built.

  public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        heapSort(array);
        System.out.println(Arrays.toString(array));
    }
   public static void siftDown(int[] array,int root,int len) {
        int parent = root;
        int child = 2*parent+1;
        while (child < len) {
            if(child+1 < len && array[child] < array[child+1]) {
                child++;
            }
            //The child subscript is the maximum subscript of the left and right children
            if(array[child] > array[parent]) {
                int tmp = array[child];
                array[child] = array[parent];
                array[parent] = tmp;
                parent = child;
                child = 2*parent+1;
            }else {
                break;
            }
        }
    }
 
    public static void createHeap(int[] array) {
        //Sort from small to large - large root heap
        for (int i = (array.length-1 - 1) / 2;  i >= 0 ; i--) {
            siftDown(array,i,array.length);
        }
    }
 
    /**
     * Time complexity: O(N*logN) is the time complexity
     * Complexity: O(1)
     * Stability: unstable sorting
     * @param array
     */
    public static void heapSort(int[] array) {
        createHeap(array);//O(n)
        int end = array.length-1;
        while (end > 0) {//O(N*logN)
            int tmp = array[end];
            array[end] = array[0];
            array[0] = tmp;
            siftDown(array,0,end);
            end--;
        }
    }

⑤ Bubble sorting

In the unordered interval, through the comparison of adjacent numbers, bubble the largest number to the end of the unordered interval, and continue this process until the array is ordered as a whole

 public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
         bubbleSort(array);
        System.out.println(Arrays.toString(array));
    }
   /**
     * Time complexity:
     *         The best and worst are O(n^2) 
     * Space complexity: O(1)
     * Stability: stable sorting
     *      Bubbling direct insertion
     * @param array
     */
    public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1; i++) {
            for (int j = 0; j < array.length-1-i; j++) {
                if(array[j] > array[j+1]) {
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
 
                }
            }
        }
    }

⑥ Quick sort

1. Select a number from the interval to be sorted as the benchmark value (pivot);

2. Partition: traverse the entire range to be sorted, put the smaller (can contain equal) than the benchmark value to the left of the benchmark value, and put the larger (can contain equal) than the benchmark value to the right of the benchmark value;

3. Using the divide and conquer idea, the left and right cells are processed in the same way until the length between cells = = 1, which means that they are in order, or the length between cells = = 0, which means that there is no data

public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        quickSort1(array);
        System.out.println(Arrays.toString(array));
    }
public static int partition(int[] array,int low,int high) {
        int tmp = array[low];
        while (low < high) {
            while (low < high && array[high] >= tmp) {
                high--;
            }
            array[low] = array[high];
            while (low < high && array[low] <= tmp) {
                low++;
            }
            array[high] = array[low];
        }
        array[low] = tmp;
        return low;
    }
 public static void quick(int[] array,int start,int end) {
        if(start >= end) {
            return;
        }
        int mid = (start+end)/2;
        int pivot = partition(array,start,end);
        quick(array,start,pivot-1);
        quick(array,pivot+1,end);
    }
 
    /**
     * Time complexity:
     *         Best: O(n*logn) under uniform segmentation
     *         Worst: o(n^2) when the data is in order
     * Space complexity:
     *        Best: logn
     *        Worst case: O(n)
     * Stability: unstable sorting
     *
     * k*n*logn
     * 2
     * 1.2
     * @param array
     */
    public static void quickSort1(int[] array) {
        quick(array,0,array.length-1);
    }

⑦ Merge sort

Merge sort is an effective sort algorithm based on merge operation. The algorithm adopts Divide and Conquer method A very typical application of (Divide and Conquer). Merge the ordered subsequences to obtain a completely ordered sequence; that is, order each subsequence first, and then order the subsequence segments. If two ordered tables are merged into one ordered table, it is called two-way merging.

 public static void main(String[] args) {
 
        int[] array = {12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        mergeSort1(array);
        System.out.println(Arrays.toString(array));
    }
public static void merge(int[] array,int low,int mid,int high) {
        int s1 = low;
        int e1 = mid;
        int s2 = mid+1;
        int e2 = high;
        int[] tmp = new int[high-low+1];
        int k = 0;//Represents the subscript of the tmp array
        while (s1 <= e1 && s2 <= e2) {
            if(array[s1] <= array[s2]) {
                tmp[k++] = array[s1++];
            }else {
                tmp[k++] = array[s2++];
            }
        }
 
        //There are two situations
        while (s1 <= e1){
            //It indicates that there is no data in the second merging segment, and copy all the remaining data in the first merging segment
            tmp[k++] = array[s1++];
        }
 
        while (s2 <= e2) {
            //It indicates that there is no data in the first merging segment, and copy all the remaining data in the second merging segment
            tmp[k++] = array[s2++];
        }
        //The tmp array stores the currently merged data
 
        for (int i = 0; i < tmp.length; i++) {
            array[i+low] = tmp[i];
        }
    }
    public static void mergeSortInternal(int[] array,int low,int high) {
        if(low >= high) {
            return;
        }
        int mid = (low+high) / 2;
        mergeSortInternal(array,low,mid);
        mergeSortInternal(array,mid+1,high);
        //Merging process
        merge(array,low,mid,high);
    }
 
    /**
     * Time complexity: O(N*log n)
     * Space complexity: O(N)
     * Stability: stable
     * @param array
     */
    public static void mergeSort1(int[] array) {
        mergeSortInternal(array, 0,array.length-1);
    }

7, List

1. Introduction to ArrayList

[description]

1. ArrayList implements the RandomAccess interface, indicating that ArrayList supports random access

2. ArrayList implements Cloneable interface, which indicates that ArrayList can clone

3. ArrayList implements the Serializable interface, indicating that ArrayList supports serialization

4. Unlike vector, ArrayList is not thread safe and can be used in a single thread. Vector or CopyOnWriteArrayList can be selected in multiple threads

5. The bottom layer of ArrayList is a continuous space and can be dynamically expanded. It is a dynamic type sequence table

2. Use ArrayList

① Construction of ArrayList

public static void main(String[] args) {
        // It is recommended to create ArrayList
        // Construct an empty list
        List<Integer> list1 = new ArrayList<>();
        // Construct a list with 10 capacities
        List<Integer> list2 = new ArrayList<>(10);
        list2.add(1);
        list2.add(2);
        list2.add(3);
        // list2.add("hello"); //  Compilation failed. List < integer > has been defined. Only integer elements can be stored in List2
        // After list3 is constructed, it is consistent with the elements in the list
        ArrayList<Integer> list3 = new ArrayList<>(list2);
        // Avoid omitting types, otherwise: elements of any type can be stored, and it will be a disaster when used
        List list4 = new ArrayList();
        list4.add("111");
        list4.add(100);
    }

② ArrayList common operations

public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("1234");
        list.add("zhongguo");
        list.add("aaaaa");
        list.add("gao");
        System.out.println(list);

    }

//add source code
  public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
  public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("1234");
        list.add("zhongguo");
        list.add("aaaaa");
        list.add("gao");
        list.add(2,"ssss");
        System.out.println(list);

    }

 //add insert source code
public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }
  public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("1234");
        list.add("zhongguo");
        list.add("aaaaa");
        list.add("gao");
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("111");
        list2.add("44554");
        list.addAll(list2);
        System.out.println(list);

    }

 //addAll source code
public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }

 public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("1234");
        list.add("zhongguo");
        list.add("aaaaa");
        list.add("gao");
        list.remove(2);
        System.out.println(list);
    }

  public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("1234");
        list.add("zhongguo");
        list.add("aaaaa");
        list.add("gao");
        String a = list.get(1);
        System.out.println(a);
        System.out.println(list);
    }

③ Traversal of ArrayList

  public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("hello");
        list.add("123");
        list.add("jsss");
        System.out.println(list);
        System.out.println("===================");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
        System.out.println();
        System.out.println("=====================");
        for (String s : list) {
            System.out.print(s + " ");
        }
        System.out.println();
        System.out.println("=========Iterator printing=======");
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            System.out.print(it.next() + " ");
        }

        System.out.println();
        System.out.println("==========iterator  list Print=======");
        ListIterator<String> it2 = list.listIterator();
        while (it2.hasNext()){
            System.out.print(it2.next() + " ");
        }

    }

8, Map and Set

1. Search

① Concept and scenario

Map and set are special containers or data structures for searching, and their search efficiency is related to their specific instantiation subclasses.

Search methods are:

1. Direct traversal. The time complexity is O(N). If there are many elements, the efficiency will be very slow

2. Binary search has a time complexity of, but the sequence must be ordered before the search. The above sorting is more suitable for static search, that is, the interval is generally not inserted or deleted, but in reality, such as:

1. Query test scores by name

2. Address book, i.e. inquire the contact information according to the name

3. Do not duplicate the set, that is, you need to search whether the keyword is already in the set

② Model

Generally, the searched data is called Key, and the corresponding Key is called Value, which is called Key Value pair. Therefore, there are two models:

1. Pure key model, such as:

There is an English dictionary to quickly find out whether a word is in the dictionary or not

2. Key value model, for example:

Count the number of times each word appears in the file. The statistical result is that each word has its corresponding number of times: Liangshan hero's Jianghu nickname: each hero has his own Jianghu nickname

2. Use of Map

① Description of Map

Map is an interface class, which does not inherit from Collection. The key value pairs of the structure are stored in this class, and K must be unique and cannot be repeated.

② About map Description of entry

Map.Entry is an internal class implemented in map and used to store the mapping relationship between Key value pairs. This internal class mainly provides the acquisition of values, the setting of values and the comparison method of keys.

methodexplain
K getKey()Returns the value of the key in the entry
V getValue()Return value in entry
V setValue(V value)Replace the value in the key value pair with the specified value

③ Description of common methods of Map

public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("123","Li Bai");
        map.put("124","Du Fu");
        map.put("125","wang changling");
        map.put("126", "known as a model of fidelity to the last Song sovereigns");
        System.out.println(map);

    }

public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("123","Li Bai");
        map.put("124","Du Fu");
        map.put("125","wang changling");
        map.put("126", "known as a model of fidelity to the last Song sovereigns");

        String val = map.get("123");
        System.out.println(val);
    }
 
 public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("123","Li Bai");
        map.put("124","Du Fu");
        map.put("125","wang changling");
        map.put("126", "known as a model of fidelity to the last Song sovereigns");
        String val;
        val = map.getOrDefault("123","Li Bai");
        System.out.println(val);
        
    }

3. Use of Set

① Description of common methods

② Use case of TreeSet

  public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("123");
        set.add("124");
        set.add("125");
        System.out.println(set);
    }

public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("123");
        set.add("124");
        set.add("125");
        boolean fla = set.contains("123");
        System.out.println(fla);
    }

public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("123");
        set.add("124");
        set.add("125");
        Iterator<String> it = set.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
    }

Topics: data structure