Linear table is a very basic and important data structure
Next, I will make a detailed summary of these four data structures, in which the linked list is implementedMore than ten kindsCommon operations. Hope to help you.
1. Array
Array is a linear table data structure. It uses a group of continuous memory space to store a group of data with the same type.
Note: 1. Array is a kind ofLinear table;②.Continuous memory space and the same type of data
Because of the second property, arrays supportRandom accessAccording to the following table, the time complexity of random access is O (1); but at the same time, it makes deleting in the array and inserting data need a lot of data moving.
Inefficient “insertion” and “deletion”
Insert operation
If the length of the array is n, we need to insert a data into the k-th position of the array. We need to move the k-th to n-th elements back one bit in order.
In the best case, the time complexity is O (1), which corresponds to inserting elements at the end of the array;
The worst-case time complexity is O (n), which corresponds to inserting elements at the beginning of the array;
The average time complexity is O (n), because the probability of inserting elements in each position is the same, so (1 + 2 + 3 +…) +n)/n=O(n);
But according to our needs, there is a specific scenario. If the data of an array is ordered, we must do that when inserting it. However, if the data stored in the array has no regularity, the array is just regarded as a dataA collection of stored dataWe can have a clever way:
Move the k-th element directly to the end of the array element, and put the new data directly into the k-th position (isn’t it very simple). At this time, the complexity of inserting elements is O (1).
Delete operation
Like the insert operation, the delete operation also needs to move data in order to ensure the continuity of memory.
In the best case, the time complexity is O (1), which corresponds to deleting the elements at the end of the array;
The worst-case time complexity is O (n), which corresponds to deleting the elements at the beginning of the array;
The average time complexity is O (n), because the probability of deleting each element is the same, so (1 + 2 + 3 +…) +n)/n=O(n);
Of course, in some special cases, we don’t have to carry out itcomplexDelete operation for. We just will need to delete the datarecordAndPretend it was deleted. Until the array has no more space to store data, we can trigger a real delete operation.
In fact, this is similar to the garbage can in life. Garbage doesn’t disappear, it’s just discarded“sign”It becomes garbage, and it doesn’t clean up until the bin is full.
Guard against array access out of bounds
In C language, as long as it is not limited to access memory, all memory space can be freely accessed. If we neglect it, we will have serious consequences. Of course, Java will detect it automatically.
2. Linked list
- Linked list node representation
- Print single linked list
- The single linked table inserts the node according to the index
- Gets the length of a single linked list
- Print the length of a single linked list
- Single linked table delete the node of the specified index
- Single linked list element search, return whether there is a Boolean value
- A single linked table deletes subsequent nodes of the specified index
- Single linked list inversion
- Single linked list inversion recursively
- Check whether there are rings in the linked list
- Delete the last K node
- Find the middle node
- Ordered list merging
Linked list node representation
public class Node{
int data;
Node Next;
}
Print single linked list
public class Method {
//Print single linked list
public static void PrintNode (Node list){
for(Node x=list;x!=null;x=x.Next)
System.out.print(x.data+" ");
System.out.println();
}
The single linked table inserts the node according to the index
public static Node insert(Node first,int index,Node a){
Node ret = new Node();
ret.Next=first ; // create a virtual head node
Node p=ret;
while((index--)!=0) p=p.Next;
//Complete the insertion operation of the node
a.Next=p.Next;
p.Next=a;
//Returns the real chain header node address
return ret.Next ; // the function returns the head node of the linked list
}
Gets the length of a single linked list
public static int GetLength(Node first){
int n=0;
for(Node x=first;x!=null;x=x.Next){
++n;
}
return n;
}
Print the length of a single linked list
public static void PrintLength(Node first){
System.out.println("Length : "+GetLength(first));
}
Single linked table delete the node of the specified index
public static Node Delete(Node first,int index){
if(index<0||index>=GetLength(first)) return first;
else{
Node ret=new Node();
ret.Next=first;
Node p=ret;
while((index--)!=0) p=p.Next;
//Delete the node
p.Next=p.Next.Next;
return ret.Next;
}
}
Single linked list element search, return whether there is a Boolean value
public static boolean Find(Node first,int key){
for(Node x=first;x!=null;x=x.Next){
if(x.data==key) return true;
}
return false;
}
A single linked table deletes subsequent nodes of the specified index
public static void RemoveAfter(Node first,int index){
Node ret=new Node();
ret.Next=first;
Node p=ret;
while((index--)!=0) p=p.Next;
p.Next.Next=null;
}
Single linked list inversion
public static Node reverse(Node list){
Node curr=list,pre=null;
while(curr!=null){
Node next=curr.Next;
curr.Next=pre;
pre=curr;
curr=next;
}
return pre;
}
Single linked list inversion recursively
public static Node reverseRecursively(Node head){
if(head==null|| head.Next==null )Return head; // recursion termination condition. Returns the head node of the inverted linked list
Node reversedListHead=reverseRecursively(head.Next);
head.Next.Next=head ; // change the pointing order between the two nodes
head.Next=null;
Return reversedlisthead; // returns the inverted chain header node
}
Check whether there are rings in the linked list
public static boolean checkCircle(Node list){
if(list==null) return false;
Node fast=list.Next;
Node slow=list;
while(fast!=null&&fast.Next!=null){
fast=fast.Next.Next;
slow=slow.Next;
if(slow==fast) return true;
}
return false;
}
Delete the last K node
public static Node deleteLastKth(Node list,int k){
//Two pointers, fast and slow, are used to judge if there is a difference of K positions between them fast.Nest=null , which means that the position of slow is the last K node
Node fast=list;
int i=1;
while(fast!=null&&i<k){
fast=fast.Next;
++i;
}
if(fast==null) return list;
Node slow=list;
Node prev=null;
while(fast.Next!=null){
fast=fast.Next;
prev=slow;
slow=slow.Next;
}
if(prev==null){
list=list.Next;
}else{
prev.Next=prev.Next.Next;
}
return list;
}
Find the middle node
public static Node findMiddleNode(Node list){
if(list==null) return null;
Node fast=list;
Node slow=list;
while(fast!=null&&fast.Next!=null){
fast=fast.Next.Next;
slow=slow.Next;
}
return slow;
}
Ordered list merging
public static Node mergeTwoLists(Node l1,Node l2){
Node soldier=new Node();
Node p=soldier;
while(l1!=null&&l2!=null){
if(l1.data<l2.data){
p.Next=l1;
l1=l2.Next;
}
else{
p.Next=l2;
l2=l2.Next;
}
p=p.Next;
}
if(l1!=null){ p.Next=l1;}
if(l2!=null){ p.Next=l2;}
return soldier.Next;
}
3. Stack
- Sequential stack
- Chain stack
1. Sequential stack based on array
- Constructors
- Stack operation
- Stack out operation
- Print operation
package Stack;
//Implementation of sequential stack based on array
public class ArrayStack {
private int[] items;
Private int count; // the number of elements in the stack
Private int n; // stack size
//Initialize the array and apply for an array space of size n
public ArrayStack(int n){
this.items=new int[n];
this.n=n;
this.count=0;
}
//Stack operation
public boolean push(int item){
//Insufficient array space, return false directly, fail to stack
if(count==n) return false;
//Put the data in the place with the subscript count, and add one to count
items[count]=item;
++count;
return true;
}
//Stack out operation
public int pop(){
//If the stack is empty, return - 1 directly;
if(count==0) return -1;
//Returns the array elements with the subscript count-1, and the number of elements in the stack count minus one
int tmp=items[count-1];
--count;
return tmp;
}
public void PrintStack(){
for(int i=count-1;i>=0;--i){
System.out.print(items[i]+" ");
}
System.out.println();
}
}
2. Chain stack based on linked list
- Stack operation
- Stack out operation
- Print operation
package Stack;
public class LinkedListStack {
Private node top; // top of stack (recently added element)
Private int n; // number of elements
private class Node{
//The nested class of node is defined
int data;
Node Next;
}
public boolean isEmpty(){
return top==null;
}
public int size(){
return N;
}
public void push(int data){
/*Node newNode=new Node();
//Determine whether the stack is empty
//if(top==null)
newNode=top;
top.data=data;
top.Next=newNode;
N++;*/
Node newNode=top;
top=new Node();
top.data=data;
top.Next=newNode;
++N;
}
public int pop(){
//Remove element from top of stack
If (top = = null) return - 1; // here - 1 means there is no data in the stack
int data=top.data;
top=top.Next;
N--;
return data;
}
public void PrintStack(){
for(Node x=top;x!=null;x=x.Next){
System.out.print(x.data+" ");
}
System.out.println();
}
}
4. Normal queue
- Ordinary queue based on array
- Queue based on linked list
- Implementation of circular queue based on array
1. Ordinary queue based on array
- Constructors
- Team operation
- Out of line operation
- Print elements in queue
package Queue;
//Using array to realize queue
public class ArrayQueue {
//Array: items, array size: n
private int[] items;
private int n=0;
//Head is the team head subscript and tail is the team tail subscript
private int head=0;
private int tail=0;
//Apply for an array of capacity
public ArrayQueue(int capacity){
items=new int[capacity];
n=capacity;
}
//Join the team (1), Basic Edition
public boolean enqueue(int item){
//If tail = = n, there is no space at the end of the queue
if(tail==n) return false;
items[tail]=item;
++tail;
return true;
}
//Team entry (2), improved version
public boolean enqueue1(int item){
//If tail = = n, there is no space at the end of the queue
if(tail==n){
//Tail = = n & & head = = 0, indicating that the whole queue is full
if(head==0) return false;
//Data migration
for(int i=head;i<tail;++i){
items[i-head]=items[i];
}
//Update the head and tail after moving
tail=tail-head;
head=0;
}
items[tail]=item;
++tail;
return true;
}
//Get out of the team
public int dequeue(){
//If head = = tail, the queue is empty
If (head = = tail) return - 1; // here - 1 means that the queue is empty
int ret=items[head];
++head;
return ret;
}
//Print queue
public void PrintQueue(){
for(int i=head;i<tail;++i){
System.out.print(items[i]+" ");
}
System.out.println();
}
}
2. Queue based on linked list
- Constructors
- Team operation
- Out of line operation
- Print elements in queue
package Queue;
//Queue based on linked list
public class LinkedListQueue {
Private node head; // link to the earliest node added
Private node tail; // link to the recently added node
Private int n; // number of elements in the queue
private class Node{
//The nested class of node is defined
int data;
Node Next;
}
public boolean isEmpty(){
return head==null;
}
public int size(){ return N;}
//Add elements to the end of the table, that is, join the queue
public void enqueue(int data){
Node newNode=tail;
tail=new Node();
tail.data=data;
tail.Next=null;
if(isEmpty()) head=tail;
else newNode.Next=tail;
++N;
}
public int dequeue(){
//Remove element from header
int data=head.data;
head=head.Next;
if(isEmpty()) tail=null;
N--;
return data;
}
//Printout queue elements
public void PrintQueue(){
for(Node x=head;x!=null;x=x.Next){
System.out.print(x.data+" ");
}
System.out.println();
}
}
3. Circular queue based on array
- Constructors
- Team operation
- Out of line operation
- Print elements in queue
package Queue;
public class CircularQueue {
//Array items, array size n
private int[] items;
private int n=0;
//Head is the team head subscript and tail is the team tail subscript
private int head=0;
private int tail=0;
//Apply for an array of capacity
public CircularQueue(int capacity){
items = new int[capacity];
n=capacity;
}
//Join the team
public boolean enqueue(int item){
//The queue is full
if((tail+1)%n==head) return false;
items[tail]=item;
Tail = (tail + 1)% n; // loop counting
return true;
}
//Get out of the team
public int dequeue(){
//If head = = tail, the queue is empty
If (head = = tail) return - 1; // if - 1, the queue is empty
int ret=items[head];
head=(head+1)%n;
return ret;
}
//Print queue
public void PrintQueue(){
if(n==0) return;
for(int i=head;i%n!=tail;i=(i+1)%n){
System.out.print(items[i]+" ");
}
System.out.println();
}
}
explain
The article code is too much, I originally hoped to divide it into several articles to write, but for some reasons, finally put them together, slightly bloated. The code has been tested by test cases, and there should be no errors.
If the experience is not very good, you can move my stepsGithubIt looks good inside.
Digression: for algorithm beginners, recommend a very nice bookAlgorithm Fourth EditionAll kinds of pictures in it are very detailed. If you need an electronic file, reply backAlgorithm 4You can get the download link. Backstage replyAlgorithm 01Send you an algorithm and data structure mind map. Finally, I hope we can make progress and grow together!