链表面试题

来源:互联网 发布:互动投影软件 编辑:程序博客网 时间:2024/05/29 07:23

1.从尾到头打印单链表

思路:用两个指针来控制打印:
①tail先指向NULL,然后指针cur从头往后走,走到tail前一个位置,就是最后一个节点,打印这个节点。
②tail往前走,tail指向链表最后一个节点,再让cur走到tail前一个位置,打印。
………….

void SListPrintTailToHead(SListNode* pHead) //从尾到头打印单链表{    SListNode* tail = NULL;    SListNode* cur = NULL;    while (tail != pHead)    {        cur = pHead;        while (cur->_next != tail)        {            cur = cur->_next;        }        printf("%d ", cur->_data);        tail = cur;    }}

2.删除一个无头单链表的非尾节点(不能遍历链表)

思路:找到我们可以找到pos的下一个节点,把pos下一个节点的值给pos,再删除pos->next。这样就相当于删除了pos。

void SListRemove(SListNode* pos){    assert(pos != NULL && pos->_next != NULL);    SListNode* next = pos->_next;    pos->_data = next->_data;    pos->_next = next->_next;    next->_next = NULL;    free(next);}

3.在无头单链表的一个节点前插入一个节点(不能遍历链表)

思路:在pos后面插入一个节点newNode,它的数据域放的是pos->_data,然后把pos-> _data改成x,这样就相当于在pos前面插入一个值为x的节点

void SListInsert2(SListNode* pos, DataType x)//在无头单链表的一个节点前插入一个节点(不能遍历链表){    assert(pos != NULL);    SListNode* tail = pos->_next;    SListNode* newNode = BuySListNode(pos->_data);    newNode->_next = pos->_next;    pos->_next = newNode;    pos->_data = x;}

4.单链表实现约瑟夫环(JosephCircle)

思路:先把链表连接成环,从1数到k,其实是往前移动k-1次,然后删除第k个链表。当链表只剩下最后一个节点时,循环结束。

SListNode* JosephCircle(SListNode* pHead, DataType k){    SListNode* cur = pHead;    SListNode* next;    while (cur->_next != cur)    {        DataType count = k;        while (--count) //k-1次循环        {            cur = cur->_next;        }        next = cur->_next;        cur->_data = next->_data;        cur->_next = next->_next;        free(next);    }    return cur;}

5.逆置/反转单链表

思路:定义三个结构体指针进行操作
注意:①开始之前把n1->_next = NULL 。②循环结束的条件

SListNode* ReverseList(SListNode* list)//逆置/反转单链表{    SListNode* n1, *n2, *n3;    if (list == NULL || list->_next == NULL)    {        return list;    }    n1 = list;    n2 = n1->_next;    n3 = n2->_next;    n1->_next = NULL;    while (n2 != NULL)    {        n2->_next = n1;        n1 = n2;        n2 = n3;        if (n3 != NULL)        {            n3 = n3->_next;        }    }    return n1;}

6.单链表排序(冒泡排序&快速排序)

冒泡排序int SListLenth(SListNode* list) //计算链表长度{    int lenth = 0;    while (list != NULL)    {        lenth++;        list = list->_next;    }    return lenth;}void SListBubbleSort(SListNode* list) //冒泡排序{    SListNode* cur = NULL;    SListNode* prv = NULL;    cur = list;    int size = SListLenth(list);    while (size--)    {        int flag = 0;        while (cur->_next != NULL)        {            if (cur->_data > cur->_next->_data)            {                flag = 1;                DataType tem = cur->_data;                cur->_data = cur->_next->_data;                cur->_next->_data = tem;            }            cur = cur->_next;        }        cur = list;        if (0 == flag)        {            break;        }    }}

7.合并两个有序链表,合并后依然有序

递归法:

SListNode* MergeSList(SListNode* pHead1, SListNode* pHead2){    if (NULL == pHead1)    {        return pHead2;    }    else if (NULL == pHead2)    {        return pHead1;    }    SListNode* newMergeListHead = NULL;     if (pHead1->_data < pHead2->_data)    {        newMergeListHead = pHead1;        newMergeListHead->_next = MergeSList(pHead1->_next, pHead2);    }    else    {        newMergeListHead = pHead2;        newMergeListHead->_next = MergeSList(pHead1, pHead2->_next);    }    return newMergeListHead;}
/*非递归*/SListNode* MergeSList(SListNode* pHead1, SListNode* pHead2){    if (NULL == pHead1)    {        return pHead2;    }    else if (NULL == pHead2)    {        return pHead1;    }    SListNode* newMergeListHead = NULL;//把排序好的链表存到这里面    SListNode* tail = NULL;  //记录新链表最后一个节点    if (pHead1->_data < pHead2->_data)    {        newMergeListHead = pHead1;        pHead1 = pHead1->_next;    }    else    {        newMergeListHead = pHead2;        pHead2 = pHead2->_next;    }    tail = newMergeListHead; //确定好第一个结点    while (pHead1 != NULL && pHead2 != NULL)    {        if (pHead1->_data < pHead2->_data)        {            tail->_next = pHead1;            pHead1 = pHead1->_next;        }        else        {            tail->_next = pHead2;            pHead2 = pHead2->_next;        }        tail = tail->_next;    }    if (NULL == pHead1)    {        tail->_next = pHead2;    }    else if (NULL == pHead2)    {        tail->_next = pHead1;    }    return newMergeListHead;}

8.查找单链表的中间节点,要求只能遍历一次链表

SListNode* FindMidNode(SListNode* list) // 遍历一遍找到链表中间节点{    assert(list != NULL);    SListNode* pFast = list;    SListNode* pSlow = list;    while (pFast != NULL && pFast->_next != NULL)    {        pFast = pFast->_next->_next;        pSlow = pSlow->_next;    }    return pSlow;}

《未完待续》

原创粉丝点击