Review of data structure -- Chapter 2 linear table

Posted by sbinkerd1 on Mon, 10 Jan 2022 19:18:42 +0100

Linear table code

1, Sequence table

1. Static definition

Static allocation of memory space, defined by one-dimensional array, the array size and space have been fixed in advance. Once the space is full, the insertion of new data will overflow, resulting in program crash.

#define MaxSize 50 / / define the maximum length of a linear table
typedef struct{
ElementType data[MaxSize];//Elements of the sequence table
int length;//Current length of sequence table
}SqList;//Type definition of sequence table

2. Dynamic definition

During dynamic allocation, the space of the storage array is allocated through the dynamic message allocation statement during the program execution. Once the space is occupied, a larger storage space will be opened up to replace the original storage space and achieve the purpose of expanding the array space.

#define InitSize 50 / / initial definition of table length
typedef struct{
ElementType *data;//Pointer indicating dynamically allocated array
int MaxSize,length;//Maximum capacity and current number of arrays
}SeqList;//Type definition of dynamic allocation array order table

3. Initial dynamic allocation of malloc function

C language

L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);//C language

C++

L.data=new ElemType[InitSize];//C++

2, Basic operation of sequence table

1. Insert operation

Insert the new element e at the ith position of the sequence table L

bool ListInsert(SqList &L，int i,ElemType e){//The & sign here indicates that you want to bring the value back
if(i<1||i>L.length+1)
return false;
//Judge whether the range of i is valid. At this time, i represents the array subscript. The array subscript starts from 0, so the value range of i is 0 to length+1
for(int j=L.length;j>=i;j--)//Move the element after the i th element back
L.data[j]=L.data[j-1];
L.data[i-1]=e;//Place the new element e at position i
L.length++;//Linear table length plus one
return true；
}

Note: distinguish the bit order of the order table (starting from 1) and the array subscript (starting from 0)
The range of bit order is 1 to length
The array subscript range is 0 to length+1

2. Delete

Delete the element at the ith position in the sequence table L, return it with the reference variable, assign the deleted element to the reference variable e, and move the i + 1st element and all subsequent elements forward one element at a time

bool ListDelete(SqList &L,int i,ElemType &e){//e here is also a reference type. Return the value of e
if(i<1||i>L.length+1)
return false;
//Judge whether the range of i is valid. At this time, i represents the array subscript. The array subscript starts from 0, so the value range of i is 0 to length+1
e=L.data[i-1];//Assign the deleted element to the variable e
for(int j=i;j<L.length;j++)//Move the element after position i forward
L.data[j-1]=L.data[j];
return true;
}

3. Search by value (search in order)

Find the element whose first element value is equal to e in the sequence table L and return its bit order

int LocateElem(SqList L,ElemType e){
int i;
for(i=0;i<L.length;i++)
if(L.data[i]==e)
return i+1;//i starts from 0, the element value with subscript i is equal to e, and its bit order i+1 is returned
return 0;//Exit the loop, search failed
}

4. Related issues

(1) Sequential table random access by sequence number
Note: access mode refers to read-write mode. Sequence table is a storage structure that supports random access. Any element can be accessed easily according to the starting address and element serial number
(2) If the most common operation of a linear table is to access any element with a specified sequence number, a linear table is used
(3) The storage space occupied by a sequential table is independent of the storage order of elements

Node type description:

typedef struct LNode{
ElemType data;//Data domain
struct LNode *next;//Pointer field

(1) A single linked list is usually identified by the head pointer, such as the single linked list L. when the head pointer is NULL, it represents an empty table. A node is attached before the first node of the single linked list, which is called the head node. The pointer field of the head node points to the first element node of the linear table.
(2) Whether there is a head node or not, the head pointer always points to the first node in the linked list, and the head node is the first node in the linked list of the leading node, and information is usually not stored in the node.
(3) The purpose of adding header node is to facilitate the implementation of operation.

Build table

Table building by head inserting method

Starting from an empty table, a new node is generated, the read data is stored in the data field (data) of the new node, and then the new node is inserted into the header of the current table, that is, the new node is continuously inserted into the head node to create a table. It can be seen that the order of the read data is opposite to the order of the elements in the generated linked list. The insertion time of each node is O(1). If the length of the single linked list is n, the total time complexity is O(n)

LNode *s;//Always pointer to new node
int x;//Insert element type
//2. Initialize to an empty linked list
L->next = NULL;
//3. Enter element value
while(x != 9999){//Enter 9999 to end the input
//4. Create a new node
s=(LNode*)malloc(sizeof(LNode));
s->data = x;//Store the input element value into the data field
s->next = L->next;//L is the header pointer
L->next = s;
}
return L;
}
Tail interpolation table

Similarly, insert a new node into the tail of the current table, that is, insert a new node after the tail node to create a table.

LinkList CreateListTail(LinkList &L){//For single linked table L, elements are inserted after the end node of the table every time
int x;//Insert element type
//1. Create tail node
//2. Create header pointer and footer pointer, and point the footer pointer to the new node
LNode *s,*r = L;
//3. Enter element value
while(x!=9999){//Enter 9999 to end the input
//4. Create a new node
s=(LNode*)malloc(sizeof(LNode));
//5. Insert the new node into the footer
s->data = x;
r->next = s;
r = s;//r points to the new footer node
}
//6. The tail node pointer is set to null
r->next = NULL;
return L;
}

Find node value by sequence number

Starting from the first node of the single linked list, look down the next field one by one until the i-th one is found. Otherwise, the pointer field of the last node is returned as NULL

LNode *GetElem(LinkList L,int i){//i is the number of nodes
int j = 1;
LNode *p = L->next;//The head node pointer is assigned to p
if(i==0)//If i is 0, the header node is returned
return L;
if(i<1)//If i position is illegal, return null
return NULL;
while(p&&j<i){//Traverse from the first node to find the i-th node
p = p->next;//The head node pointer traverses backward in turn
j++;//Serial number plus one
}
return p;//Returns the pointer of the ith node; If i is greater than the table length, then p=null, just return P directly
}

Lookup table node by value

Starting from the first node of the single linked list, compare the values of the node data field in the table from front to back. If the value of a node data field is equal to the given value e, return the pointer of the node; If the entire single linked list does not have such a node, NULL is returned

//Take the node pointer with the data field equal to e in the single linked list L of the leading node. If there is no such node, NULL is returned
LNode *p = L->next;//Assign the head node to p
while(p!=NULL&&p->next!=e){//Start from the first node to find the node whose data field is equal to e
p = p->next;//Find backward in turn
}
return p;//The pointer node is returned after it is found, otherwise NULL is returned
}

Insert Knot

Insert the new node with the value of x into the ith position of the single linked list. First check whether the insertion position is legal, then find the precursor node of the position to be inserted, that is, the i-1 node, and then insert a new node. //Forward insertion
//1. Find the precursor position of the inserted node
p = GetElem(L,i-1);
//2. Insert node s after node p
s->next = p->next;
p->next = s;

Post insert: in the single linked list insert, the post insert operation is usually used to convert the pre insert into post insert: that is, after the pre insert operation, the data fields of p and s are exchanged, which is equivalent to inserting data after the data stored at the p node

//Same as the forward interpolation operation
s->next = p->next;
p->next = s;
//Re exchange data field
temp = p->data;
p-data = s->data;
s->data = temp;

Delete Vertex

To delete the ith node of the single linked list, first check whether the deletion position is legal, then find the precursor node to be inserted, that is, the i-1 node, and then delete it. //Delete the next node after a given node * q
p = GetElem(L,i-1);//Find and delete the precursor node of the node
q = p->next;//Let q point to the deleted node
//Disconnect the * q node from the chain
p->next = q->next;
//Release q node
free(q);

Delete the given node: find its precursor node from the head node of the linked list header, and then delete it. You can also delete its successor node. Similar to the previous backward insertion, assign the value of the successor node to the p to be deleted, and then delete the successor node //Delete the given node * p
//Let q point to the successor node of * p
q = p->next;
//Exchange data fields with subsequent nodes
p->data = p->next->data;
//Disconnect the q node from the chain
p->next = q->next;
//Release q node
free(q);

Because the single linked list node has only one pointer that only wants its successor, yes, the single linked list can only traverse backward from the first node in turn. If you want to access the precursor node of a node, you can only traverse from the beginning. Therefore, the time complexity of accessing subsequent nodes is O(1), and the time complexity of accessing precursor nodes is O (n).

In order to more conveniently access the predecessor node and successor node of a node, a double linked list is introduced. The double linked list has two pointers, prior and next, which point to the predecessor node and successor node of the node respectively.

typedef struct DNode{//Define double linked list node type
ElemType data;//Data domain
struct DNode *prior,*next;//Predecessor and successor pointers

Insert node * q after the node indicated by p //Insert * q node after * p
q->next = p->next;//1
p->next->prior = q;//2
q->prior = p;//3
p->next = q;//4
//Step 1.2 must be before step 4, otherwise * p subsequent node pointers will be lost

Insert node q before the node indicated by p Insert q before * p

p->proir->next=q;//1
q->next=p;//2
q->proir=p->prior;//3
p->prior=q;//4

Delete the successor node q of the double linked list p //Delete the successor node * q of * p
p->next = q->next;
q->next->prior = p;
free(q);

The difference between circular single linked list and single linked list is that the pointer of the last node is not NULL, but points to the head node (the next field of the tail pointer * r points to L), so there is no node with NULL pointer field in the table.

Therefore, the condition to judge whether the circular single linked list is empty is to see whether the pointer of the head node is equal to the head pointer, not whether the head pointer is empty. The circular single linked list exits the circular single linked list, adding that the pointer of the head node, the prior pointer, also points to the tail node

If node * p is the tail node, p - > next = = L;
When the circular double linked list is empty, the prior ity and next fields of its head node are equal to L  Static linked list describes the linked storage structure of linear list with the help of array. The nodes include data field and pointer field next.

Different from the pointer in the linked list mentioned earlier, the pointer here is the relative address of the node (array subscript, indicating the subscript of the next element in the array, referred to as cursor)

Like the sequential list, the static linked list also needs to allocate a continuous memory space (larger space) in advance

Static linked list structure type definition:

#define MaxSize 50 / / maximum length of static linked list
typedef struct{
ElemType data;//Store data elements
int next;//Array subscript of the next element