Algorithm + data structure = programming
1 > what is a data structure
1.1 > computer problem solving process

Abstraction of specific problems

Establish the solution model of practical problems

The corresponding algorithm is designed

Programming and debugging

Practical problems are solved
 Numerical calculation problem: the solution model can be described by mathematical equations. The operation objects involved are generally some simple data types such as integer, real or logical. Therefore, the programmer's main focus is on the skills of programming, rather than the organization and storage of data
 Non numerical calculation problem: the model cannot be solved by mathematical equations. Corresponding data structures must be established to describe, analyze how the data used in the problem are organized, study the relationship between the data, and then design appropriate algorithms
1.2 > data structure research content:
There are relationships between data, which often affect the selection and efficiency of algorithms
Data structure is the subject of studying data objects, their relationships and operation algorithms in computer non numerical computing problems. It mainly includes four aspects:
Logical structure of data  structural relationship between data elements
Storage structure of data  the representation of logical structure of data in computer
Each structure definition is adapted to various algorithms  insertion, deletion, modification, query, sorting, etc
The corresponding algorithm is designed and the efficiency of the algorithm is analyzed
1.3 > data relationships
Data: the general name of all symbols that can be recognized, stored and processed by the computer (including numbers, characters, sound, images, video and other information), which is the general name of the objects operated by the computer
Data element: it is the basic unit of data and has completely determined practical significance (element, node, vertex, record, etc.). Data element is an individual of data
Data item: the item that constitutes a data element. A data item is the smallest and indivisible unit of data
The relationship among the three: Data > data elements > data items
Data object: a collection of data elements with the same nature. A data object is a subset of data
Structure: in any problem, data elements do not exist in isolation, but there is a certain relationship between them. This relationship between data elements is called structure
The same elements, different "relationships" constitute different "structures"
A data structure is a collection of data elements that have one or more specific relationships (logical relationships) with each other
Logical structure: refers to the logical relationship between data elements
 aggregate
 linear structure
 tree structure
 Graphic structure or reticular structure
The data structure can be defined as a binary, Data_Structure=(D, S)
D: Finite set of data elements
S: Relational finite set
Physical structure: the representation (also known as image) of data structure in computer is called the physical structure of data, also known as storage structure. The representation (or image) of logical structure of data in computer memory. It depends on computer
Mapping method of "relationship"
Sequential mapping  sequential storage structure: the logical relationship between data elements is represented by the relative position of elements in memory (no additional information is stored)
Chained image  chained storage structure: the logical relationship between data elements (additional information pointer) is represented by a pointer indicating the storage address of the element
1.4 > algorithm
Algorithm: it is a limited instruction set, which can complete specific functions by following the instruction flow
Algorithm is a finite sequence of instructions for solving a specific problem, in which each instruction represents one or more operations
Five important characteristics of the algorithm:
 Poverty
 certainty
 feasibility
 Have input
 Have output
Evaluation indexes of the algorithm: correctness, readability, robustness, efficiency and low storage requirements
Algorithm = control structure + original operation (operation of inherent data type)
How to estimate the time complexity of the algorithm?
The "running workload" of a specific algorithm only depends on the scale of the problem (usually expressed as integer n), or it is a function of the scale of the problem
Execution time of algorithm = ∑ execution times of original operation (i) × Execution time of original operation (i)
Time complexity of the algorithm: the number of repetitions of basic operations in the algorithm is a function f(n) of the problem scale n, and the time measurement of the algorithm is recorded as
T(n) = O(f(n))
Sometimes, to estimate the efficiency of the algorithm, you can directly estimate the sentence frequency of the deepest sentence
1.5 > abstract data types
A mathematical model and a set of operations defined on the model
 Atomic type
 Fixed aggregate type
 Variable aggregate type
ADT Abstract data type name{ data object:; Data relation:; basic operation : }
1.6 > purpose

The program runs fast

Can access these data more quickly

Data takes up the least memory space
However, in terms of points 1 and 2, it is contradictory in most cases, because using large memory space can usually speed up the running speed of programs, and vice versa
2 > linear table
Single linked list

Sequential table static storage allocation predetermined capacity

Linked list dynamic storage allocation runtime allocation space
2.1 > linearity table
Definition of linear table: finite sequence of n data elements
2.1.1 > main operations of linear table
1 create an empty linear table
2 destroy linear table
3 reset the linear table to an empty table
4 judge whether the linear table L is empty
5 find the number of data elements in the linear table
6 take the Ith data element in the linear table L
7 find a data element in a linear table
8 find the precursor element of a data element in the linear table
9 find the successor element of a data element in the linear table
10 insert a new data element into the linear table
11 delete a data element in the linear table
12 merge two linear tables
2.2 > sequential representation and implementation of linear table
The sequential representation of linear table is also called sequential storage structure or sequential image
Sequential storage definition: a storage structure that stores logically adjacent data elements in physically adjacent storage units
Sequential storage method: a group of storage units with continuous addresses are used to store the data elements of the linear table in turn. The linear table with this storage structure is called the sequential table
2.3 > chain representation and implementation of linear list
2.3.1 > type definition of linear table
Chained storage: use a set of arbitrary storage units to store the elements of a linear table
continuity
Discontinuity
Scattered distribution
Characteristics of chain storage structure: the location of its nodes in the memory is arbitrary, that is, logically adjacent data elements are not necessarily adjacent physically
2.3.2 > single linked list
Single linked list: n nodes are linked into a linked list, and each node has only one pointer field
Header pointer: indicates the storage location of the first node in the linked list
Header node: no information or additional information such as table length can be stored in the data field
The header node brings the following two advantages:
(1) Since the position of the start node is stored in the pointer field of the head node, the operation at the first position of the linked list is the same as that at other positions of the table
Consistent without special treatment
(2) No matter whether the linked list is empty or not, its head pointer refers to the non null pointer to the head node (the pointer field of the head node in the empty table is empty), so the processing of empty table and non empty table is unified
Tail flag: the pointer of the last node in the linear linked list is NULL (NULL or / \)
A single linked list can be uniquely determined by a header pointer
Storage features:
– logical order and physical order are not necessarily the same
 the logical relationship between elements is represented by pointers
2.3.3 > storage image of node data elements
data next
Data field pointer field
Data field: stores data element information
Pointer field: store direct and subsequent storage locations
Single linked list n nodes are linked into a linked list, and each node has only one pointer field
2.3.4 > supplementary c language knowledge
sizeof(x): calculates the length of the variable x
mallocm): open up an address space of m bytes and return the first address of this space
free §: release the storage space of the variable indicated by the pointer p, that is, completely delete a variable
2.3.5 > intersection operation
Algorithm idea:
① Take out a data element from LB in turn;
② Judge whether it exists in LA;
③ If not, insert into LA.
void union( List &LA, LB ) { //Insert all data elements in LB but not in LA into LA LA_len = ListLength (LA)；//Determine the length of the linear table LA LB_len = ListLength (LB)；//Determine the length of the linear table LB for( i = 1; i <=LB_len; i++ ) { GetElem(LB, i, e)； //Take the ith data element in LB and assign it to e if (!LocateElem(LA, e, equal) ) //Does the judgment exist in LA ListInsert(LA, ++LA_len, e) //If the same element as e does not exist in LA, insert it into La} }}//union
Time efficiency
T(n) = O(ListLength(LAListLength(LB))
2.3.6 > sequential merging of two arrays
Algorithm idea:
① Initialization: set LC as an empty table, set variables and j, and the initial value is 1,
Point to the first data element of LA and LB respectively, and k represents the value of LC
Length, initial value is 0.
**② When I < = listlength (LA) * * and j < = listlength (LB),
ü judgment: if the element referred to by i < = the element referred to by J, the element referred to by i will be
The element is inserted before k+1 of LC, and the values of i and k are added with i respectively;
ü otherwise, insert the element referred to by J before k+1 of LC, and j,k
Add 1 to the values of.
③ Repeat ② until the elements of a table are inserted.
④ Insert the remaining elements of the table that have not been inserted into the LC in turn.
void MergeList(List LA，List LB, List &LC){ //It is known that the elements in LA and LB are arranged in non decreasing order, and the elements in LC are obtained by merging //The prime is still non decreasing by value InitList (LC)； i = j = 1； k = 0； //initialization LA_len = ListLength (LA)； LB_len = ListLength (LB)； while ((i <= LA_len) && (j <= LB_len) ){ //Neither LA nor LB is empty GetElem(LA, i, ai); GetElem(LB, j, bj); if (ai <= bj) { ListInsert(LC, ++k, ai); ++i; } else {ListInsert(LC, ++k, bj); ++j; } } while ( i <= LA_len ){ //After LB is inserted, LA itself is not decreasing GetElem(LA, i++, ai); ListInsert(LC, ++k, ai); } While (j <= LB_len) { GetElem(LB, j++, bj); ListInsert(LC, ++k, bj); } }//MergeList algorithm 2.2
Time efficiency
T(n) = O(ListLength(LA)+ListLength(LB))
2.3.7 > establishment and output of single linked list
Tail interpolation
For example, the structure of single linked list is used to store 26 English letters
Implementation idea: first open the header pointer, then successively open up storage space and assign values for each data element, and send the address to the front pointer in time
include<stdio.h> include<stdlib.h> typedef struct liu{ char data; struct liu *next; }test; liu *p,*head; //Three pointer variables are generally required int m=sizeof(test); /*After the structure type is defined, each variable The length of m is fixed, m can be found once*/
void build() //The generation of the alphabet should be linked slowly one by one { int i; head=(test*)malloc(m); //m=sizeof(test) has been calculated previously p=head; for(i=1;i<26;i++) //Because the tail node needs special treatment, i ≠ 26 { p>data=i+'a'1; // The first node value is the character a p  > next = (test *) malloc (m)// Open a new space for subsequent nodes! p=p>next；} //Change the pointer variable P to point to the subsequent node p>data=i+'a'1; //The last element is handled separately p>next=NULL ;} //The pointer field of the end node of the single linked list should be set to null!
P = P  > next pointer moves back
void display() /*Output of alphabetic list*/ {p=head; while (p>next!=NULL) /* As long as we don't get to the last element, Keep "following the vine" output */ {printf("%c",p>data); p=p>next; } printf("%c\n",p>data); //Don't forget to output tail node data } void display() /*Output of alphabetic list*/ {p=head; while (p!=NULL) /* As long as we don't get to the last element, Keep "following the vine" output */ {printf("%c",p>data); p=p>next; } }
Establishment of single linked list  head interpolation method
Void CreateList_L(LinkList &l，int n){ //Input the values of n elements in the reverse bit order to establish the single chain linear table L of the leading node L=(LinkList) malloc ( sizeof (LNode) ); L>next=NULL; //First establish a single linked list of leading nodes for ( i=n; i>0;i){ p＝(LinkList )malloc(sizeof(LNode)); //Generate new node scanf(&p>date); //Enter element value p>next= L>next; L>next=p; //Insert into header } }//CreateList_L
Insertion of single linked list
Insert step (i.e. core statement):
(1) s=(LinkList )malloc(sizeof(LNode)); // Element x nodes shall be generated in advance:
(2) s>data=x; // Add content to new node
(3) s>next=p>next;// Chain the new node into the chain
(4) p>next=s ； // Change the pointer of the previous node
Status ListInsert_L(LinkList &L, int i, ElemType e) { //Apply for a new node and put e into //Insert element e before the ith position in the single chain linear table L of the leading node p = L; j =0; while (p && j<i1) {p=p>next; ++j;} //Find node i1 if (!p  j>i1) return ERROR; //i is less than 1 or greater than the meter length s=(LinkList)malloc(sizeof(LNode)); //Generate new node s>data = e; s>next = p>next; p>next = s; //Insert into Table L return OK; }//ListInsert_L
Time efficiency T(n) = O(n)
Deletion of single linked list
Delete step (i.e. core statement):
q = p>next;// Save the pointer of b to point to c
p>next=q>next; // a. C two nodes are connected
e=q>data; // Use e to return the deleted node value
free(q) ； // Delete node b and release it completely
Status Listdelete_L(LinkList &L, int i, ElemType &e) { //Delete the ith element in the single chain linear table L with nodes and return its value by e p = L; j =0; while (p>next && j<i1) {p=p>next; ++j;} //Find node i1 (or find node i and point p to its precursor) if (!(p>next)  j>i1) return ERROR; //Unreasonable deletion position q=p>next; p>next=q>next; e=q>data; free(q); //Delete and release nodes return OK; }//Listdelete_L
Search by bit
Status GetElem_L(LinkedList L,int i,ElemType &e) { // L is the header pointer of the single linked list of the leading node // Find the ith element node in the single linked list L, and return its value with e if it exists p=L>next；j=1; //Initialization, p points to the first node, and j is the counter while ( p && j<i ) //Find the pointer backward until p points to {p=p>next; ++j; } The first i Elements or p Empty if (!p  j>i) return ERROR; /*!p And j > I? The ith element does not exist*/ e=p>data; return OK; }// GetElem_L
Finding by value adds judgment to the loop
Union of two ordered linked lists
Void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc) { pa=La>next; pb=Lb>next; //initialization Lc=pc=La； while(pa&&pb) //pa and pb have a null jump out cycle { if(pa>data<=pb>data) {pc>next=pa; pc=pa; pa=pa>next;} else {pc>next=pb; pc=pb; pb=pb>next} } pc>next = pa?pa:pb ; //Insert remaining segments //The single linked list La and LB sorted by non decreasing value are also sorted by value after merging into LC free(Lb); //Release the header node of Lb } //MergeList_L
2.4 > circular linked list
Single cycle linked list:
In the single linked list, the pointer field NULL of the terminal node is changed to point to the header node or the start node. The whole linked list forms a ring to form a single circular linked list, which is called circular linked list for short
Features: starting from any node in the table, you can find other nodes in the table
Sometimes, if the tail pointer is set instead of the head pointer in the circular linked list, some operations can be simplified. For example, when merging two circular linked lists into one table, it is only necessary to connect the tail of one table with the header of the other table
Bidirectional linked list:
In each node of the single linked list, set a pointer field prior to its direct precursor node
Data: a data field that stores data elements**
prior: pointer field, which stores the address of the direct precursor node of the node**
next: pointer field, which stores the address of the direct successor node of the node**
Bidirectional linked list will be widely used in nonlinear structure (such as tree structure)
(p > next) > prior == (p > prior) > next == p
Insert operation
(1) s=(DuLinkList )malloc(sizeof(DuLNode));
//Element x nodes shall be generated in advance:
(2) s>data=x;
//Add content to new node
(3) s>prior = p>prior;
(4) p>prior>next = s；
//Chain the new node into the chain
(5) s>next = p ；
The pointer in both directions needs to be modified
(6) p>prior = s;
status ListInsert_Dul(DuLinkList &L, int i, ElemType e) { //Insert element e before the ith position in the bidirectional circular linked list of the leading node // The legal value of i is 1 ≤ i ≤ table length + 1 if (!(p=GetElemP_Dul(L,i))) //Determine the insertion position in L return ERROR; //p=NULL, illegal insertion position s = (DuLinkList)malloc(sizeof(DuLNode)); if (!s) return (ERROR) //Insufficient space, overflow s>data = e; s>prior = p>prior; p>prior>next=s; s>next= p; p>prior = s; return OK; }//ListInsert_Dul
Delete operation
(1) e = p>data;
(2) p–>prior–>next = p–>next;
(3) p–>next–>prior = p–>prior;
(4) free§;
Status ListDelete_Dul(DuLinkList &L,int i,ElemType &e) { //Delete the ith element of the double chain cyclic linear table L with the leading node, and I is legal The value is 1≤i≤Table length if (!(p=GetElemP_Dul(L,i))) //Determine the position pointer p of the ith element in L return ERROR; //p=NULL, the ith element does not exist e=p>data; // The deleted element is assigned to e p – > prior – > next = P – > next; p–>next–>prior=p–>prior; //Modify pointers in both directions free(p); return OK; }//ListDelete_Dul
2.5 > comparison of storage allocation methods

The sequential table adopts the sequential storage structure, that is, a storage unit with continuous addresses is used to store the data elements of the linear table in turn. The logical relationship between the data elements is realized through the storage location (logical and physical consistency)

The single linked list adopts the linked storage structure, that is, a group of arbitrary storage units are used to store the elements of the linear table, and pointers are used to reflect the logical relationship between data elements (logic and physics are not necessarily consistent)
2.6 > space performance comparison
Define the storage density of nodes: space performance refers to the amount of storage space occupied by a storage structure
Storage density: the storage occupied by the data field / the storage occupied by the whole node
If the linear table needs to be searched frequently but rarely performs insertion and deletion operations, or its operations are closely related to the position of elements in the table, the sequential table should be used as the storage structure;
If the linear table needs to be frequently inserted and deleted, the single linked table should be used as the storage structure
When the number of elements in a linear table changes greatly or is unknown, it is best to use a single linked list; If the user knows the approximate length of the linear table in advance, the space efficiency of using the sequential table will be higher