Our goal:
1. Understand the characteristics of linear structures . Master the definition, search, insertion and deletion of sequence tables.
2. Master the definition, creation, search, insertion and deletion of linked lists.
3. Be able to compare the different characteristics and applicable occasions of the two storage structures from the perspective of time and space complexity . (Continually updated)
Table of contents
1. Chain representation and realization of linear table
1.2 Terms related to chained storage
1.3 Features of Linked List (Linked Storage Structure)
1.4 Advantages and disadvantages of linked list
1.5 Definition and implementation of singly linked list
1.6 Algorithm implementation of several simple basic operations
2. Important basic operations of linear tables
3.1 Analysis of operation time efficiency of linked list
3.2 Establishment of single linked list (forward insertion method)
3.3 Establishment of single linked list (tail insertion method)
foreword
Today we mainly learn the important basic operations of linear lists and how to use linked lists.
1. Chain representation and realization of linear table
1.1 Chain storage structure
The location of nodes in memory is arbitrary, that is, logically adjacent data elements are not necessarily physically adjacent.
Therefore, the linked representation of a linear list is also called a non-sequential image or a linked image.
How it's implemented - via pointers.
Example 1 Storage image of singly linked list
Example 2 Draw the chain storage structure of 26 English alphabets
Logical structure: ( a, b, … ,y, z)
Chain storage structure:
As you can see, each node consists of two domains:
Data field: Store element value data.
Pointer field: stores the storage location of the immediate successor node.
1.2 Terms related to chained storage
1. Node: the storage image of the data element. It consists of two parts, the data field and the pointer field.
2. Linked list : n nodes are composed of pointer chains to form a linked list. It is the linked storage image of the linear list, called the linked storage structure of the linear list.
3. Singly linked list, double linked list, circular linked list:
A linked list whose nodes have only one pointer field is called a singly linked list or a linear linked list.
A linked list with two pointer fields is called a doubly linked list.
A linked list connected end to end is called a circular linked list.
Schematic diagram of circular linked list:
4. Head pointer, head node and head node:
The head pointer is a pointer to the first node in the linked list.
The head node refers to the node that stores the first data element a1 in the linked list.
The head node is a node attached before the head node of the linked list.
In the data field, only information such as the table flag and table length are left blank.
The schematic diagram of the logical structure of the linked list in the above example has the following two forms:
Difference : ① headless node ② headed node
Next, let's discuss together:
Discussion 1. So how should empty tables be represented?
Answer: When there is a head node, when the pointer field of the head node is empty, it means an empty table.
Discussion 2. What are the benefits of setting the head node in the linked list?
1. Facilitate the processing of the first node
The address of the head node is stored in the pointer field of the head node, so the operation on the first position of the linked list is consistent with other positions, and no special processing is required.
2. Facilitate the unified processing of empty tables and non-empty tables
Regardless of whether the linked list is empty or not, the head pointer is a non-null pointer pointing to the head node, so the processing of the empty list and the non-empty list is unified.
Discussion 3. What is contained in the data field of the head node?
The data field of the head node can be empty, and additional information such as the length of the linear list can also be stored, but this node cannot be included in the length value of the linked list.
Here is the data field of the head node
1.3 Linked list(chain storage structure) characteristics
1. The position of the node in the memory is arbitrary, that is, logically adjacent data elements are not necessarily physically adjacent.
2. When accessing, you can only enter the linked list through the head pointer, and scan the remaining nodes backward through the pointer field of each node, so the time it takes to find the first node and the last node is different.
Therefore, this method of accessing elements is called sequential access.
1.4 Advantages and disadvantages of linked list
advantage
Time: Operations such as insertion and deletion do not need to move data, but only need to modify the link pointer, which is more efficient.
Space: The number of data elements can be freely expanded.
shortcoming
Time: The access efficiency is not high, and sequential access must be used, that is, when accessing data elements, they can only be accessed in the order of the linked list (follow the vine).
Space: The storage density is small.
1.5 Definition and implementation of singly linked list
non-empty table
empty table
The singly linked list is uniquely determined by the header, so the singly linked list can be named by the name of the head pointer; if the name of the head pointer is L, the linked list is called list L.
Code:
typedef struct Lnode
{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList; // *LinkList为Lnode类型的指针
Note: Distinguish between two different concepts of pointer variables and node variables.
Pointer variable p: Indicates the node address ———> LNode *p
Node variable *p : represents a node
If p->data=ai, then p->next->data=ai+1
1.6 Algorithm implementation of several simple basic operations
To recap:
initialize (construct an empty table)
Status InitList_L(LinkList &L){
L=new LNode;
L->next=NULL;
return OK;
}
destroy
Status DestroyList_L(LinkList &L)
{
LinkList p;
while(L)
{
p=L;
L=L->next;
delete p;
}
return OK;
}
empty
Status ClearList(LinkList & L){
// 将L重置为空表
LinkList p,q;
p=L->next; //p指向第一个结点
while(p) //没到表尾
{ q=p->next; delete p; p=q; }
L->next=NULL; //头结点指针域为空
return OK;
}
Let's solve the problem - find the length of the table
Method: "count" nodes
The pointer p points to each node in turn, "counting" from the first element, and "counting" to the last node.
Code:
p=L->next;
i=0;
while(p){i++;p=p->next;}
The final overall code implementation:
int ListLength_L(LinkList L){
//返回L中数据元素个数
LinkList p;
p=L->next; //p指向第一个结点
i=0;
while(p){//遍历单链表,统计结点数
i++;
p=p->next; }
return i;
}
Next, check whether the table is empty:
int ListEmpty(LinkList L)
{
//若L为空表,则返回1,否则返回0
if(L->next) //非空
return 0;
else
return 1;
}
According to the previous article: https://mp.csdn.net/mp_blog/creation/editor/129893007
Then I talked about the important basic operation of the linear table- value
2. Important basic operations of linear tables
2.5 value
According to position i, get the content of the corresponding position data element.
So how to find the i-th element in the sequence table?
Answer: The lookup of the linked list starts from the head pointer of the linked list, and searches down the chain domain next node by node until the i-th node is searched. Therefore, a linked list is not a random access structure.
For example, take out the elements i=3 and i=15 in the table respectively .
Algorithm steps
1. Scan along the chain from the first node (L->next), use the pointer p to point to the currently scanned node, and the initial value of p = L->next;
2. j is used as a counter to accumulate the number of nodes currently scanned, and the initial value of j is 1;
3. When p points to the next node scanned, the counter j is incremented by 1;
4. When j = i, the node pointed to by p is the ith node to be found.
Code:
//获取线性表L中的某个数据元素的内容
Status GetElem_L(LinkList L,int i,ElemType &e){
p=L->next;j=1; //初始化
while(p&&j<i){ //向后扫描,直到p指向第i个元素或p为空
p=p->next; ++j;
}
if(!p || j>i)return ERROR; //第i个元素不存在
e=p->data; //取第i个元素
return OK;
}//GetElem_L
2.6 Search
Get the location of the data according to the specified data.
Algorithm steps
1. From the first node, compare with e in turn;
2. If a data element whose value is equal to e is found, return its "position" or address in the linked list;
3. If no element whose value is equal to e is found after searching the entire linked list, return 0 or "NULL".
Code:
//在线性表L中查找值为e的数据元素
LNode *LocateELem_L (LinkList L,Elemtype e) {
//返回L中值为e的数据元素的地址,查找失败返回NULL
p=L->next;
while(p &&p->data!=e)
p=p->next;
return p;
}
Another way:
//在线性表L中查找值为e的数据元素
int LocateELem_L (LinkList L,Elemtype e) {
//返回L中值为e的数据元素的位置序号,查找失败返回0
p=L->next; j=1;
while(p &&p->data!=e)
{p=p->next; j++;}
if(p) return j;
else return 0;
}
2.7 insert
Insert a new node whose value is x into the position of the i-th node in the table, that is, between ai-1 and ai.
Insertion process: s->next=p->next; p->next=s;
NOTE: Step 1 and Step 2 are not interchangeable! If step 2 is taken first, it will cause trouble between ai-1 and ai. Just like s->next=p->next; is a bridge linking ai-1 and ai .
Algorithm steps:
1. Find the storage location p of ai-1;
2. Generate a new node *s;
3. Set the data field of the new node *s to x;
4. The pointer field of the new node *s points to the node ai;
5. Let the pointer field of node *p point to the new node *s.
Code:
//在L中第i个元素之前插入数据元素e
Status ListInsert_L(LinkList &L,int i,ElemType e){
p=L;j=0;
while(p&&j<i−1){p=p->next;++j;} //寻找第i−1个结点
if(!p||j>i−1)return ERROR; //i大于表长 + 1或者小于1
s=new LNode; //生成新结点s
s->data=e; //将结点s的数据域置为e
s->next=p->next; //将结点s插入L中
p->next=s;
return OK;
}//ListInsert_L
2.8 delete
Delete the i-th node of the table.
Algorithm steps :
1. Find the storage location p of ai-1;
2. Temporarily store the address of node ai in q for release;
3. Make p->next point to the direct successor node of ai;
4. Keep the value of ai in e;
5. Free up space for AI.
Code:
//将线性表L中第i个数据元素删除
Status ListDelete_L(LinkList &L,int i,ElemType &e){
p=L;j=0;
while(p->next &&j<i-1){ //寻找第i个结点,并令p指向其前驱
p=p->next; ++j;
}
if(!(p->next)||j>i-1) return ERROR; //删除位置不合理
q=p->next; //临时保存被删结点的地址以备释放
p->next=q->next; //改变删除结点前驱结点的指针域
e=q->data; //保存删除结点的数据域
delete q; //释放删除结点的空间
return OK;
}//ListDelete_L
3. Linked list
3.1 Analysis of operation time efficiency of linked list
1. Search: Since the linear linked list can only be accessed sequentially, that is, when searching, it needs to start from the head pointer, and the time complexity of searching is O(n) .
2. Insertion and deletion: Because the linear linked list does not need to move elements, it only needs to modify the pointer. Generally, the time complexity is O(1) .
Note: If you want to perform forward insertion or deletion in the singly linked list, because you need to find the predecessor node from the beginning, the time complexity is O(n).
3.2 Establishment of single linked list (forward insertion method)
Starting with an empty table, read in data repeatedly:
Generate a new node, store the read data into the data field of the new node, and then insert the new node into the front end of the linked list.
Code:
void CreateList_F(LinkList &L,int n){
L=new LNode;
L->next=NULL; //先建立一个带头结点的单链表
for(i=n;i>0;--i){
p=new LNode; //生成新结点
cin>>p->data; //输入元素值
p->next=L->next;L->next=p; //插入到表头
}
}//CreateList_F
3.3 Establishment of single linked list (tail insertion method)
Starting from an empty list L, insert new nodes to the end of the linked list one by one, and the tail pointer r points to the end node of the linked list.
Initially, both r and L point to the head node. Every time a data element is read, a new node is applied for, and after the new node is inserted into the end node, r points to the new node.
Code:
void CreateList_L(LinkList &L,int n){
//正位序输入n个元素的值,建立带表头结点的单链表L
L=new LNode;
L->next=NULL;
r=L; //尾指针r指向头结点
for(i=0;i<n;++i){
p=new LNode; //生成新结点
cin>>p->data; //输入元素值
p->next=NULL; r->next=p; //插入到表尾
r=p; //r指向新的尾结点
}
}//CreateList_L
Four. Summary
The above is what I will talk about today. The method of the linked list has not been introduced yet, and I will continue to update it. In this chapter, we have mainly explained the important basic operations of the linear table. I hope you can understand it a lot, and if you have any questions, please advise the big guys! I will continue to work hard!