Learning Data Structure-Chapter 2: Linear List (Chained Storage, Single Linked List, Double Linked List, Circular Linked List)

Chapter 2: Linear table (chain representation)

Learning Data Structure-Chapter 2: Linear Table (Sequential Storage, Insertion, Delete) This article talks about the sequential representation of linear tables, which is the sequential table. Although the sequential table can be stored randomly, it needs to apply for a large block when initializing. Continuous storage space, and when inserting and deleting operations, also need a large number of moving elements, the time complexity is relatively high, the following is another storage structure of the linear table:链式存储

1. Definition of singly linked list

The chain storage of the linear table is also called:, the data elements in the linear table are stored 单链表through a set 任意of storage units.

Data elements are stored in any position, not necessarily continuous, and linear logic relationships are realized through pointers.

We such single linked list 数据加地址的组合is called a single linked list of nodes, a 结点storage data element 数据域and the next node (element data) address 指针域components.

Insert picture description here
There are two ways to create a singly linked list

  • Singly linked list without head node
  • Singly linked list with head node

For a singly linked list with a head node, the data field of its head node generally does not store data, and its pointer field stores the address of the first node.
advantage:

  • The first position of the linked list is the same as the operations at other positions (such as insert operation: a linked list without a head node. When a node is inserted into the table, there are nodes on both sides, and when the table header is inserted into the node, there is no node on the left. Point, but the head node is the same.)
  • Uniform operation of empty and non-empty lists

Insert picture description here

2. Basic operation of singly linked list

2.1 Head insertion method establishment

Insert picture description here

//头插法
LinkList List_HeadInsert (LinkList &L){
    
    
      LNode *s;
      int x;
      L=(LinkList)malloc(sizeof(LNode));
      L->next=NULL;
      scanf("%d",&x);
      while(x!=9999){
    
    
         s=(LNode*)malloc(sizeof(LNode));
         s->data=x;
         s->next=L->next;
         L->next=s;
         scanf("%d",&x);
      }
      return L;
}

Insert picture description here
Time complexity: O(n)

2.2 The establishment of the tail insertion method

Insert picture description here

LinkList List_TailInsert (LinkList &L){
    
    
     int x;
     L=(LinkList)malloc(sizeof(LNode));
     LNode *s,*r=L; //注意这里重新定义一个指针r,作为尾指针,同时初始化为了头节点
     scanf("%d",&x);
     while(x!=999){
    
    
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s; //修改尾指针,指向新插入的结点
        scanf("%d",&x);
     }
	 r->next=NULL;
	 return L;
}

Time complexity: O(n)

2.3 Search by serial number & search by value

The singly linked list must be traversed according to and searching by sequence number.

Search by serial number

LNode *GetElem(LinkList L,int i){
    
    
    int j=1; //标识当前结点的序号
    LNode *p=L->next; //当前所查找的结点,初始化为头节点的下一个结点,因为头节点不保存数据
    if(i==0){
    
     //序号不合法
       return L;
    }
    if(i<1){
    
     //序号不合法
       return NULL;
    }
    while(p&&j<i){
    
     //当结点不为空,且序号小于j的时候,继续循环
      p=p->next;
      j++;
    }
    return p;
}

Time complexity: O(n)

Search by ordinal value

LNode *LocateElem(LinkList L,ElemType e){
    
    
    //初始化一个指针指向头节点的下一个结点
    LNode *p=L->next;
    //判断结点不为空,且数据不为e
    while(p!=NULL&&p->data!=e){
    
    
     //如果结点不为空,且值不为e,则指针继续向下移动
      p=p->next;
    }
    return p;
}

Time complexity: O(n)

2.4 Insert node

There are two ways to insert, pre-interpolation and post-interpolation. For example, the insert position is i, the pre-interpolation method is to insert before the position of i, and the post-interpolation method is to insert after the position of i, so the pre-interpolation method is to find i-1 Position, and then interpolate to find the position of i. So if the position of i is known, there will be a difference between the two methods. The pre-interpolation method still needs to traverse the linked list O(n), and the post-interpolation method directly uses this position to O(1). The post-interpolation method can realize the pre-interpolation method, and the positions of the two nodes can be exchanged after insertion. The following demonstrates the pre-interpolation method:

Insertion node must first know the inserted location, if the insertion position i, it is necessary to know i-1the location of the node. Then modify the pointer to the new node i-1to the next node position, and then modify i-1the node pointer to the newly inserted node.

Insert picture description here
注意 The following code cannot swap positions.

s->next=p->next;
p->next=s;

Why???
This order cannot be exchanged. If exchanged, the inode address will be lost.
p->next=s;At this time , the address pof the inode stored in the node has been overwritten, becoming the address of the new node, and then s->next=p->next;this is equivalent to sthe point of the node pointing to himself. In this way, the following linked list is discarded.

2.5 delete node

The location of the node is unknown

If you want to delete the list of ithe position of the node number, modify the first i-1pointer number of the node to point to the first i+1number of node position. It is to be noted that the first to use a pointer to ia node, because after the changes we will lose the first iposition of the nodes, so that the back will not be able to release ithe space node.

Insert picture description here
The position of the node is known*p

At this time, you can exchange the data of the pnode and the 后一个node first , and then delete the next node. Note that there must be one 指针指向后一个结点to free up space later.

Insert picture description here

2.6 Seeking the table length

The linked list judgments of head nodes and headless nodes are different.
Insert picture description here

3. Special linked list

3.1 Double-linked list

When using a singly linked list, we know ithe pointer of the current node . When performing operations such as inserting and deleting, we need to know its predecessor node. We need to find its predecessor node by searching by sequence number. This time complexity is O(n).

Insert picture description here

If the node has a pointer that directly points to its predecessor node, then we can directly find its predecessor node. So there is a double-linked list.

Insert picture description here
Insert picture description here

3.1 Double-linked list insertion operation

Insert picture description here
The time complexity of the pre-interpolation method and the post-interpolation method are both O(1). The insertion order can be adjusted, but the first and second steps must be before the fourth step, because in the second step we need i+1the position of the node.

In a singly linked list, the steps for inserting in the header, in the table, and in the footer are the same. But note that in a double-linked list, inserting at the head and the end of the table is a different step. When inserting at the end of a double-linked list, pay attention to the fact that there is no next node after the end of the table, so you cannot modify the pointer of the next node to the predecessor, otherwise an error will occur.

3.1 Delete operation of doubly linked list

First find qthe pointer of the predecessor node of the node to be deleted ( ), set it p, and then directly modify the pointer to release the space. The time complexity is O(1). It is also different when deleting at the end of the table.
Insert picture description here

3.2 Circular linked list

3.2.1 Circular singly linked list

Suppose we use a singly linked list, we only know the tail pointer, but need to know the head pointer, which is impossible to know at this time.
This is if the pointer of the last node of the singly linked list points to the head section, so that the head pointer can be found. Such a linked list forms a ring, which is called a circular singly linked list.
In this way, only one tail pointer is enough, and it is more efficient: because if there is only a head pointer, we want to find the tail pointer and need to traverse the singly linked list, but if there is a tail pointer, we can find the head pointer directly.
Insert and delete operations in a circular singly linked list are the same at every position.

Insert picture description here

3.2.1 Circular doubly linked list

We need to modify the pointer of the last node of the linked list to the head node, and need to modify the predecessor pointer of the head node to point to the last node. At this time, the insertion and deletion operations at each position are the same.Insert picture description here

3.2.3 The circular linked list is empty

We found that in the circular linked list, we used the pointer of each node, that is to say, in the circular linked list, there are no null pointers. How should we judge null at this time? ? Please see the picture below:
Insert picture description here

3.3 Static linked list

Static 就是使用数组来实现的链式存储结构的链表lists: .

Single linked list:
Insert picture description here
static linked list:

Insert picture description here
Each node in the static linked list not only has its own data part, but also needs to store the location of the next node, so the storage implementation of the static linked list uses a structure array, which contains two parts: 数据域and 游标(stores the next node Subscript at the position in the array).

#define MaxSize 50
typedef struct DNode{
    
    
       ElemType data;
       int next;
}SLinkList[MaxSize];

Guess you like

Origin blog.csdn.net/qq_41941875/article/details/106147844