The basic operation of C language to realize singly linked list

table of Contents

1. The definition of linked list nodes

2. The statement of the linked list basic operation Function

3. The definition and realization of the basic operation function of the linked list

 3.1 Creation of singly linked list (head insertion method)

3.2 The creation of a singly linked list (tail interpolation)

3.3 The creation of an ordered singly linked list

3.4 Traversal of singly linked lists 

3.5 Finding an element in a singly linked list

3.6 Insert an element after the specified position in the singly linked list

3.7 Delete specific elements in a singly linked list

3.8 The problem of merging two ordered singly linked lists 

to sum up



1. The definition of linked list nodes

The definition of a singly linked list node only needs to have a data field and a pointer field. The data field is used to store node data, and the pointer field is used to store the address of subsequent nodes (without it, you can still call it a linked list!) , The definition code is as follows:

typedef int Status;     //状态码数据类型
typedef int ElemType;      //数据元素数据类型
typedef struct Node{
    ElemType data;
    struct Node *next;
}Node;
typedef struct Node *LinkList;        //结构体链表指针

2. The statement of the linked list basic operation Function

The basic operation functions of singly linked lists are nothing more than the basic operations of creation, deletion, insertion, query, and traversal. Here I will simply implement the functions of creation, traversal, insertion, and query (I am here with "sentinel "Single linked list!)

//创建单链表(头插法)
void CreateListHead(LinkList *L, int n);
//创建单链表(尾插法)
void CreateListTail(LinkList *L, int n);
//插入节点
//删除节点
//查询特定节点
Status Find_List_Node(LinkList L, ElemType data);
//遍历单链表
void DisplayList(LinkList L);
//创建特定有序链表(头插法)
void CreateOrderListH(LinkList *L, int n, int array[]);
//创建特定有序链表(尾插法)
void CreateOrderListT(LinkList *L, int n, int array[]);
//合并两个有序单链表
LinkList MergeTwoList(LinkList l1, LinkList l2);

Here I added a question often tested in the interview, which is the "operation of merging two ordered singly linked lists", which is shown in LinkList MergeTwoList (LinkList l1, LinkList l2)!

3. The definition and realization of the basic operation function of the linked list

 3.1 Creation of singly linked list (head insertion method)

First of all, let's implement the creation function of singly linked list. The creation of singly linked list is divided into two types: head insertion method and tail insertion method (remember, I am a singly linked list with a head node!). Let's talk about head insertion first!

How to insert the head! That is to insert one by one node into the successor position of the head node, that is, place each newly inserted node in the successor position of the head node (sentinel node)! As long as you understand this point, the realization will be the same as playing in mud. First, you need to create a P node and make its pointer field point to NULL. (I'm afraid he will do things, so it is best to point to empty) This P node is just one Babysitter, used to take care of the data and pointers of our newly created nodes. We allocate memory space for the incoming head node, then create a new node, allocate data (a random number), and put the next pointer field of the P node Point to the successor of the head node (head->next); the specific code implementation is as follows

//创建单链表(头插法)
void CreateListHead(LinkList *L, int n)
{
    LinkList p; int i;
    //srand(time(0));       //初始化随机数种子
    *L = (LinkList)malloc(sizeof(Node));
    (*L)->next = NULL;     //建立一个带头结点的单链表
    for(i = 0; i < n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));      //生成新的节点
        p->data = rand() % 100 + 1;     //生成100以内的随机数
        p->next = (*L)->next;
        (*L)->next = p;     //插入到表头
    }
}

3.2 The creation of a singly linked list (tail interpolation)

Let's take a look at how the tail insertion method works? The tail plug method! Is to insert the new node into the tail of the singly linked list, then? How do we know where is the tail of the singly linked list? Here we place a "pawn", this pawn does nothing, just to help us record where the "tail of the singly linked list" is, find the tail, and insert the new node behind the tail. At this time, our pawn is not pointing to the single The tail of the linked list is over, we need to make the soldier move one node back (update the point of the soldier), so that the soldier will point to the tail of the singly linked list again! Repeat in turn! When you are done inserting, don’t forget to let your soldier point to Kongha (otherwise he will do something!); the specific implementation code is as follows!

//创建单链表(尾插法)
void CreateListTail(LinkList *L, int n)
{
    LinkList p, r; int i;
    //srand(time(0));     //初始化随机数种子
    *L = (LinkList)malloc(sizeof(Node));        //L为整个线性表
    r = *L;     //r为指向尾部的节点
    for(i = 0; i < n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));     //生成新的节点
        p->data = rand() % 100 + 1;     //随机生成100以内的数字
        r->next = p;        //将表尾终端节点的指针指向新节点
        r = p;      //将当前的新节点定义为表尾终端节点
    }

    r->next = NULL;     //表示当前链表结束
}

3.3 The creation of an ordered singly linked list

For the creation of this ordered singly linked list, I use sequential storage structure data to store node data. We only need to modify the above function to use it! That is, just add one more array parameter! The specific implementation code is as follows:

//创建特定有序链表(头插法)
void CreateOrderListH(LinkList *L, int n, int array[])
{
    LinkList p; 
    int i;
    *L = (LinkList)malloc(sizeof(Node));
    (*L)->next = NULL;
    for(i = 0; i < n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));
        p->data = array[i];
        p->next = (*L)->next;
        (*L)->next = p;     //插到表头
    }
}
//创建特定有序链表(尾插法)
void CreateOrderListT(LinkList *L, int n, int array[])
{
    LinkList r,p;
    int i;
    (*L) = (LinkList)malloc(sizeof(Node));
    r = (*L);
    for(i = 0; i < n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));
        p->data = array[i];
        r->next = p;
        r = p;
    }
    r->next = NULL;
}

3.4 Traversal of singly linked lists 

The traversal of singly linked lists is quite simple! If you don’t, 99% of it is because you didn’t understand pointers! Then take a good look at the pointer and look at it again! code show as below:

//遍历单链表
void DisplayList(LinkList L)
{
    LinkList p;     //声明一节点
    p = L->next;    //让p指向L的第一个节点
    for(;p != NULL; p = p->next)
    {
        printf("%d ",p->data);
    }
    printf("\n");
}

Is it so easy? What? So, if you don’t understand, just knock on your head! Thinking of the past (hhhhhh)

3.5 Finding an element in a singly linked list

This is also relatively simple, so Brother Cai won't talk about it! Post the code directly! If you don’t understand, you’ll have to think about it!

//查询特定节点元素
Status Find_List_Node(LinkList L, ElemType data)
{
    LinkList p; int j;
    p = L->next;
    for(j = 1; p != NULL; p = p->next, j++)
    {
        if(data == p->data)
        {
            break;
        }
        else
            continue;
    }
    p->next = NULL;
    return j;
}

3.6 Insert an element after the specified position in the singly linked list

        Insert an element after the specified position in the singly linked list. This operation is not difficult. The general idea is like this. Traverse the linked list, search for the node at the corresponding position, use a "nanny" pointer to store the inserted data, and add the "nanny" pointer Store the pointer field of the specific location node into the subsequent address of the node, and then store the pointer field of the specific location node into the address of the "nanny" pointer! The specific operation code is as follows:

//在特定位置插入节点
void InsertListElem(LinkList *L, int n, ElemType data)
{
    LinkList me, pre; int i = 1;
    pre = (*L)->next;
    if(pre == NULL)
        printf("LinkList is NULL!\n");
    else
    {
        for(; i < n; i++)
        {
            pre = pre->next;
        }
        me = (LinkList)malloc(sizeof(Node));
        me->data = data;
        me->next = pre->next;
        pre->next = me;
    }
}

3.7 Delete specific elements in a singly linked list

       It is not difficult to delete a specific element in a singly linked list. The idea is roughly two steps. The first is to traverse the linked list to find the node corresponding to the specific element. The second is to kick the node out of the linked list and release the node. Memory space (otherwise there will be memory overflow problems!), alright! Not much nonsense, just go to the code!

//在单链表中删除指定元素
Status DeleteListElem(LinkList *L, ElemType data)
{
    LinkList me, bonne;
    me = (*L);
    while(me->next != NULL)
    {
        if(me->data == data)
        {
            bonne->next = me->next;
            free(me);
            return OK;
        }
        else
        {
            bonne = me;
            me = me->next;
        }
    }
    return ERROR;
}

3.8 The problem of merging two ordered singly linked lists 

        Listen carefully! This interview is often a testament! The general idea is to compare, move backward, and then compare. When whoever finishes moving first, it can basically be over! (The following is in order from small to large)

 

As shown in the picture! L1 and L2 are two ordered singly linked lists (the leading node!), L3 is a new head node we created, used to connect the merged result, first compare the data of the first node of L1 with L2 The data of the first node, if L1 is smaller than L2, point the head node of L3 to the first node of L1, and move L3 back by one position, and then compare it. When the comparison is last, who will arrive first At the end, you can directly connect the nodes that are not at the end to the tail of L3! The specific operation code is as follows:

//合并两个有序单链表
LinkList MergeTwoList(LinkList l1, LinkList l2)
{
    LinkList preHead = (LinkList)malloc(sizeof(Node));
    LinkList prev = preHead,list1 = l1->next, list2 = l2->next;
    while(list1 != NULL && list2 != NULL)
    {
        if(list1->data <list2->data)
        {
            prev->next = list1;
            list1 = list1->next;
        }
        else{
            prev->next = list2;
            list2 = list2->next;
        }

        prev = prev->next;
    }
    // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
    prev->next = list1 == NULL ? list2 : list1;

    return preHead->next;
}

to sum up

That's it, that's it, Cai Ge's lecture is over!

right! The blogger is a person who loves cooking and fun! Please give me a lot of praise if you like it! At the same time, there are some shortcomings in the article, and you are welcome to comment below, and Cai Ge will read it!

Guess you like

Origin blog.csdn.net/songjun007/article/details/114005551