Reprint please indicate the source (extremely grateful.) ):
http://blog.csdn.net/javazejian/article/details/52953190
From "Zejian's blog."
Related articles:
Design and implementation analysis of sequence table and link list of Java Data structure and algorithm
Design and implementation of two-link list of Java Data structure and algorithm
Java data structure and algorithm of improved sequence table and double linked list similar to ArrayList and LinkedList (with iterator iterator and fast-fail mechanism)
Design and implementation of Java data structure and algorithm stack (stack)
Design and implementation of queues (queue) for Java data structure and algorithms
Recursive thinking of Java Data structure and algorithm (let's understand recursion more commonly)
Java data structure and algorithm tree basic concept and binary tree (BinaryTree) design and implementation
Design and implementation of a balanced binary lookup tree (AVL tree) for Java data structure and algorithm
Data structure and algorithm although the subject has been studied in the university, but has also forgotten a lot, so recently again read the book-"Data Structure and algorithm analysis" coupled with the previous reading of the "Java Data Structure" is a further in-depth study of data structure, So I'm going to write a series of data structure posts to deepen our understanding, these blogs cover their own understanding of data structures and algorithms and also contain the basics of such books, so posting will include references to some of the concepts in the book, not to be surprised when you see it, this is the beginning of this article, which mainly covers the knowledge points of sequential tables and lists, The sequence table and the linked list will be divided into two blog entries, and this article will be based on the following points to analyze the design and implementation of the linear table.
Overview of linear table abstract data type sequential storage design and implementation of linear table 1 sequential storage structure Design principle Overview 2 sequential storage structure Implementation Analysis 3 sequential storage structure design and implementation of chain-type storage of linear table with efficiency Analysis List 1 linked list chain-type storage structure Design principle 2 single-link list storage structure Realization Analysis 3 Single linked list of lead nodes and the realization of circular single chain list the efficiency analysis of single link list of single chain table 4
1. Overview of linear table abstract data types
Let's start by explaining what an abstract data type is, and we all know that Java by default, all basic data types (Int,float,boolean, and so on) support basic operations, such as addition and subtraction, because the system has helped us implement basic operations for these basic data types. For a custom data type (such as a Class), you also need to define the corresponding operation. But in the actual use of these custom data types of operations, you need to implement the relevant operations, that is, the user-defined data type of operation requires us to use the basic operations provided by the system to define and implement. These custom data structures (such as custom classes) and those that contain the implementation of the associated operation combination are called abstract data types (adt,abstract data type), so a ADT contains data declarations and operation declarations. Commonly used ADT include linked lists, stacks, queues, priority queues, binary trees, hash lists, graphs, etc., so the order table and list that we want to analyze are also belong to the ADT category. The following refers to the definition of a linear table from a book of Java Data structures:
A linear table is a finite sequence of a0,a1,..., an-1 consisting of the same data elements as n (n>=0) types, which are recorded in mathematics (a0,a1,..., an-1), where the data type of AI can be a basic data type (int,float, etc.), a character, or a class. n represents the number of elements in a linear table, also known as length. If n=0, then an empty table; if n > 0, then ai (0 < i < n-1) has and only one precursor (predecessor) element Ai-1 and a successor (successor) element ai+1,a0 without precursor elements, AI has no successor element.
The above is a summary of the abstract data types for linear tables, and we start with an in-depth analysis of sequential tables and lists. 2. Design and implementation of sequential storage of linear table (sequential table) Outline of design principle of 2.1 sequential storage structure
The underlying sequence storage structure is implemented using arrays, and arrays can store elements with the same data type, such as int,float or custom types, and when we create an array, the computer operating system assigns a contiguous block of memory to the array. This means that the address of each storage cell in the array is contiguous, so as long as you know the starting memory address of the arrays, you can compute the memory address of the N-1 storage unit in the group by simple multiplication and addition, as shown in the following illustration:
The above figure shows that in order to access an array element, the memory address of the element needs to compute its offset from the array base address, that is, to compute the offset with a multiplication and then add the base addresses, you can get the memory address of an element in the array. where c represents the size of the storage space for the element data type, and the ordinal number is the subscript index of the array. The whole process needs one multiplication and one addition operation, because the execution time of these two operations is constant time, we can think that the array access operation can be completed in a constant time, that is, the time complexity is O (1), the data structure that accesses the time complexity of any element O (1) is called random access structure. The sequence table is stored as shown above, so the order table is defined as follows (reference):
The sequential storage structure of a linear table is called a sequential table (sequential list), which uses one-dimensional arrays to store data elements from A0 to an-1 (A0,a1,..., an-1), storing AI (0< i <> n-1) in the first element of the array, So that AI is adjacent to the storage location of its precursor ai-1 and subsequent ai+1, so the physical storage order of the data elements in memory reflects the logical order between the linear table data elements. implementation analysis of 2.2 sequential storage structure
Then we analyze the implementation of the sequential table, first declare a sequential table interface class Iseqlist<t>, and then implement the interface and implement the interface method code, iseqlist interface code is as follows:
Package com.zejian.structures.LinkedList;
/** * Created by Zejian on 2016/10/30.
* Order table top-level interface/public interface Iseqlist<t> {/** * To determine whether the list is null * @return * * Boolean isempty ();
/** * Chain Table length * @return/int length ();
/** * Gets the element * @param index * @return/T get (int index);
/** * Set the value of an element * @param index * @param data * @return/t Set (int index, t data);
/** * add element according to index * @param index * @param data * @return * * Boolean Add (int index, T data);
/** * Add Element * @param data * @return * * Boolean Add (T data);
/** * Remove element by index * @param index * @return/T Remove (int index);
/** * Removes element * @param data * @return/boolean remove (T data) based on data;
/** * Removes element * @param data * @return/Boolean RemoveAll (T data) based on data;
/** * Clear List */void clear ();
/** * contains the data element * @param data * @return/Boolean contains (T data);
/** * According to the value of the query subscript * @param data * @return/int indexOf (T data);
/** * According to the data value query the last occurrence in the order table subscript * @param data * @return/int LastIndexOf (T data);
/** * Output format * @return/String toString (); }
}
The code declares an object array, the initialization array size defaults to 64, the stored element type is generic t,length is the length of the sequential table, partial method implementation is relatively simple, here not too much analysis, we mainly analyze get (int index), set (int index, T Data), add (int index, T data), remove (int index), RemoveAll (t data), indexof (t data) and other methods.
Get (int index) Implementation analysis
Getting a value from a sequential table is a fairly simple operation and highly efficient, because an array is used internally as a container for storing data. So as long as the value of the index is passed, and then the corresponding values in the array are obtained directly, the code is implemented as follows:
Public T get (int index) {
if (index>=0 && index<this.length) return
(T) this.table[index];
return null;
}
Implementation analysis of Set (int index, T data)
Replacing a value in a sequential table is also very efficient and simple, as long as you find the element that needs to be replaced based on the index value that is passed, and then replace the corresponding element value with the passed data value, as follows:
Public T Set (int index, T data) {
if (index>=0 && index<this.length&& data!=null)
{
T Old = (T) this.table[index];
This.table[index] = data;
return old;
}
return null;
}
Add (int index, T data implementation Analysis
When you perform an insert operation in a sequential table, if the capacity of its internal array has not reached its maximum value, it can be summed up in two cases, one in the header or the middle Insert, in which case you need to move the data elements in the array, less efficient, The other is at the end of the insertion, without moving the elements in the array, high efficiency. However, when the capacity of an array within a sequential table has reached its maximum size and cannot be inserted, you will need to request another larger-capacity array and copy all of the array elements to the new array, which is much more time-consuming and expensive, resulting in even worse efficiency. Therefore, in the case of inserting frequently, the insertion of sequential table is not an ideal choice. The following is a sequential table in which the array capacity is sufficiently large to insert the head or the middle insertion operation sketch (the tail insert is simpler to not demonstrate):
Sequential tables The head or center insert operation diagram when the array capacity is not sufficient:
Understanding the insertion of the preceding several sequential tables, We use code to implement this insert operation as follows, the annotation is very clear too much analysis:
/** * According to index insert element * @param index insertion position subscript, 0 as starting value * @param data inserted by * @return/public boolean add (int i
Ndex, T data) {if (data==null) return false;
Inserts the subscript's fault tolerant judgment, inserts in the front if (index<0) index=0;
Inserts the subscript's fault tolerant judgment, inserts in the last face if (index>this.length) index = this.length; Determine if the inner array is full if (this.length==table.length) {//Assign the original array to the temporary array object[] temp = this
. Table;
The original array is multiplied and the elements of the original array are copied to the new array this.table = object[temp.length*2];
Copy the original array subscript from 0 to index-1 (that is, the previous position of the insertion position) to the new array for (int i=0; i<index; i++) {this.table[i] = Temp[i]; }//From the last element of the original array until the index position, and then a position//the final vacated position is the position of the new inserted element for (int j=this.length-1; j>=in Dex
j--) {this.table[j + 1] = This.table[j];
}//Insert new value this.table[index] = data;
Length Plus One this.length++;
Insert succeeded return true; }
Implementation analysis of Remove (int index)
The delete operation of the sequential table and the previous insert operation are similar. If the elements in the order table are removed in the middle or the head, then the elements after the deletion position must move forward in turn, with less efficiency, and if the end of the order table is deleted directly, no elements need to be moved, in which case the deletion is highly efficient. As shown in the following illustration, when you delete an element ai in a sequential table, the elements behind the AI move forward in turn:
The code for the delete operation is implemented as follows:
/**
* Delete element according to index
* @param index needs to delete the subscript
* @return
/public T Remove (int index)
{
if ( This.length!=0 && index>=0 && index<this.length)
{
//Record Delete element's value and return
t old = (t) This.table[index];
From the position of the deleted element, the elements thereafter move forward for
(int j=index; j<this.length-1; J + +) {
This.table[j] = this.table[j + 1];
//Set the array element object to be an empty
this.table[this.length-1]=null;
The sequential table length is reduced by 1
this.length--;
return old;
}
return null;
}
Implementation analysis of RemoveAll (T data)
Finding the data elements that need to be deleted in the order table is the same as the data elements in the previous analysis based on the index Delete order table, so we simply compare the data element to the database and get its subscript, and then call the previously implemented remove (int index ) method to remove it. The code implementation is as follows:
@Override Public
Boolean removeall (T data) {
Boolean done=false;
if (this.length!=0 && data!=null)
{
int i=0;
while (i<this.length)
//Find the same option
if (Data.equals (this.table[i))
{
this.remove (i);//Delete by subscript Done
= true;
}
else
i++;//continue to find} return done
;
}
Implementation analysis of INDEXOF (T data)
To find the subscript of the first occurrence of the data element in the order table based on data, you only need to compare the items to be equal, the equality returns the subscript, and the -1,indexof and LastIndexOf methods are returned as follows:
/**
* According to the data query subscript
*
@return
/@Override public
int indexOf (T data)
{
if ( Data!=null) for
(int i=0; i<this.length; i++) {
//equivalent returns subscript
if (this.table[i].equals (data)
) return i;
}
return-1;
}
/**
* According to the data query the last occurrence in the order table of the subscript
* @param data
* @return * *
@Override public
int LastIndexOf (T data)
{
if (data!=null) for
(int i=this.length-1; i>=0; i--)
if (Data.equals ( This.table[i]) return
i;
return-1;
}
The above is the main method of operation of the sequential table, of course, the order table can also implement other operations, such as the initialization of the constructor in the array to initialize the whole order table, compare two information tables are equal, contains a data, etc. Here to paste the incoming data construction sequence table construction method implementation, other implementation code we do not paste here, and later realize the source will be uploaded GitHub provided to you:
/**
* Pass in an array initialization order table
* @param array
/Public seqlist (t[] array) {
if (array==null) {
throw new NullPointerException ("Array can\ ' t be empty!");
}
Create an array of corresponding capacities
this.table = new Object[array.length];
Copy element for
(int i=0;i<array.length;i++) {
this.table[i]=array[i];
}
this.length=array.length;
}
efficiency analysis of 2.3 sequential storage structure
Through the above analysis, we have a clearer understanding of the implementation of the sequential table, then look at the execution efficiency of the sequential table, mainly for the acquisition, insertion, modification, deletion and other major operations. Previously analyzed, because the sequence table is an array of storage containers, and the array is a random access structure of the container, that is, when the array is created by the operating system to allocate the array is a contiguous memory space, the array of each storage cell address is continuous, So the memory address of other storage units can be computed by a simple multiplication and addition operation after knowing the array base address (which is actually done inside the computer), the execution time of these two operations is constant time, so it can be assumed that the access operation of the array can be done in constant time, that is, the access operation of the sequential table ( The time for getting and modifying element values is complex O (1).
For inserting or deleting elements in a sequential table, the efficiency is not very good, because the insertion or deletion of the operation is based on location, you need to move the other elements in the array, so the insertion or deletion of the sequential table, the algorithm spent the time is mainly used to move elements, such as in the Order table head insert or delete, Efficiency seems pretty bad. If you insert or delete at the top, you need to move n (this assumes a length of n) element, or 0 if you want to insert or delete the last element. Here we assume that the insert or delete value is the first (0<i<=n) element with the probability of Pi p_{i}, and the average number of moves to insert or delete an element is summed as:
P1∗ (n−1) +p2∗ (n−2) +...+pi∗ (n−i) +...+pn−1∗1+pn∗0=∑i=1n