Singly linked list common interview questions (1)

One: Print a singly linked list from end to end

Idea: From the end to the beginning, we can easily think of the idea of ​​using function recursion. To print the first node, we must first print the second one. To print the second node, we must first print the third one..., so the method here is the simplest. It is to use function recursion, the code is as follows:

void PrintSListFromTail2Head(PNode pHead)//将单链表头节点传过来
{
    if (pHead->_pNext != NULL)
    {
        PrintSListFromTail2Head(pHead->_pNext);
    }

    printf("%d ", pHead->data);
    return;
}

There is also the possibility to create an array of structures, save the singly linked list to the array, and then print the array from end to end

Two: delete the non-tail node of the headless singly linked list (cannot traverse the linked list)

Idea: Because it is a non-tail node and cannot traverse the linked list, the node before pos cannot be found, so it is impossible to find the node before pos according to the conventional idea, let its _pNext point to the node after pos, and only delete the node after pos , and assign the following content to pos, the code is implemented as follows:

void DeleteListNotTailNode(PNode pos)
{
    PNode pNext = pos->_pNext;
    pos->data = pNext->data;//先将数据覆盖pos
    pos->_pNext = pNext->_pNext;//再链接后面的节点
    free(pNext);//释放节点
    pNext = NULL;

}

Three: Insert a node before a node in a headless singly linked list (cannot traverse the linked list)

Idea: As in the previous question, because there is no head node, the linked list cannot be traversed, so it is impossible to find the node in front of pos, only the latter node can be found, then insert a new node in between, and finally exchange the content of the new node with pos (because People let it be inserted into the pos position), the code is implemented as follows:

void InesrtPosFront(PNode pos, DataType data)
{
    PNode Next = pos->_pNext;//先保存pos的下一个节点
    pos->_pNext = BuyNewNode(pos->data);//将新节点链接到pos后面,传pos的data为了避免以后再交换
    pos->_pNext->_pNext = Next;//将pos之前的下个节点连接到新节点后面
    pos->data = data;//将传过来的data覆盖原data
}

Four: singly linked list to achieve Joseph circle (Josephcircle)

Ideas: Joseph Ring: Known n people (represented by numbers 1, 2, 3...n respectively) sit around a round table. The person numbered k starts to count, and the person who counts to m is dequeued; the next person starts to count from 1, and the person who counts to m is dequeued; repeat this pattern until around the round table There is only one person left, and the code is implemented as follows:

void JosephCircle(PNode* pHead, const int M)
{
    assert(pHead);

    while ((*pHead)->_pNext != *pHead)//等于说明只剩一个节点
    {
        PNode pCur = *pHead;
        PNode pPre = *pHead;
        int count = M;

        while (--count)//注意,这里是前置--
        {
            pPre = pCur;
            pCur = pCur->_pNext;
        }
        pPre->_pNext = pCur->_pNext;//链接链表
        *pHead = pCur->_pNext;//改变头指针位置
        free(pCur);
    }
}

Five: Reverse/reverse singly linked list

Method 1: Three pointers, idea: Change the original _pNext field to point to the next node and change it to point to the previous node, and the inversion is completed. The code items are as follows:

void ReverseSList(PNode* pHead)
{
    assert(pHead);
    PNode pPre = NULL;
    PNode pCur = *pHead;
    PNode pNext = NULL;

    if (NULL == *pHead)
        return;

    while (pCur)
    {
        pNext = pCur->_pNext;
        pCur->_pNext = pPre;//将Next指针域指向上一个节点
        pPre = pCur;
        pCur = pNext;
    }

    *pHead = pPre;//pPre成为新的头节点

}

Method Two-head insertion method idea: create a head pointer and assign null, and then insert each node head of the singly linked list from front to back into the created head pointer. The code is implemented as follows:

PNode ReverseSListOP(PNode pHead)
{
    PNode pCur = pHead;
    PNode pNewHead = NULL;

    while (pHead)
    {
        pCur = pHead;//进来就让pCur指向头部
        pHead = pHead->_pNext;//头向后走一步
        pCur->_pNext = pNewHead;//pCur插到新头部前
        pNewHead = pCur;//新头为pCur
    }

    return pNewHead;
}

Six: Merge two ordered linked lists, which are still in order after the merger

Idea: Create a new head node and empty it, create two pointers to point to the head nodes of the two linked lists respectively, start the comparison from front to back, and insert the larger tail into the new head node. The code is implemented as follows:

PNode MergeSList(PNode pHead1, PNode pHead2)
{
    PNode pCur1 = pHead1;
    PNode pCur2 = pHead2;
    PNode pNewHead = NULL;
    PNode pTail = NULL;//用来记录合并后链表的最后一个节点

    if (NULL == pHead1)
        return pHead2;
    if (NULL == pHead2)
        return pHead1;
    //放pNewHead
    if (pCur1->data < pCur2->data)
    {
        pNewHead = pCur1;
        pCur1 = pCur1->_pNext;
    }

    else if (pCur1->data >= pCur2->data)
    {
        pNewHead = pCur2;
        pCur2 = pCur2->_pNext;
    }
    //两链表中较小的节点尾插到pNewHead
    pTail = pNewHead;
    while (pCur1 && pCur2)//只要有一个链表为空就出来
    {
        if (pCur1->data < pCur2->data)
        {
            pTail->_pNext = pCur1;
            pCur1 = pCur1->_pNext;  
        }
        else if (pCur1->data >= pCur2->data)
        {
            pTail->_pNext = pCur2;
            pCur2 = pCur2->_pNext;
        }
        pTail = pTail->_pNext;

    }

    if (pCur1)//说明pCur2为空
        pTail->_pNext = pCur1;

    else
        pTail->_pNext = pCur2;

    return pNewHead;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325944666&siteId=291194637