# Data structure and algorithm linear table

Posted by Bobulous on Sat, 05 Mar 2022 01:22:48 +0100

## Linear table

###### Definition of linear table:
• A finite sequence consisting of n(n ≥ 0) data elements (a1,a2,..., an).
• Record as: L=(a1,a2,..., an)
ai-1 is the direct precursor of ai, and ai+1 is the direct successor of ai
a1 - first element - it has no precursor
an -- tail element - it has no successor
• Table length: the number of elements in a linear table
• Empty table: a linear table without elements
###### Basic operation of linear table:
```  1.InitList(&L)            //Construct empty table L.
2.LengthList(L)          //Find the length of table L
3.GetElem(L,i,&e)        //Take the element ai and return ai from e
4.PriorElem(L,ce,&pre_e) //Find the precursor of ce by pre_e return
5.InsertElem(&L,i,e)     //Insert new element e before element ai
6.DeleteElem(&L,i)       //Delete the i th element
7.EmptyList(L)           //Judge whether L is an empty table
```
###### Selection and algorithm of linear table:
• Example 1: insert sequence table
Let there be length elements in L.elem[0... maxleng-1], insert a new element e before L.elem[i-1], (1 < = I < = length + 1)
1. Algorithm 1: point to the operated linear table with a pointer and allocate it statically
``` #define maxleng 100
typedef struct
{ ElemType elem[maxleng]；//Subscript: 0,1, maxleng-1
int length；            //Table length
} SqList；
SqList L；

int Insert1(SqList *L,int i,ElemType e)
{ if (i<1||i>L->length+1) return ERROR     //Illegal i value
if (L->length>=maxleng) return OVERFLOW  //overflow
for (j=L->length-1；j>=i-1；j--；)  //Move the following elements first (until the i-1 element is moved)
L->elem[j+1]=L->elem[j]； //Move element backward
L->elem[i-1]=e；              //Insert new element
L->length++；                 //Length variable increases by 1
return OK;                     //Insert successful
}
```

The process is shown in the figure: 1. Algorithm 2: use reference parameters to represent the operated linear table and static allocation
```//L is defined as above
Status Insert2(SqList &L,int i,ElemType e)  //L here is no longer a pointer
{ if (i<1||i>L.length+1) return ERROR     //Illegal i value
if (L.length>=maxleng) return OVERFLOW  //overflow
for (j=L.length-1；j>=i-1；j--；)
L.elem[j+1]=L.elem[j]；      //Move element backward
L.elem[i-1]=e；                  //Insert new element
L.length++；                     //Length variable increases by 1
return OK                        //Insert successful
}    //Summary: and change "* l" and "- >" to "& L" and "."
```
1. Algorithm 3: use reference parameters to represent the operated linear table and allocate dynamically
```#define LIST_INIT_SIZE 100 / / initial length
#10 / / increment
typedef struct
{ ElemType *elem；//Storage space base address
int length；    //Table length
int listsize;   //Currently allocated storage capacity
//(in sizeof(ElemType)
} SqList；
SqList L；

int Insert3(SqList &L,int i, ElemType e)
{int j;
if (i<1 || i>L.length+1)     //The legal value of i is 1 to n+1
return ERROR;
if (L.length>=L.listsize)    /*Expand on overflow*/
{
ElemType *newbase;
newbase=(ElemType *) realloc(L.elem,
(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if (newbase==NULL) return OVERFLOW;   //System space is full, expansion failed
L.elem=newbase; //Update linear table
L.listsize+=LISTINCREMENT; //Update current length
}
//Move the element backward to empty the component elem[i-1] of the ith element
for(j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j];
L.elem[i-1]=e;                   /*New element insertion*/
L.length++;                      /*Linear meter length plus 1*/
return OK; //Same as static allocation
}
```
• realloc function
• Usage: pointer name = (data type *) realloc (pointer name to change memory size, new size). Where - the new size can be large or small (if the new size is larger than the original memory size, the newly allocated part will not be initialized; if the new size is smaller than the original memory size, data loss may occur)
• Header file: #include < stdlib h> Some compilers require #include < malloc h> , at TC2 Alloc. Can be used in 0 H header file
• Return value: if the reallocation is successful, the pointer to the allocated memory is returned; otherwise, the NULL pointer is returned.
• Note: free is required when not in use

Evaluation of sequential structure:

(1) Is a random access structure. The time of accessing any element is a
Constant, fast speed;
(2) The structure is simple, and logically adjacent elements are also physically adjacent;
(3) Do not use pointers to save storage space.
(1) Inserting and deleting elements requires moving a large number of elements, which consumes a lot of time;
(2) A continuous storage space is required;
(3) "Overflow" may occur when inserting elements;
(4) The storage space in the free area cannot be occupied (shared) by other data.

### Chain storage structure of linear list  ```Definition of single linked list:
struct node  //typedef can also be used
{ ElemType data；     //data is an abstract element type
struct node *next； //next is the pointer type
}；
Pointer variable to node head,p,q explain:
head=malloc(sizeof(struct node)) //There can also be no forced type conversion in the front, and the equation will be automatically converted to the data type on the left
p1=malloc(sizeof(struct node))
tail->next=p1  //You can assign a value to the data field of p in combination with the scanf function
tail=p1
p2=malloc(sizeof(struct node))
tail->next=p2  //You can also write P1 - > next = P2 without tail
tail=p2
..........
tail->next=NULL;   //or pn=NULL
2.First in then out:( head Front (insert)
p=(struct node *)malloc(LENG)；//Generate new node
scanf("%d",&e)；
p->data=e；                   //Input data to send the data of the new node
p->next=head->next；     //The new node pointer points to the original first node
head->next=p；           //The pointer of the header node points to the new node
scanf("%d",&e)；          //Enter another number
}
```
###### Various basic operations:
```1.Insert:
f=(struct node *)malloc(LENG)； //generate
f->next=p->next；                //The new node points to the successor of p
p->next=f；                      //The new node becomes the successor of p
2.Delete:
q->next=p->next；
free(p)；
```
• The function based on basic operation has been realized
• Example: suppose there is an incrementally sorted linked list without header node, insert a new node to make it still increment.
• Algorithm 1: generate an incremental ordered single linked list without leading nodes: ① insert an empty table; ② Tail insertion; ③ Head insertion; ④ General insertion.
```struct node * creat3_1(struct node *head，int e)
{ q=NULL； p=head；                  //q. Insert pointer (P) to scan the position, not to
while (p && e>p->data)             //Not finished scanning, and e is greater than the current node
{ q=p； p=p->next；}              //q. P move back and check the next position
f=(struct node *)malloc(LENG)；    //Generate new node
if (p==NULL){
f->next=NULL;
if  (q==NULL)           //(1) Insert empty table
else  q->next=f;}       //(2) Insert as the last node
else  if (q==NULL)                  //(3) Insert as first node
else
{f->next=p； q->next=f；}   //(4) Generally, insert a new node
``` • Algorithm 2: generate an incremental ordered single linked list of leading nodes
```here q Can not be empty, omit the information about in algorithm 1 q of if sentence
p=head->next；         //q. P scan to find the insertion position
while (p && e>p->data) //Not finished scanning, and e is greater than the current node
{ q=p；
p=p->next；         //q. P move back and check the next position
}
f=(struct node *)malloc(LENG)； //Generate new node
f->next=p； q->next=f； //Insert new node
//(2) is also included here as the last node insertion, because the statement F - > next = P does not affect the result
}  It can be seen that the header node is wise! (generally, linked lists are owned by default)
```
• Algorithm 3: insert a new element at the specified position in the single linked list (specified position - no pq positioning)
There is no need to consider the first insertion, F - > next = P - > next; p->next=f； Can include all
```int insert( Linklist &L，int i, ElemType e)
{p=L；
j=1;
while (p && j<i)
{  p=p->next；   //p moves back to the next position
j++；}
if (i<1 || p==NULL)           //Insertion point error
return ERROR;
f->next=p->next； p->next=f； //Insert new node
return OK;
}
```
• Example: delete a node in the single linked list
• Algorithm 1: delete the node with element value e in the single linked list with header node (there can be multiple nodes)
```int Delete1(Linklist head, ElemType e)
{ struct node *q,*p;
int result=Yes；
while(p)
{
while(p&&p->data!=e) //Find the node with element e
{
q=p；                //Remember that you may want to delete the previous node p of the element
p=p->next；          //Find next node
}
if (p)                //There are nodes with element e
{
q->next=p->next；  //Delete this node
free(p)；          //Free up space occupied by nodes
p=q->next;	     //p points to the next node
result=Yes;
}
}
return result;
```
• Algorithm 2: delete the element at the specified position in the single linked list
```int Delete2( Linklist &L，int i,ElemType &e)
{p=L；
j=1;
while (p->next && j<i)     //p cannot be empty at the end of the loop
{  p=p->next；          //p moves back to the next position
j++；}
if (i<1 || p->next==NULL)     //Delete point error
return ERROR;
p->next=q->next；            //Extract from the linked list
e=q->data;                   //Retrieve data element value record
free(q)；                    //Free node space
return OK;
}
```

• When nodes are found, inserting and deleting elements is faster than sequential tables
• No pre allocated space is required, and the number of elements is not limited
• Finding the data elements of a node is slower than the sequential table

• And a linked list described by an array ```typedef struct  //Definition of static linked list
{
int data; //Data in static linked list nodes
int cur;   //Cursors in static linked list nodes
}component;
component a;
```

• In the insertion and deletion operations, only the cursor needs to be modified without moving elements, which improves the disadvantage that the insertion and deletion operations in the sequential storage structure need to move a large number of elements
• shortcoming
• The problem that it is difficult to determine the table length caused by continuous storage allocation (array) is not solved.
• Lost the random access characteristics of sequential storage structure.  3. Circular linked list with tail pointer only 4. Circular null table with tail pointer only • When using circular linked list, tail pointer is also advocated. It can save the time of finding the tail node in some operations (for example, the first part of two circular linked lists is connected), so as to reduce the time complexity.
• Some algorithms of circular linked list:
• Find the length of the circular single linked list with head as the head pointer, and output the values of nodes in turn.
```int length(struct node *head)
{ int leng=0；             //The initial value of the length variable is 0
struct node *p；
p=head->next；           //p points to the first node
{ printf("%d",p->data)；//output
leng++；              //count
p=p->next；}           //p move to the next node
return leng；            //Return length value
}
```

• It is further improved on the basis of single linked list. When traversing, it can start from any node, which increases the flexibility of traversal.
• It does not solve the problem of slow lookup of elements in single linked list

• Structure of bidirectional linked list 1. Non empty two-way linked list 2. Empty table  4. Empty table • Basic operation of circular linked list
```definition:
typedef struct Dnode
{ ElemType data；             //data is an abstract element type
struct Dnode *prior,*next； //Prior and next are pointer types
}*DLList                     //DLList is a pointer type

1.insert
f->prior=p->prior；  //The prior ity of node B points to node A
f->next=p；          //The next of node B points to node C
p->prior->next=f；   //The next of node A points to node B
p->prior=f；         //The prior ity of node C points to node B

2.delete
p->prior->next=p->next；  //The next of node A points to node C
p->next->prior=p->prior； //The prior ity of node C points to node A
free(p)；                 //Release the space occupied by node B
```

Insert: Delete: 