Data structure linear list super detailed sorting (access, insert, delete / sequential storage structure / linked storage structure / static linked list) | data structure and algorithm

Posted by freeloader on Tue, 26 Oct 2021 08:32:08 +0200

3.1 definition of linear table

Definition: a finite sequence of zero or more data elements

  • The first element has no predecessor and the last element has no successor

  • The number of linear table elements n (n > = 0) is defined as the length of the linear table. When n=0, it is an empty table

  • Permutations must be of the same data type

  • In a more complex linear table, a data element can be composed of several data items

  • The relationship between elements is one-to-one

3.2 abstract data type of linear table

ADT Linear table(List)
Data The type of each element is DataType
Operation
    InitList(*L):Initialization operation to create an empty linear table
	ListEmpty(L):If the linear table is empty, return true´╝îOtherwise return false
    CleanList(*L):Empty linear table
    GetElem(L,i,*e):The second in the linear table i A location element value is returned to e
    LocateElem(L,e):Look up the given value in the linear table e Equal elements. If the search is successful, the sequence number of the element in the table is returned, indicating success. Otherwise, it returns 0 and fails
    ListInsert(*L,i,e):In linear table L Section in i Insert new element at e
    ListDelete(*L,i,*e):Delete linear table L pass the civil examinations i A location element and e Returns its value
    ListLength(L):Return linear table L Number of elements
end ADT

3.3 sequential storage structure of linear table

Definition: the data elements of a linear table are sequentially stored in a storage unit with continuous addresses

Data elements emphasize the same data type

3.3.2 sequential storage mode

It can be implemented with a one-dimensional array

why?cuz the type of each data element in a linear table is the same

//Sequentially stored structure code
#define MAXSIZE 20 / / initial allocation of storage space
typedef int ElemType; //The type depends on the specific situation
typedef struct{
    ElemType data[MAXSIZE]; //Array storage element, Max MAXSIZE
    int length; //Current length of linear table
}SqList;

Difference between array length and linear table length

  1. The length of the array is the length of the storage space where the linear table is stored
  2. The length of the linear table is the number of data elements in the linear table. It is dynamically allocated according to insertion and deletion
  3. At any time, the length of the linear table < = the length of the array

The access time performance is O(1). Generally, such a specific storage structure is called a random access structure

3.3.3 insertion and deletion of sequential storage structure

  • Get element operation
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;/*Status Is a function type whose value is the status code of the function result, such as OK*/
				 /*Status Is an integer and returns 1 or 0*/
				 /*Initial condition: sequential linear table l already exists, 1 < = I < = listlength (L)*/
				 /*Operation results; Use e to return the value of the ith data element in L*/
Status GetElem(Sqlist L,int i,ElemType *e)
{
    if(L.length == 0|| i < 1 || i>L.length)
        return ERROR;
    *e = L.data[i-1];
    	return OK;
}

  • Insert element operation

    Algorithm idea:

    * if the insertion position is unreasonable, an exception is thrown

    * if the length of the linear table is greater than the length of the array, throw an exception or dynamically increase the capacity

    * traverse forward from the last element to the ith position, and move them back one position respectively

    * insert element into position i

    * gauge length + 1

/*Initial condition: sequential linear table l already exists, 1 < = I < listlength (L)*/
/*Operation result: insert a new element before the ith position in L, table length + 1*/
Status ListInsert(Sqlist *L,int i,ElemType e)
{
    int k;
    if(L->length==MAXSIZE)
        return ERROR; /*The sequential linear table is full*/
    if(i < 1 || i > L->length+1)
        return ERROR;/*Improper insertion position*/
    if(i <= L->length)
    {
        for(k = L->length-1;k < i-1;k--)
            L->data[k + 1] = L->data[k];/*Move back, assignment*/
    }
    L->data[i - 1] = e;/*Insert new element*/
    L->length++;
    return OK;
}
  • Delete element operation

    Algorithm idea

    * if the deletion position is incorrect, an exception is thrown

    * remove and delete elements

    * if the deleted element is not the last position, traverse backward from the deleted element position to the last element position, and move them forward one position

    * table length-1

/*Initial condition: sequential linear table l already exists, 1 < = I < listlength (L)*/
/*Operation result: delete the ith data element in L and return its value with e. the length of L is - 1*/
Status ListDelete(Sqlist *L,int i,ElemType *e)
{
    int k;
    if(L->length==0)
        return ERROR;/*The linear table is empty*/
    if(i < 1 || i > L->length)
        return ERROR; /*The deletion location is incorrect*/
    *e = L->data[i-1];/*If the last location is not deleted*/
    if(i < L->length)
    {
        for(k = i;k < L->length;k++) /*Moves the subsequent element of the deleted position forward*/
            L->data[k - 1] = L->data[K];
    }
    L->length--;
    return OK;
}

An episode

When learning linear tables, I wrote down in the book why (E) should be inserted

Time complexity analysis

Save, read data as O(1), insert and delete as O(n)

Advantages and disadvantages of linear table sequential storage

advantage:

  1. There is no need to add additional storage space to represent the logical relationship between the elements in the table
  2. You can quickly access elements anywhere in the table

Disadvantages:

  1. Insert and delete operations require moving a large number of elements
  2. When the length of linear table changes greatly, it is difficult to determine the storage space
  3. Cause fragmentation of storage space and waste of storage space

3.4 chain storage structure of linear list

n nodes are linked into a linked list, which is the linked storage structure of the linear list (a1, a2,..., an). Because each node of the linked list contains only one pointer field, it is called a single linked list.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-7i0rc7vp-1635213668869) (C: \ users \ Gabrielle \ appdata \ roaming \ typora \ user images \ image-20210316171059107. PNG)]

Header pointer: the storage location of the first node in the linked list is called header pointer

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-jwkrttlp-1635213668873) (C: \ users \ Gabrielle \ appdata \ roaming \ typora user images \ image-20210316193855223. PNG)]

In order to operate the linked list more conveniently, a header node will be attached before the first node of the single linked list

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-m3ezzktv-1635213668876) (C: \ users \ Gabrielle \ appdata \ roaming \ typora user images \ image-20210316194335689. PNG)]

Similarities and differences between header pointer and header node

Head pointer: * refers to the pointer of the linked list to the first node. If the linked list has a head node, it refers to the pointer of the head node

* the header pointer has the function of identification, so the header pointer is often named with the name of the linked list

* whether the linked list is empty or not, the header pointer is not empty

Header node: * it is set up for the unification and convenience of operation. If it is placed before the node of the first element, its data field is generally meaningless and can also store the length of the linked list

* the operations of inserting and deleting nodes before the node of the first element are unified

* the header node is not necessarily a required element of the linked list

Our main concern is the logical relationship between data elements and data elements

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-19m3ispb-163521366880) (C: \ users \ Gabrielle \ appdata \ roaming \ typora user images \ image-20210316195835877. PNG)]

Single linked list, structure pointer code is as follows

/*Single linked list storage structure of linear table*/
typedef struct Node
{
    ElemType data;
    struct Node *next;
}Node;
typedef struct Node *LinkList;/*Define LinkList*/

A node consists of a data field for storing data elements and a pointer field for storing subsequent nodes.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-11exhleu-163521366881) (C: \ users \ Gabrielle \ appdata \ roaming \ typora user images \ image-20210316200939686. PNG)]

3.4.1 basic operation of single linked list

  • Reading of single linked list

Algorithm idea

  1. Declare a pointer p to the first node of the linked list, and initialize j from 1
  2. When J < I, traverse the linked list, make the pointer of p move backward, and constantly point to the next node, j+1
  3. If p is empty at the end of the linked list, it indicates that the ith node does not exist
  4. Otherwise, the search succeeds and the data of node p is returned

The time complexity of the algorithm depends on the position of i.

/*Initial condition: sequential linear table l already exists, 1 < = I < = listlength (L)*/
/*Operation result: use e to return the value of the ith data element in L*/
Status GetElem(LinkList L,int i,ElemType *e)
{
    int j;
    LinkList p;
    p = L->next;/*Declare a pointer p*/
    j=1; /*j For a counter*/
    while (p && j<i)
    {
        p = p->next;
        ++j;
    }
    if(!p || j>i)
        return ERROR;
    *e = p->data;
    return OK;
}

Why use a while loop instead of a for loop?

cuz single linked list structure does not define the table length, and the number of cycles is unknown. It is not convenient to use for to control

  • Insertion and deletion of single linked list

insert

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-wumyvutv-163521366883) (C: \ users \ Gabrielle \ appdata \ roaming \ typora \ user images \ image-20210316203331175. PNG)]

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

Change the successor node of P to the successor node of S, and then change p - > next to s

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-aralqndu-16352131668885) (C: \ users \ Gabrielle \ appdata \ roaming \ typora \ user images \ image-20210316203402489. PNG)]

Insertion algorithm idea

  1. Declare a pointer p to the chain header node, and initialize j from 1
  2. When J < I, traverse the linked list, move the p pointer back, and constantly point to the next node, j+1
  3. If the end p of the linked list is empty, the ith node does not exist
  4. Otherwise, the search succeeds and an empty node s is generated in the system
  5. Assign data e to s - > data
  6. Single linked list insert standard statement s - > next = P - > next; p->next = s;
  7. Return success
/*Initial condition: sequential linear table l already exists, 1 < = I < = listlength (L)*/
/*Operation result: insert a new data element e before the ith node in L, and the length of L + 1*/
Status ListInsert(LinkLikst *L,int i,ElemType e)
{
    int j;
    LinkList p,s;
    p = *L;
    j = 1;
    while(p && j < i);/*Find the i-1 node*/
    {
        p = p->next;
        ++j;
    }
    if(!p || j>i)
        return ERROR;
    s = (LinkList)malloc(sizeof(Node));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK;
}
  • delete

Change the subsequent node of p into the subsequent node of p

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-g44lrtnd-163521366886) (C: \ users \ Gabrielle \ appdata \ roaming \ typora user images \ image-20210316205513844. PNG)]

q = p->next;
p->next = q->next;

Delete algorithm idea

  1. Declare a pointer p to the chain header pointer, and initialize j from 1
  2. When J < I, traverse the linked list, move the p pointer back, and constantly point to the next node, j+1
  3. If the end p of the linked list is empty, the ith node does not exist
  4. Otherwise, the search is successful, and the node to be deleted p - > next is assigned to q
  5. Delete standard statement of single linked list p - > next = q - > next
  6. Assign the data of node q to e as a return
  7. Release node q;
  8. Return success
/*Initial condition: sequential linear table l already exists, 1 < = I < = listlength (L)*/
/*Operation result: delete the ith node of L and return its value with e. the length field of L is - 1*/
Status ListDelete(LinkList *L,int i,ElemType *e)
{
    int j;
    LinkList q,p;
    p = *L;
    j = 1;
    while(p->next && j<i)
    {
        p = p->next;
        ++j;
    }
    if(!(p->next) || j>i)
        return ERROR;
    q = p->next;
    *e = q->data;
    free(q);/*C The standard function of free is to let the system reclaim a Node and free memory*/
    return OK;
}

For the more frequent operations of inserting and deleting data, the efficiency advantage of single linked list is obvious.

  • Creation of single linked list = = the process of dynamically generating linked list, and the establishment of empty list begins

Algorithm idea

  1. Declare a pointer p and a counter variable i

  2. Initialize an empty linked list L

  3. Let the pointer of the head node of L point to NULL, that is, establish a single linked list of the head node

  4. Loop * generates a new node and assigns it to p

    * randomly generate a number assigned to the data field p - > data of p

    * insert p between the head node and the previous new node

Head insertion

/*Randomly generate the values of n elements and establish a single chain linear table L (head interpolation) of the leading node*/
void CreateListHead(LinkList *L,int n)
{
    LinkList p;
    srand(time(0));/*Initialize random number seed*/
    *L = (LinkList)malloc(sizeof(Node));
    (*L)->next = NULL;/*First establish a single linked list of leading nodes*/
    for(i = 0;i < n;i++ )
    {
        p = (LinkList)malloc(sizeof(Node));
        p->data = rand()%100+1;/*Randomly generate numbers within 100*/
        p->next = (*L)->next;
        (*L)->next = p;
    }
}

Tail interpolation

/*Randomly generate the values of n elements, and establish the single chain linear table L (tail interpolation) of the leading node*/
void CreateListTail(LinkList *L,int n)
{
    LinkList p,r;
    int i;
    srand(time(0));
    *L = (LinkList)malloc(sizeof(Node));
    r = *L;
    for(i = 0;i < n;i++)
    {
        p = (Node *)malloc(sizeof(Node));
        p->data = rand()%100+1;
        r->next = p;
        r = p;
    }
    r->next = NULL;
}

Whole table deletion of single linked list

Algorithm idea

  1. Declare a node p and q
  2. Assign the first node to p
  3. loop
  • Assign the next node to q
  • Release p
  • Assign q to p
/*Initial condition: sequential linear table already exists*/
/*Reset L to empty table*/
Status CleanList(LinkList *L)
{
    LinkList p,q;
    p = (*L)->next;
    while(p)
    {
        q = p->next;
        free(p);
        p = q;
    }
    (*L)->next = NULL;
    return OK;
}

Why set the variable q?

cuz: when free § is released, p includes pointer field and data field. When free § is released, the pointer field is also released. The next node cannot be found, so q is required.

Advantages and disadvantages of single linked list structure and sequential storage structure

1. Storage allocation method

  • Sequential storage structure uses a continuous section of storage units to store data elements in turn.
  • The single linked list adopts the chain storage structure, and any group of storage units are used to store the data elements of the linear list, opening up space discontinuity

2 time performance

  • Find: sequential storage structure 0 (1), single linked table 0(n)
  • Insert and delete: sequential storage structure O(n), single linked table O(1)

3 space performance

  • Sequential storage structure needs to allocate storage space in advance, which is easy to cause space waste and overflow
  • Single linked list dynamically allocates storage space.

3.5 static linked list

Definition: a linked list described by an array is called a static linked list (cursor implementation, data, cur)

/*Static chain storage structure of linear table*/
#define MAXSIZE 1000
typedef struct
{
    ElemType data;
    int cur;/*Cursor curson, no pointing when 0*/
}

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-laoqzxfe-163521366888) (C: \ users \ Gabrielle \ appdata \ roaming \ typora \ user images \ image-20210317154701193. PNG)]

The above figure is equivalent to the initialized array state

/*Chain the components in one-dimensional array space into a spare table*/
/*sapce[0].cur Is a header pointer, "0" represents a null pointer*/
Status InitLink(StaticLinkList space)
{
    int i;
    for(i = 0;i < MAXSIZE-1;i++)
 		space[i].cur = i + 1;
	space[MAXSIZE-1].cur  = 0;/*At present, the linked list is 0, and the cur of the last data element is 0*/
    return  OK;
}

In the dynamic linked list, the application and release of nodes are realized by malloc() and free() functions respectively. Static linked list operation is array, static linked list insertion and deletion, need to write implementation functions.

Static linked list is actually an implementation designed for high-level languages without pointers

insert

/*If the spare space linked list is not empty, the allocated node subscript is returned; otherwise, 0 is returned*/
int  Malloc_SLL(StaticLinkList space)
{
    int i = space[0].cur;
    if(space[0].cur)
        space[0].cur = space[i].cur;
    return i;
}

/*Insert a new data element e before the ith element in L*/
Status ListInsert(StaticLinkList L,int i,ElemType e)
{
    int j,k,l;
    k = MAX_SIZE-1;	/*k Is the subscript of the last element*/
    if(i <1 ||i > ListLength(L) + 1)
	return ERROR;
    j = Malloc_SSL(L);	/*Gets the subscript of the free component*/
    if(j)
    {
        L[j].data = e;
        for(l = 1; l <=i-1; l++) /*Find the position before the ith element*/
            	k = L[k].cur;
        
        L[j].cur = L[k].cur; /*Assign cur before the ith element to the new element*/
        L[k].cur = j; /*Assign the subscript of the new element to the cur of the element before the ith element*/
        
        return OK;
    }
    return ERROR;
}

delete

/*Delete the ith data element in L, which is equivalent to free()*/
Status ListDelete(StaticLinkList L,int i)
{
    int j,k;
    if(i < 1 || i > ListLength(L))
	return ERROR;
    k = MAX_SIZE-1;
    for(j = 1;j<= i-1;j++)
 		k = L[k].cur;
    j = L[k].cur;
    L[k].cur = L[j].cur;
    Fred_SSL(L,j);
    return OK;
}

void Free_SSL(StaticLinkList space,int k)
{
    space[k].cur = space[0].cur;
    space[0].cur = k;
}

Advantages and disadvantages of static linked list

advantage

There is no need to move elements during insert and delete operations, and the disadvantage of moving a large number of elements during insert and delete operations in sequential storage structure is improved

shortcoming

It is difficult to determine the table length, which can not solve the problems caused by the allocation of space, which may cause a waste of space

Random access without sequential storage structure
n ERROR;
}

**delete**

```C
/*Delete the ith data element in L, which is equivalent to free()*/
Status ListDelete(StaticLinkList L,int i)
{
    int j,k;
    if(i < 1 || i > ListLength(L))
	return ERROR;
    k = MAX_SIZE-1;
    for(j = 1;j<= i-1;j++)
 		k = L[k].cur;
    j = L[k].cur;
    L[k].cur = L[j].cur;
    Fred_SSL(L,j);
    return OK;
}

void Free_SSL(StaticLinkList space,int k)
{
    space[k].cur = space[0].cur;
    space[0].cur = k;
}

Advantages and disadvantages of static linked list

advantage

There is no need to move elements during insert and delete operations, and the disadvantage of moving a large number of elements during insert and delete operations in sequential storage structure is improved

shortcoming

It is difficult to determine the table length, which can not solve the problems caused by the allocation of space, which may cause a waste of space

Random access without sequential storage structure

Topics: data structure linked list