Bidirectional linked list of data structure (implemented in C language)

Several insertion, deletion and specified location output of bidirectional linked list

Appearance of two-way linked list

A two-way linked list is composed of a precursor pointer, a descendant pointer and a data field. The front and back pointers between nodes are connected to form a linked list

Encapsulation of bidirectional linked list nodes

Compared with a single linked list, a two-way linked list has only one more precursor pointer

typedef struct Node {
    int data;//content
    struct Node* frontNode;//Precursor pointer
    struct Node* nextNode;//Subsequent pointer
}*LPNODE;

The characteristic of bidirectional linked list is that it can output the linked list from left to right or from right to left. Therefore, a head node and tail node need to point to the head and tail of the linked list respectively to realize the sequential or reverse printing of the linked list

Encapsulated linked list

typedef struct List {
    struct Node* HeadNode;//Head node
    struct Node* TailNode;//Tail node
    int curSize;//Wanjinyou parameters
}*LPLIST;

Wanjinyou parameter is responsible for recording the number of nodes to facilitate subsequent condition judgment

Create head and tail nodes

Here, it mainly plays the role of encapsulating the head node and tail node. The function initializes the node and returns the corresponding node

LPNODE CreateHeadNode() {
    LPNODE headNode = (LPNODE)malloc(sizeof(Node));//Dynamically request memory of a node size
    assert(headNode);//Air judgment
    headNode->frontNode = NULL;
    headNode->nextNode = NULL;
    return headNode;
}
LPNODE CreateTailNode() {
    LPNODE tailNode = (LPNODE)malloc(sizeof(Node));
    assert(tailNode);
    tailNode->frontNode = NULL;
    tailNode->nextNode = NULL;
    return tailNode;
}

NULL is determined because the memory application may fail and return NULL. This function is to avoid affecting the operation of subsequent pointers due to assignment to NULL pointers.

Create a new node

LPNODE CreateNode(int data) {
    LPNODE newNode = (LPNODE)malloc(sizeof(Node));
    assert(newNode);
    newNode->data = data;//Unlike the head node and tail node, the node to be inserted is to initialize data
    newNode->frontNode = NULL;
    newNode->nextNode = NULL;
    return newNode;
}

The purpose of creating a new node is to facilitate the creation of subsequent new nodes

Create linked list and initialize data

LPLIST CreateList() {
    LPLIST list = (LPLIST)malloc(sizeof(List));//Request a List size memory
    assert(list);//Air judgment
    list->curSize = 0;//The current node is 0
    list->HeadNode = CreateHeadNode();//Initialize header node
    list->TailNode =CreateTailNode();//Initialize tail node
    return list;
}

Head insertion

The key point here is that when the node is 0, the next node of the head node is NULL. If you want to insert again, you must require the precursor pointer of the next node of the head node to point to the new node. Here, because the node is NULL, you can't manually operate the NULL pointer to cause an interrupt

The tail node points to the last node, because the head interpolation is always inserted in the middle, and the position of the tail node at the end has not changed

The code is as follows:

void insertByHead(LPLIST list, int data) {
    LPNODE newNode = CreateNode(data);
    if(list->curSize==0)//When there are no nodes
        list->TailNode = newNode;//Point to a new node for the node
    else {
        newNode->nextNode = list->HeadNode->nextNode;//The trailing pointer of the new node points to the next of the header node
        list->HeadNode->nextNode->frontNode = newNode;//The precursor pointer of the new node points to the new node
    }
    list->HeadNode->nextNode = newNode;//The trailing pointer of the header node points to the new node
    newNode->frontNode = list->HeadNode;//The precursor pointer of the new node points to the head node
    list->curSize++;//Each time one is inserted, the number of nodes is increased by one
}

Tail interpolation

The key point of tail interpolation is similar to that of head interpolation, because when the node is 0, the subsequent pointer will be null

In addition, every new node inserted is the tail node, and the direction of the tail node should be changed

The code is as follows:

void insertByTail(LPLIST list, int data) {
    LPNODE newNode = CreateNode(data);
    if (list->curSize == 0)//When node is empty
        list->HeadNode =newNode;
    else {
        list->TailNode->nextNode = newNode;//Straight in the back
        newNode->frontNode = list->TailNode;
    }
    list->TailNode = newNode;//Change tail node
    list->curSize++;
}

Insert at specified location

Idea: prepare a pointer in the front and a pointer in the back. The two pointers go hand in hand. When the later pointer points to the specified position, insert the data between the two pointers

The point here is that if the specified data is not found, the data should be inserted behind the linked list, and the tail node changes at the same time

The code is as follows:

void insertByAppoint(LPLIST list, int data, int posData) {
    LPNODE LeftNode = list->HeadNode->nextNode;//Left pointer
    LPNODE curNode = list->HeadNode->nextNode;//Current pointer
    while (curNode != NULL && curNode->data != posData) {//Keep looking if you don't find it. The CurNode found is empty
        LeftNode = curNode;//Move left pointer
        curNode = curNode->nextNode;//Move current pointer
    }
    LPNODE newNode = CreateNode(data);//Create a new node
    //After that, insert the middle operation
    LeftNode->nextNode = newNode;
    newNode->frontNode = LeftNode;
    if (curNode == NULL)//Tail node change
        list->TailNode = newNode;
    if (curNode != NULL) {
        newNode->nextNode = curNode;
        curNode->frontNode = newNode;
    }
    list->curSize++;//Increase in the number of nodes
}

Node deletion

The idea here is similar to the above. Prepare two pointers, one in the front and one in the back, going hand in hand. When the position of the node to be deleted is found, stop moving, connect the next node of the rear pointer with the node pointed to by the front pointer, and finally release the memory of the node pointed to by the rear pointer

The code is as follows:

void DeleteByAppoint(LPLIST list, int posData) {
    LPNODE frontNode = list->HeadNode;//Front pointer
    LPNODE curNode = list->HeadNode;//Current pointer
    while (curNode != NULL && curNode->data != posData) {
        frontNode = curNode;
        curNode = curNode->nextNode;
    }
    if (curNode == NULL)//Return if not found
        return;
    //Connect nodes in front of and behind curNode
    frontNode->nextNode = curNode->nextNode;
    curNode->nextNode->frontNode = frontNode;
    free(curNode);//Free memory
    curNode = NULL;
    list->curSize--;//Delete one node and one node less
}

Orderly insertion of linked list

Prepare a pile of disorderly data and return the ordered linked list through orderly insertion

Idea: insert one by one in order. When the value of the next node is larger or smaller than the value in the node to be inserted, insert it in front of the node to form a sort from small to large or from large to small. If it is not found, insert it in the back

main points:

1. If you want to insert to the back, you don't need to point the predecessor pointer of the subsequent pointer to the front node, because misoperation of the null pointer will cause program interruption

2. When a new node is inserted into the last position, the tail node will change

The code is as follows:

void insertBySqList(LPLIST list, int Mydata) {
    LPNODE frontNode = list->HeadNode;//Front pointer
    LPNODE PosNode = list->HeadNode->nextNode;//Specify position pointer
    while (PosNode != NULL && PosNode->data < Mydata) {
        frontNode = PosNode;//move
        PosNode = PosNode->nextNode;//move
    }
    LPNODE newNode = CreateNode(Mydata);//New node creation
    frontNode->nextNode = newNode;
    newNode->frontNode = frontNode;
    if (PosNode == NULL)//Change tail node
        list->TailNode = newNode;
    if (PosNode != NULL) {
        PosNode->frontNode = newNode;
        newNode->nextNode = PosNode;
    }
    list->curSize++;
}

Print linked list

You can print from beginning to end or from end to end

1. From beginning to end

void printListByHead(LPLIST list) {
    printf("Head output:\t");
    LPNODE pMove = list->HeadNode->nextNode;
    while (pMove) {
        printf("%d\t", pMove->data);
        pMove = pMove->nextNode;
    }
    printf("\n");
}

2. From end to end

void printListByTail(LPLIST list) {
    printf("Tail output:\t");
    LPNODE pMove = list->TailNode;
    while (pMove!=list->HeadNode) {
        printf("%d\t", pMove->data);
        pMove = pMove->frontNode;
    }
    printf("\n");
}

Test code:

For the beauty of the console output data, I added some line breaks and text modifiers

The code is as follows:

int main() {
    LPLIST list = CreateList();
    printf("\n Tail interpolation\n");
    for (int i = 0; i < 5; i++)
        insertByTail(list, i);
    printListByHead(list);
    printListByTail(list);
    printf("Delete specified data");
    DeleteByAppoint(list, 3);
    printListByHead(list);
    LPLIST list2 = CreateList();
    printf("\n Head insertion\n");
    for (int i = 0; i < 5; i++)
        insertByHead(list2, i);
    printListByHead(list2);
    printListByTail(list2);
    printf("Delete specified data");
    DeleteByAppoint(list2, 2);
    printListByTail(list2);
    printf("Inserts the of the specified data");
    insertByAppoint(list2, 100, 2);
    printListByTail(list2);
    printf("Inserts the of the specified data");
    printListByHead(list2);
    LPLIST list3 = CreateList();
    int array[] = { 3,5,9,7,2,6 };
    printf("Construction of ordered linked list");
    for(int i=0;i<6;i++)
    insertBySqList(list3, array[i]);
    printListByTail(list3);
    printf("Construction of ordered linked list");
    printListByHead(list3);
    return 0;
}

The operation effect is as follows:

 

Keywords: C linked list

Added by clio-stylers on Wed, 05 Jan 2022 17:09:32 +0200