# Analysis of data structure chain table C/C++

## What is a linked list

```Linked list, as the name implies, is a kind of linear storage structure, which uses "chain" to connect data in series, but unlike the sequential list, the connected data does not need to be a continuous physical address, but uses a pointer to connect.
For example, using linked list to store {1,2,3}, the physical storage state of data is shown in the following figure: data elements are stored randomly, and the storage structure that indicates the logical relationship between data through pointers is linked storage structure.
```

It is convenient to add and delete, only the pointer domain of the adjacent nodes needs to be considered, without moving data, and the time complexity is O (1).
The efficiency of random search is low. It needs to traverse nodes one by one according to the pointer. The time complexity is O (n).
It consumes a lot of space, because each node needs to store not only the data itself, but also the pointer field, which is used to store the addresses of the nodes before and after.

The common types of linked list are mainly divided into single linked list, two-way linked list and circular linked list. The basic operation and implementation of single / double linked list are recorded below.

## 1, Single chain table

Single chain table, that is, each node contains only one subsequent pointer;

The head node and the tail node of the single chain table are special. The head node is used to record the base address of the chain table, which is the starting point of the chain table traversal. The subsequent pointer of the tail node does not point to any node, but points to a NULL address.

The time complexity of insertion and deletion is O(1), and the time complexity of random lookup is O(n).

## Complete code

```#include<iostream>
#include<stdlib.h>
using namespace std;

typedef struct Node
{
int data;//Data domain
struct Node *next;//Pointer domain
}LNode;

LNode* nodeInit(int n)//n represents the number of nodes other than the head node
{
//Create the head pointer. Don't forget to point to NULL to avoid wild pointer
//Create the header node and keep the temp pointer pointing to the current node
LNode *temp=(LNode*)malloc(sizeof(LNode));
//If you need to assign a value to the head node, you can use head - > data = XXX;

for(int i=0;i<n;i++)//Apply for nodes other than header nodes
{
LNode *node=(LNode*)malloc(sizeof(LNode));

if(node)//
{
cin>>node->data;//Input data field
node->next=NULL;//Keep the pointer field of the created node pointing to NULL

/*****Establishing the relationship between the new node and its predecessor******/
temp->next=node;//1. Give the first address of the new node to the pointer field of its predecessor node
temp=temp->next;//2. Point the temporary pointer to the next node (successor node)
}
else
{
cout<<"Memory request failed";
}
}

return head;//The return head pointer is convenient for subsequent operation, and plays an index role in the linked list
}

{
LNode *temp = head;//Assign the head pointer to the temp pointer first
//First find the last node to insert
for (int i = 1; i < add; i++)//Here the insertion position refers to the number, not the index value, so i counts from 1
{
temp = temp->next;
if (temp == NULL) {
cout<<"Invalid insertion position"<<endl;
}
}
//Create insertion node c
LNode *insert = (LNode*)malloc(sizeof(LNode));
insert->data = elem;
insert->next = temp->next;//The order cannot be wrong. First, update the pointer field of the inserted node, that is, temp - > next
temp->next = insert;//Then update the pointer field of the precursor node
}

{
//Traverse to the previous node of the deleted node
for (int i = 1; i < add; i++)
{
temp = temp->next;
if (temp->next == NULL)
{
cout<<"No such node"<<endl;
}
}
LNode *del = temp->next;//Set a separate pointer to the deleted node to prevent loss
temp->next = temp->next->next;//The way to delete a node is to change the pointer field of the previous node
free(del);//Release the node manually to prevent memory leakage
}

void display(LNode *p) //Just pass in the chain header pointer
{
LNode *temp =p;//Point the temp pointer back to the head node
//The output statement is executed as long as the next of the node to which the temp pointer points is not Null.
while (temp->next)
{
temp = temp->next;
cout<<temp->data;
}
cout<<endl;
}

//p is the original list, and elem represents the searched element
int selectElem(LNode * p,int elem){
//Create a new pointer t and initialize it as the head pointer p
LNode *temp=p;
int i=1;

while (temp->next) {
temp=temp->next;
if (temp->data==elem)
{
}
i++;
}
//When the program is executed here, it means that the search fails
return -1;
}

//Update function, where add represents the position of the change node in the linked list, and newElem is the value of the new data field
LNode *amendElem(LNode * p,int add,int newElem){
LNode * temp=p;
temp=temp->next;//Before traversal, temp points to the primary node
//Traverse to the node to be updated
for (int i=1; i<add; i++) {
temp=temp->next;
}
temp->data=newElem;
return p;
}

int main()
{
LNode *p = NULL;
p=nodeInit(5);
cout<<"The original list is:"<<endl;
display(p);//Output original list

cout<<"Insert element 5 at position 4"<<endl;
p = insertElem(p, 5, 4);
display(p);

cout<<"Delete element 3"<<endl;
p = delElem(p, 3);
display(p);

cout<<"Find element 2 at"<<endl;
printf("There is no such element");
}
else
{
cout<<"The location of element 2 is:"<<address<<endl;
}

cout<<"Change the data on position 3 to 7"<<endl;
p = amendElem(p, 3, 7);
display(p);

return 0;
}
```

## -----------------

Each node in a two-way linked list has two direction pointers,
• subsequent pointer: points to the subsequent node,
• precursor pointer: the node pointing to the precursor.
There are also two special nodes in the two-way linked list. The precursor pointer of the first node and the successor pointer of the tail node point to NULL address.

## Definition of double linked list

Compared with the single linked list, each node of the two-way linked list has an additional pointer field for pointing to the direct precursor. Therefore, we can create double linked list on the basis of single linked list.

It should be noted that in the process of creating a double linked list, different from a single linked list, each new node must establish two connections with its predecessor nodes, namely:

• point the prior pointer of the new node to the direct predecessor node: node - > prior = temp;
• point the next pointer of the direct precursor node to the new node: temp - > next = node;

## Complete code

```#include<iostream>
#include<stdlib.h>
using namespace std;

typedef struct Node
{
struct Node *prior;//Precursor pointer
int data;//Data domain
struct Node *next;//Successor pointer
}LNode;

LNode* nodeInit(int n)//n represents the number of nodes other than the head node
{
//Create the head pointer. Don't forget to point to NULL to avoid wild pointer
//Create the header node and keep the temp pointer pointing to the current node
LNode *temp=(LNode*)malloc(sizeof(LNode));

//If you need to assign a value to the head node, you can use head - > data = XXX;

for(int i=0;i<n;i++)//Apply for nodes other than header nodes
{
LNode *node=(LNode*)malloc(sizeof(LNode));

if(node)
{
cin>>node->data;//Input data field
node->next=NULL;//Keep the pointer field of the created node pointing to NULL

/*****Establishing the relationship between the new node and its predecessor******/
node->prior=temp;//The prior of the new node is the first address of the previous node, temp
temp->next=node;//1. Give the first address of the new node to the pointer field of its predecessor node
temp=temp->next;//2. Point the temporary pointer to the next node (successor node)
}
else
{
cout<<"Memory request failed";
}
}

return head;//The return head pointer is convenient for subsequent operation, and plays an index role in the linked list
}

{
int len = 0;
while(temp->next)
{
temp = temp->next;
len++;
}
return len;
}

{
LNode *temp = head;//Assign the head pointer to the temp pointer first
//First find the last node to insert
//To find this node, you need to point the pointer of temp to the first node of the header node, temp = temp - > next;
for (int i = 1; i < add; i++)//Here, the insertion position refers to the number, not the index value, so i counts from 1, and temp points to the previous node of the position to be inserted
{
temp = temp->next;
if (temp == NULL) {
cout<<"Invalid insertion position"<<endl;
}
}
//Create insertion node c
LNode *insert = (LNode*)malloc(sizeof(LNode));
insert->data = elem;
insert->next = temp->next;//The order cannot be wrong. First, update the pointer field of the inserted node, that is, temp - > next
insert->prior=temp;//The precursor pointer points to the previous node
temp->next = insert;//Then update the pointer field of the precursor node
}

//Add (insert) node at the end
{
LNode *node=(LNode*)malloc(sizeof(LNode));//Create a tail node

while(temp->next)//Traverse to tail node
{
temp=temp->next;
}

node->next=NULL;
node->prior=temp;
node->data=elem;
temp->next=node;

}

//Delete Vertex
{
//Traverse to the previous node of the deleted node
for (int i = 1; i < add; i++)//Use traversal to find the previous node of the node (excluding the header node)
{
temp = temp->next;
if (temp->next == NULL)
{
cout<<"No such node"<<endl;
}
}

{
cout<<"The list after deleting the tail node is:";
LNode *del = temp->next;//Set a separate pointer to the deleted node to prevent loss
temp->next=NULL;

free(del);//Release the node manually to prevent memory leakage
}
else//If the deleted node is a general node
{
LNode *del = temp->next;//Set a separate pointer to the deleted node to prevent loss
temp->next = temp->next->next;//The way to delete a node is to change the pointer field of the previous node
temp->next->prior=temp;
free(del);//Release the node manually to prevent memory leakage
}

}

//Modify node data
LNode *editElem(LNode *head, int n, int newdata)
{
temp=temp->next;//Temp first points to the first node except the header node. If you delete this statement, temp will point to the header node at the beginning

for (int i = 1; i < n; i++)//Use traversal to find the node. At this time, temp points to the node
{
temp = temp->next;
if (temp->next == NULL)
{
cout<<"No such node"<<endl;
}
}
temp->data=newdata;

}

//Get the node at the specified location. If you get the location of the specified element, add if judgment to return n during traversal
{
for (int i = 1; i <= n; i++)//Another method of traversal, which you can handle flexibly according to your preference
{
temp = temp->next;
//If (Temp - > data = = XXX, return n) plus this statement can be modified to return the location of the specified element
if (temp->next == NULL)
{
cout<<"No such node"<<endl;
return 0;
}
}

return temp->data;
//Return temp - > prior - > data; you can obtain the data of the precursor node of the node and the advantages of the two-way linked list
}

{
LNode *temp=head;//temp pointer is not necessary, just habit
LNode *current=temp->next;
LNode *pre=NULL;
LNode *pnext=NULL;
while(current)
{
//Set the pointer separately to keep the successor node,
//You cannot use current=current->next because you need to point it to the pre precursor below
pnext = current -> next;
//New follow-up to the precursor to reverse
current -> next = pre;
current->prior=pnext;

//Move the current node back
pre = current;
current = pnext;
}
current->next=pre;
current->prior=NULL;//NULL initialization of head node precursor pointer
return current;
}

{
//Execute the output statement as long as the next of the node to which the temp pointer points is not Null
while (temp->next)
{
temp = temp->next;
cout<<temp->data;
}
cout<<endl;
}

int main()
{
LNode *p = NULL;
p=nodeInit(5);
cout<<"The original list is:";
display(p);//Output original list
cout<<"The length of the list is: "<<getlength(p)<<endl;

//Non tail insertion node
cout<<"Insert 8 in the first position:";
p=insertElem(p,8,1);
display(p);

p=Reverse(p);
cout<<"After the list is reversed, it is: ";
display(p);

//Tail insertion node
cout<<"Insert 0 at the end:";
p=insertEnd(p,0);
display(p);

//Delete node (including tail)
p=delElem(p,7);
display(p);

//Modify node data
cout<<"Modify the data of node 1 to 5:";
p=editElem(p,1,5);
display(p);

//Get node data
cout<<"Obtain the data of the third node as follows:"<<getElem(p,3)<<endl;

return 0;
}
```