Linear structure - linked list

Linked list definition

  1. n nodes discrete allocation
  2. Connected to each other by pointers
  3. Each node has only one predecessor node and each node has only one successor node
  4. The first node has no predecessor node and the tail node has no successor node

Technical Term

  1. Head node:
    The first valid node is the previous one
    The header node generally does not store data
    The purpose of adding head node is to facilitate the operation of linked list
  2. First node: the first node to store valid data
  3. Tail node: the last node to store valid data
  4. Head pointer: pointer variable to the head node
  5. Tail pointer: pointer variable to tail node
image.png

Chain classification

  • Single linked list
  • Double linked list
  • Circular list: tail node refers to head node
  • Acyclic list: all are acyclic list except the circular list

Implementation of acyclic single chain table

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
/**
    Define a linked list structure data type
*/
typedef struct Node{
    int data; //Data domain
    struct Node * pNext; //Pointer domain
}NODE,*PNODE; //NODE is equivalent to struct Node, PNODE is equivalent to struct Node*

/**
    Function declaration
*/
PNODE create_list(); //Initializing an empty list
void traverse_list(PNODE pHead);  //Traversing linked list
bool isEmpty(PNODE pHead); //Judge whether the list is empty
int length_list(PNODE pHead); //Calculate the length of the list
bool insert_list(PNODE,int,int);  //Insert linked list
bool delete_list(PNODE,int,int *);  //Delete linked list
void sort_list(PNODE);  //Sort list

int main()
{
    int elem; //Save the value of the deleted element
    PNODE pHead=NULL; //Equivalent to struct Node * pHead
    pHead = create_list(); //Create an acyclic single linked list and assign the address of the head node of the linked list to pHead
    //Test whether the link list is empty
    if(isEmpty(pHead))
        printf("The list is empty!!!!!\n");
    //Test traversal array
    traverse_list(pHead);

    //Test and calculate the length of chain list
    int leng = length_list(pHead);
    printf("The length of the list is:%d\n",leng);

    //Test to sort the linked list
    sort_list(pHead);
    traverse_list(pHead);

    //Test insert elements to linked list
    insert_list(pHead,2,88);
    traverse_list(pHead);

    //Test deleting elements in a linked list
    if(delete_list(pHead,2,&elem))
        printf("Delete succeeded. The elements you deleted are: %d\n ",elem);
    else
        printf("Deletion failed, unable to find the element to be deleted!");
    traverse_list(pHead);
    return 0;
}

/**
    Create an empty linked list
*/
PNODE create_list(){
    int length; //List number
    int data; //Link list node value

    //Generate the head node and assign the address of the head node to the head pointer
    PNODE pHead = (PNODE)malloc(sizeof(NODE));
    if(pHead==NULL){
        printf("Memory allocation failed, program terminated!\n");
        exit(-1);
    }

    //Define a tail pointer. When initializing, the tail pointer and the head pointer point to the head node at the same time, and the pointer field is empty, because there is no other node except the head node
    PNODE pTail = pHead;
    pTail->pNext=NULL;
    //Determine the number of nodes
    printf("Please enter the number of nodes to generate the list, length= ");
    scanf("%d",&length);

    //Enter values for each node
    for(int i=0; i<length; i++){
        printf("Please input number 1.%d Values of nodes: ",i+1);
        scanf("%d",&data);

        //Generate new node
        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if(pNew==NULL){
            printf("Memory allocation failed, program terminated!\n");
            exit(-1);
        }
        //Save the input value to the data field of the node
        pNew->data=data;
        //Hang the newly generated node to the back of the list, tail interpolation
        pTail->pNext=pNew;
        pNew->pNext=NULL; //The last node has no successor, so its pointer field is empty
        //Point the tail pointer to the last node
        pTail=pNew;
    }

    return pHead;
}

/**
    Traversing linked list
*/
void traverse_list(PNODE pHead){
    //In general, it does not operate directly on the head pointer, but redefines an operation pointer p, which points to the head node
    PNODE p = pHead->pNext;

    //When the list is empty, the program ends
    if(p==NULL){
        printf("The list is empty!\n");
        return;
    }

    //When the list is not empty, output the value of the list
    while(p != NULL){
        printf("%d\t",p->data);
        p=p->pNext;
    }
    printf("\n");

    return;
}

/**
    Judge whether the list is empty
*/
bool isEmpty(PNODE pHead){
    if(pHead->pNext==NULL)
        return true;
    else
        return false;
}

/**
    Calculate the length of the linked list, that is, the number of nodes
*/
int length_list(PNODE pHead){
    PNODE p = pHead->pNext;
    int leng=0; //It must be initialized. If it is not initialized, the garbage number will appear

    while(p != NULL){
        leng++;
        p=p->pNext;
    }
    return leng;
}

/**
    Sort the linked list
    The narrow sense algorithm is closely related to the storage mode of data
    The generalized algorithm is independent of the storage mode of data
    Therefore, although single chain table and sequential table are stored in different ways, they are basically the same in sorting related operations
*/
void sort_list(PNODE pHead){
    int i,j,t;
    int leg=length_list(pHead);
    PNODE p=NULL,q=NULL;
    for(i=0,p=pHead->pNext; i<leg-1; i++,p=p->pNext){
        for(j=i+1,q=p->pNext; j<leg; j++,q=q->pNext){
            if(p->data > q->data){ //Similar to a [i] > a [J] in an array
                t=p->data;  //Similar to t=a[i] in an array
                p->data = q->data;  //Similar to a[i]=a[j] in an array
                q->data=t;  //Similar to a[j]=t in an array
            }
        }
    }
    return;
}

/**
    Insert a new node with the value of element before the pos node of the linked list pointed to by pHead
    And the value of pos starts at 1
*/
bool insert_list(PNODE pHead,int pos,int element){
    int i=0;
    PNODE p=pHead;
    //Find the location where the element needs to be inserted, because p - > pnext may be empty, so judge from the beginning of the node
    while(p != NULL && i<pos-1){
        p=p->pNext;
        ++i;
    }

    if(p==NULL || i>pos-1)
        return false;

    //Dynamically allocate memory space for new nodes
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    if(pNew==NULL){
        printf("Dynamic memory allocation failed!");
        exit(-1);
    }

    pNew->data = element;

    //Insert the new node into the element and operate with the help of the third pointer
    /*PNODE q = p->pNext;
    p->pNext = pNew;
    pNew->pNext = q;*/

    //Insert the new node into the element and operate directly
    pNew->pNext = p->pNext;
    p->pNext = pNew;

    return true;
}

/**
    Delete the element at the specified position in the linked list
*/
bool delete_list(PNODE pHead,int pos,int * pElement){
    int i=0;
    PNODE p=pHead;
    //Find the element to be deleted. Since it is a deleted element, you need to judge from the first node
    while(NULL != p->pNext && i<pos-1){
        p=p->pNext;
        i++;
    }

    if(p->pNext == NULL || i>pos-1)
        return false;

    //Save the elements to be deleted before deleting the time line
    PNODE q=p->pNext;
    *pElement = q->data;

    //Perform delete operation
    p->pNext = p->pNext->pNext;
    free(q);
    q=NULL;

    return true;

}

Posted on Fri, 31 Jan 2020 10:25:54 -0500 by mordeith