# Chapter II linear table

## 2.1 outline requirements

(1) Basic concepts of linear table

(2) Implementation of linear table

1. Sequential storage

2. Linked Storage

(3) Application of linear table

## 2.2 basic concept of linear table

Definition of linear table: a linear table is a finite sequence of elements with the same characteristics

The storage structure of linear list: sequential storage and chain storage, that is, sequential list and chain list,

definition of sequence table

definition of linked list

storage structure | logically | Physical address |
---|---|---|

Sequence table | adjacent | adjacent |

Linked list | adjacent | Not necessarily adjacent |

The Head pointer is used to completely identify the whole linked list

The empty judgment conditions of single linked list are: Single linked list with header node: Head->next = NULL Single linked list without head node: Head = NULL

Double linked list

The difference from the single linked list is that a pointer to the precursor is added to each node.

The empty judgment condition is the same as that of the single linked list.

Circular single linked list

The empty judgment conditions of circular single linked list are: Circular single linked list with header node: Head->next = Head Circular single linked list without leading node: Head = NULL

Circular double linked list:

The empty judgment conditions of circular double linked list are: Header node: Head->next=Head or Head->prior=NULL Circular single linked list without leading node: Head = NULL

Exercise 1:

#include<iostream> #include<cmath> using namespace std; #define MIN 0.001 #define MAXSIZE 100 int compare(float A[],int alen,float B[],int blen) { int i = 0; while(i < alen && i < blen) { if (fabs(A[i]-B[i])<MIN) ++i; else break; } if(i >= alen && i >= blen) return 0; else if((i>=alen&&i<blen) || A[i]<B[i]) return -1; else return 1; } int main() { float A[MAXSIZE] = {1,2,3,4}; float B[MAXSIZE] = {1,2,3,4,5,6}; cout <<compare(A,4,B,6); return 0; }

## 2.3 comparison of storage structure characteristics

### 2.3.1 insert delete element

#### 2.3.1.1 sequence table insertion

When a position is selected, all elements move one position to the right from the back to the front. From front to back will result in element coverage.

#### 2.3.1.2 deletion of sequence table

When the position is selected, all elements from the front to the back move one position to the left in turn. From back to front will result in element coverage.

#### 2.3.1.3 conclusion

The insertion and deletion of sequential list may lead to the joint operation of a large number of elements, while the linked list will not.

### 2.3.2 element extraction

Finding the location of any node in a single linked list is not as simple as a sequential list, because the sequential list supports random storage, while the linked list does not.

### 2.3.3 storage space

Linear table adopts sequential storage structure, which must occupy a whole piece of continuous storage space, while chain storage structure does not need this;

From the overall point of view of the table, the storage space utilization of the general sequential table is lower than that of the linked list, but from the perspective of a single storage unit, the utilization of the sequential table is higher than that of the linked list.

Storage density refers to the ratio of the storage occupied by the node itself to the storage occupied by the whole storage structure.

Exercise 2:

Select A because the sequence table supports random storage

Select B, exclusion method

## 2.4 calculation of element movement times and static linked list

### 2.4.1 calculation of element movement times

It is mainly used to insert and delete elements in the sequence table.

The insertion position of a sequence table with length n is n+1, so the probability of inserting elements at any position is:
1
n
+
1
\frac{1}{n+1}
n+11；

Insert elements before position i, and n-1 elements need to be moved;

So the average number of moves of the inserted element is
n
2
\frac{n}{2}
2n；

The insertion position of a sequence table with length n is n+1, so the probability of deleting elements at any position is:
1
n
\frac{1}{n}
n1；

Insert elements before I position, and n-i-1 elements need to be moved;

So the average number of moves of the inserted element is
n
−
1
2
\frac{n-1}{2}
2n−1；

### 2.4.2 static linked list

Static linked list node type definition:

typedef struct { int data; int next; }SLNode;

Construct a static linked list with length MAXSIZE:

SLNode SLink[MAXSIZE];

int p = Ad0; //Define a pointer SLink[p].data;//Take the node value pointed to by P, which is equivalent to p - > data SLink[p].next;//Take the subsequent node pointer of P, which is equivalent to p - > next stay p Insert node after q: SLink[q].next = SLink[p].next; Slink[p].next = q; //Analogy q.next = p.next p.next = q

Exercise 3:

Choose B

A. Both are O(1)

C. Linked lists with the same number of nodes occupy the same storage space

Choose C

A. It's not simple

B. Random storage is not supported

D. Can't make good use of scattered storage space

## 2.5 linear table insertion and deletion

### 2.5.1 inserting and deleting elements in single linked list

#### 2.5.1.1 insertion

Implementation code:

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

#### 2.5.1.2 delete

Implementation code:

p->next = s->next; free(s);

### 2.5.2 double linked list insert delete element

#### 2.5.2.1 insertion

Implementation code:

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

#### 2.5.2.2 deletion

Implementation code:

s->prior->next = s->next s->next->prior = s->prior free(s);

### 2.5.3 insertion and deletion of sequence table elements

#### 2.5.3.1 insert elements

Position of insertable element: 0-length;

When length=maxsize, no more elements can be inserted;

Move elements from front to back.

Insert operation implementation code:

int sqList[maxsize] = {1,2,3,4,...n}; int length = n; int InsertElem(int sqList[],int &length,int p,int e) { if(p<0||p>length||length==maxsize) return 0; for(int i = length-1;i>=p;--i) { sqList[i+1]=sqList[i]; } sqList[p]=e; ++length; return 1; }

#### 2.5.3.2 delete element

Position of insertable element: 0-length-1;

When length=0, no more elements can be inserted;

Move elements from back to front.

Delete operation implementation code:

int sqList[maxsize] = {1,2,3,4,...n}; int length = n; int DeleteElem(int sqList[],int &length,int p,int e) { if(p<0||p>length-1) return 0; e = sqList[p]; for(int i = p;i<length-1;++i) { sqList[i]=sqList[i+1]; } --length; return 1; }

Exercise 4:

Select B. the longer the linked list, the more data to scan

void DeleteElem(int sqList[],int &length,int p,int e) { int len = j-i+1; for(int k = j+1;k<length;++i) { sqList[k-len]=sqList[k]; } length-=len; }

void del(LNode *L) { LNode *p = L-next,*q; while(p->next !=NULL) { if(p->data==p->next-data) { q = p->next; p->next = q->next; free(q); } else { p = p->next; } } }

void spilit(LNode *A,LNode *B) { B = (LNode*)molloc(sizeof(LNode)); LNode *p,*q,*r; B->next = NULL; r = B; p = A; while(p->next!=NULL) { if(p->next->data%2==0) { q = p->next; p->next= q->next; q->next =NULL; r->next =q; r = q; } else { p = p->next; } } }

## 2.6 table building

### 2.6.1 construction of sequence table

Implementation code:

### 2.6.2 linked list creation

Implementation code (tail interpolation):

Implementation code (header insertion):

Exercise 5:

## 2.7 inverse problem

### 2.7.1 reverse setting of sequence table

Main implementation code:

for(int i = left,int j = right;i<j;++i,--j) { temp = a[i]; a[i] = a[j]; a[j] = temp; }

### 2.7.2 reverse linked list

Main implementation code:

t = p->next; p->next = t->next; t->next = q->next; q->next = t; if(p->next ==q) end;

Exercise 6:

1. Algorithm idea: first reverse the first P elements in R, then reverse the remaining elements, and finally reverse the whole R.

2.void reverse(int a[],int left,int right,int p) { for(int i = left,int j = right;i<left+p&&i<j;++i,--j) { temp = a[i]; a[i] = a[j]; a[j] = temp; } } void solve(int a[],int n,int p) { reverse(a,0,p-1,p); reverse(a,p,n-1,n-p); reverse(a,0,n-1,n); }

3. Time complexity: O(n);

Spatial complexity: O(1);

In situ algorithm: the auxiliary space is a constant algorithm relative to the amount of input data

## 2.8 take the maximum value

### 2.8.1 maximum value of sequence table

Main implementation code:

The minimum value can be changed to the details;

### 2.8.2 maximum value of linked list

Main implementation code:

LNode *p,*q; int max = head->next->data; q = p = head->next; while(p!=NULL) { if(max < p->data) { max = p->data; q = p; } p = p->next; }

Exercise 7:

Implementation code: void maxFirst(DLNode *head) { ## get max DLNode *p = head->rlink,*q = p; int max = p->data; while(p!=NULL) { if(max<p->data) { max = p->data; q = p; } p = p->rlink; } ---------------------------------------- ##delete DLNode *l = q->llink,*r = q->rlink; l->rlink = r; if(r!=NULL) r->llink = l; ---------------------------------------- ##insert q->llink = head; q->rlink = head->rlink; head->rlink = q; q->rlink->llink = q; }

1. Basic idea of algorithm:

(1) Calculate the length of the two linked lists, len1 and len2;

(2) Make the pointers p and q point to the head node of str1 and str2 respectively. If M > = n, make p point to the m-n+1 node in the linked list; If M < n, make q point to the n-m+1 node in the linked list; Even if the length from the node to the end of the table indicated by pointers p and q is equal.

(3) Move the pointers p and q backward synchronously and judge whether they point to the same node. If p and q point to the same node, the point is the starting position of the common suffix.

2.LNode *solve(LNode *str1,LNode *str2) { int len1 = 0,len2 = 0; LNode *p = str1->next,*q = str2->next; while(p!=NULL) { len1++; p = p->next; } while(q!=NULL) { len2++; q = q->next; } for(p = str1->next;len1>len2;len1--) p = p->next; for(q = str2->next;len1<len2;len2--) q = q->next; while(p!=NULL&&p!=q) { p = p->next; q = q->next; } return p; }

3. The time complexity is O(n)

## 2.9 Division

Give a sequence table with the first element as the pivot so that the elements on the left are smaller than the pivot and the elements on the right are larger than the pivot

Thought:

First, define a temp constant, assign the pivot to temp, and then define the positions i, J, i < J at both ends of the array. Move J scan to the left. If the number is smaller than the pivot, move it to i position, and then move i to the right. If an element larger than the pivot is found, move it to j position

Implementation code:

void partition(int arr[],int n) { int temp; int i = 0,j = n-1; temp = arr[i]; while(i<j) { while(i<j&&arr[j]>=temp) --j; if(i<j) { arr[i] = arr[j] ++i； } while(i<j&&arr[i]<temp) ++i; if(i<j) { arr[j] = arr[i] --j; } } arr[i] = temp; }

The effect is to divide the array elements into two parts with Y as the boundary. The first half is less than Y and the second half is greater than or equal to Y;

i and j end up pointing to X, not Y.

Exercise 8:

There is a linear table, which is stored by the single linked table L of the leading node. Design an algorithm to reverse it. It is required that no new nodes can be created, but only through the re combination of existing nodes in the table.

Implementation code:

LNode *p = head->next,*q; L->next = NULL; while(p!=NULL) { q = p->next; p->next = L->next; L->next = p; p = q; }

Write a function to print the data in the single linked list in reverse order, assuming that the pointer L points to the start node of the single linked list

Implementation code:

void reprint (LNode *L) { if(L!=NULL) { reprint(L->next); cout<<L->data<<" "; } }

## 2.10 consolidation

### 2.10.1 merging of sequence tables

Implementation code:

void mergearray(int a[],int m,int b[],int n,int c[]) { int i,j = 0; int k = 0; while(i < m&&j<n) { if(a[i]<b[j]) c[k++] = a[i++]; else c[k++] = b[j++]; } while(i<m) c[k++] = a[i++]; while(j<n) c[k++] = b[j++]; }

### 2.10.2 list merging

Implementation code (tail interpolation):

void merge(LNode *A,LNode *B,LNode *&C) { LNode *p = A->next; LNode *q = B->next; LNode *r; C = A; C->next = NULL; free(B); r = C; while(p!= NULL&&q!=NULL) { if(p->data<=q->data) r->next = p; p = p->next; r = r->next; else r->next = q; q = q->next; r = r->next; } if(p!=NULL) r->next = p; if(q!=NULL) r->next = q; }

Implementation code (header insertion): merge in reverse order

void mergeR(LNode *A,LNode *B,LNode *&C) { LNode *p = A->next; LNode *q = B->next; LNode *s; C = A; C->next = NULL; free(B); while(p!= NULL&&q!=NULL) { if(p->data<=q->data) s = p;p = p->next; s->next = C->next; C->next = s; else s = q;q = q->next; s->next = C->next; C->next = s; } while(p!=NULL) s = q;q = q->next; s->next = C->next; C->next = s; while(q!=NULL) s = q;q = q->next; s->next = C->next; C->next = s; }