链表的常见面试题

原创 2018年04月16日 11:53:54
链表的基本操作

逆序打印单链表
删除链表的非尾结点,要求:不能遍历链表
在链表pos位置前插入值到data的结点
查找链表的中间结点,要求只能遍历一次链表
查找链表的倒数第K个结点,要求只能遍历一次链表
删除链表的倒数第K个结点,要求只能遍历一次链表
用单链表实现约瑟夫环
链表的逆置–三个指针
链表的逆置–头插法
用冒泡排序思想对单链表进行排序
合并两个有序单链表,合并后依然有序
判断两个单链表是否相交—链表不带环
求两个单链表相交的交点—链表不带环
测试

逆序打印单链表
void PrintSListFromTail2Head(PNode pHead)       
{
    PNode pTail = NULL;
    PNode pCur = pHead;
    PNode pPre = NULL;
    if (NULL == pHead)
        return;
    while (pCur)
    {
        pTail = pCur;
        pCur = pCur->_pNext;
    }
    while (pTail!=pHead)
    {
        pCur = pHead;
        while (pCur!=pTail)
        {
            pPre = pCur;
            pCur = pCur->_pNext;

        }
        printf("%d->", pTail->_data);
        pTail = pPre;
    }
    printf("%d->NULL\n", pTail->_data);

//递归实现
#if 0
    if(pHead->_pNext)
    {
        PrintSListFromTail2Head(pHead->_pNext);
    }
    printf("->%d", pHead->_data);

#endif
}

删除链表的非尾结点,要求:不能遍历链表
void DeleteListNotTailNode(PNode pos)
{
    PNode pNext = NULL;
    pNext = pos->_pNext;
    pos->_data = pNext->_data;
    pos->_pNext = pNext->_pNext;
    free(pNext);
    pNext = NULL;
}

在链表pos位置前插入值到data的结点
/*在链表后边插入,然后将pos的值给后边的,再将值给pos*/
void InesrtPosFront(PNode pos, DataType data)
{
    PNode pNext = BuySListNode(data);
    pNext->_pNext = pos->_pNext;
    pos->_pNext = pNext;
    pNext->_data = pos->_data;
    pos->_data = data;
}

查找链表的中间结点,要求只能遍历一次链表
/*定义两个指针,一个一次走两步,一个走一步*/
PNode FindMiddleNode(PNode pHead)
{
    PNode pFast = pHead;
    PNode pSlow = pHead;
    if (NULL == pHead)
    {
        return NULL;
    }
    else if (NULL == pHead->_pNext)
    {
        return pHead;
    }
    else
    {
        while (pFast&&pFast->_pNext)
        {
            pFast = pFast->_pNext->_pNext;
            pSlow = pSlow->_pNext;
        }
        return  pSlow;
    }
}

查找链表的倒数第K个结点,要求只能遍历一次链表
PNode FindLastKNode(PNode pHead, int K)
{
    PNode pSlow = pHead;
    PNode pFast = pHead;
    if (NULL == pHead || K <= 0)
    {
        return NULL;
    }
    while (K--)
    {
        pFast = pFast->_pNext;
    }
    while (pFast)
    {
        pFast = pFast->_pNext;
        pSlow = pSlow->_pNext;
    }

    return pSlow;
}

// 删除链表的倒数第K个结点,要求只能遍历一次链表

void DeleteLastKNode(PNode pHead, int K)
{
    PNode pSlow = pHead;
    PNode pFast = pHead;
    PNode pPre = NULL;
    if (NULL == pHead || K <= 0)
    {
        return;
    }
    while (K--)
    {
        pFast = pFast->_pNext;
    }
    while (pFast)
    {
        pFast = pFast->_pNext;
        pPre = pSlow;
        pSlow = pSlow->_pNext;
    }
    pPre->_pNext = pSlow->_pNext;
    free(pSlow);
    pSlow = NULL;

}

用单链表实现约瑟夫环
void JosephCircle(PNode* pHead, const int M)
{
    PNode pCur = NULL;
    PNode pDel = NULL;
    int count = 0 ;
    assert(pHead);
    if (NULL == *pHead|| M <= 0)
    {
        return;
    }
    pCur = *pHead;
    //先遍历链表,让尾指向头
    while (pCur->_pNext)
    {
        pCur = pCur->_pNext;
    }
    pCur->_pNext = *pHead;
    pCur = *pHead;
    while ((pCur)->_pNext != pCur)
    {
        count = M;
        while (--count)                     //为什么时--M
        {
            pCur = pCur->_pNext;
        }
        //删节点
        pDel = pCur->_pNext;
        pCur->_data = pDel->_data;
        pCur->_pNext = pDel->_pNext;
        free(pDel);
        pDel = NULL;

    }
    //解环
    pCur->_pNext = NULL;

    SListPrint(pCur);
}

链表的逆置–三个指针

void ReverseSList(PNode* pHead)
{
    PNode pPre = NULL;
    PNode pCur = NULL;
    PNode pNext = NULL;
    assert(pHead);
    pCur = *pHead;
    while (pCur)
    {
        pNext = pCur->_pNext;
        pCur->_pNext = pPre;
        pPre = pCur;
        pCur = pNext;
    }
    *pHead = pPre;
}

链表的逆置–头插法

PNode ReverseSListOP(PNode pHead)
{
    PNode pCur = NULL;
    PNode pNewNode= NULL;
    if (NULL == pHead || NULL == pHead->_pNext)
        return NULL;

    while (pHead)
    {   
        pCur = pHead;
        pHead = pCur->_pNext;
        pCur->_pNext = pNewNode;
        pNewNode = pCur;
    }
    pHead = pCur;

    return pHead;
}

用冒泡排序思想对单链表进行排序

void BubbleSort(PNode pHead)
{
    PNode pTail = NULL;
    PNode pCur = pHead;
    int flag = 0;
    if (pHead == NULL || pHead->_pNext == NULL) 
    {
        return;
    }
    while (pTail != pHead)
    {
        pCur = pHead;
        flag = 0;
//这里为pCur->_pNext是为了防止if语句的中pCur->_pNext为空,如果为空第一次比较程序就会崩溃
        while (pCur->_pNext != pTail)           
        {
            if (pCur->_data < pCur->_pNext->_data)
            {
                DataType temp = pCur->_data;
                pCur->_data = pCur->_pNext->_data;
                pCur->_pNext->_data = temp;
                flag = 1;
            }

            pCur = pCur->_pNext;
        }
        pTail = pCur;
        if (0 == flag)
            break;
    }
}

合并两个有序单链表,合并后依然有序
PNode MergeSList(PNode pHead1, PNode pHead2)
{
    PNode pNewHead = NULL;
    PNode pCur = NULL;

    if (!pHead1)
        return pHead2;
    if (!pHead2)
        return pHead1;
    if (pHead1->_data >= pHead2->_data)
    {
        pCur = BuySListNode(pHead2->_data);
        pHead2 = pHead2->_pNext;
        pNewHead = pCur;
    }
    else if (pHead1->_data < pHead2->_data)
    {
        pCur = BuySListNode(pHead1->_data);
        pHead1 = pHead1->_pNext;
        pNewHead = pCur;
    }

    while (pHead1&&pHead2)
    {
        if (pHead1->_data >= pHead2->_data)
        {
            pCur->_pNext = BuySListNode(pHead2->_data);
            pHead2 = pHead2->_pNext;
            pCur = pCur->_pNext;
        }
        else if (pHead1->_data < pHead2->_data)
        {
            pCur->_pNext = BuySListNode(pHead1->_data);
            pHead1 = pHead1->_pNext;
            pCur = pCur->_pNext;
        }
    }
    while (pHead1)
    {
        pCur->_pNext = BuySListNode(pHead1->_data);
        pHead1 = pHead1->_pNext;
        pCur = pCur->_pNext;
    }
    while (pHead2)
    {
        pCur->_pNext = BuySListNode(pHead2->_data);
        pHead2= pHead2->_pNext;
        pCur = pCur->_pNext;
    }

    return pNewHead;
}

判断两个单链表是否相交—链表不带环
int IsSListCross(PNode pHead1, PNode pHead2)
{
    if (NULL == pHead1 || NULL == pHead2)
        return 0;
    //找到链表的最后一个节点
    while (pHead1->_pNext)
    {
        pHead1 = pHead1->_pNext;
    }
    while (pHead2->_pNext)
    {
        pHead2 = pHead2->_pNext;
    }
    if (pHead1 == pHead2)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

求两个单链表相交的交点—链表不带环
/*先让长的链表遍历size1-size2,再让两个链表一起遍历,
            当pCur1==pCur2时,两链表相交*/
PNode GetCorssNode(PNode pHead1, PNode pHead2)
{
    if (NULL == pHead1 || NULL == pHead2)
        return NULL;
    int size1 = 0;
    int size2 = 0;
    int gap = 0;
    PNode pCur1 = pHead1;
    PNode pCur2 = pHead2;
    while (pCur1)
    {
        pCur1 = pCur1->_pNext;
        size1++;
    }
    while (pCur2)
    {
        pCur2 = pCur2->_pNext;
        size2++;
    }
    gap = size1 - size2;
    pCur1 = pHead1; pCur2 = pHead2;
    if (gap > 0)
    {
        while (gap--)
        {
            pCur1 = pCur1->_pNext;
        }
    }
    else
    {
        while (gap++)
        {
            pCur2 = pCur2->_pNext;
        }
    }
    while (pCur1 != pCur2)
    {
        pCur1 = pCur1->_pNext;
        pCur2 = pCur2->_pNext;
    }
    return pCur2;
}

测试程序
void TestInterview()
{
    PNode pHead1, pHead2,pCur;

    SListInit(&pHead1);
    SListPushBlack(&pHead1, 1);
    SListPushBlack(&pHead1, 5);
    SListPushBlack(&pHead1, 9);
    SListPushBlack(&pHead1, 3);
    SListPushBlack(&pHead1, 6);
    SListPushBlack(&pHead1, 34);
    SListPrint(pHead1);
    SListInit(&pHead2);
    SListPushBlack(&pHead2, 2);
    SListPushBlack(&pHead2, 4);

    pHead2->_pNext->_pNext = SListFind(pHead1,6);
    SListPrint(pHead2);
    pCur = GetCorssNode(pHead1, pHead2);
    //int ret = IsSListCross(pHead1, pHead2);


    //SListPushBlack(&pHead2, 6);
    //SListPushBlack(&pHead2, 34);
    //SListPrint(pHead2);


    //pCur = MergeSList(pHead1, pHead2);
    //SListPrint(pCur);

    //PrintSListFromTail2Head(pHead);
    //pCur = SListFind(pHead, 6);
    //DeleteListNotTailNode(pCur);
    //InesrtPosFront(pCur, 5);
    //SListPrint(pHead);

    /*pCur = FindMiddleNode(pHead);*/
    //pCur = FindLastKNode(pHead, 3);

    //DeleteLastKNode(pHead, 3);
    //SListPrint(pHead);

    //JosephCircle(&pHead, 3);

    //ReverseSList(&pHead);
    /*SListPrint(pHead);

    pHead = ReverseSListOP(pHead);
    SListPrint(pHead);*/

    /*BubbleSort(pHead);
    SListPrint(pHead);*/
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LYJwonderful/article/details/79958779

常见的链表面试题大汇总:

常见的链表面试题大汇总: 源代码下载链接 1,创建一个链表结点 2,遍历链表中的所有结点 3,倒序打印链表 4,往链表末尾添加结点 5,往链表前端添加结点,6,获取链表的节点数目 7,销...
  • mengni123321
  • mengni123321
  • 2015年09月05日 20:57
  • 510

【数据结构】链表的原理及与其相关的常见面试题总结

链表是一种数据结构,和数组同级。比如,Java中我们使用的ArrayList,其实现原理是数组。而LinkedList的实现原理就是链表了。链表在进行循环遍历时效率不高,但是插入和删除时优势明显。下面...
  • jianyuerensheng
  • jianyuerensheng
  • 2016年06月06日 09:49
  • 1754

链表面试题总结(一)

基于上一次写的链表,现在,我们来讨论下面这些问题。1.链表的冒泡排序 2.删除无头非尾节点 3.反转链表 4.在当前节点前插入一个数据x 5.查找链表的中间节点。 6.删除单链表的倒数第K个...
  • qq_26768741
  • qq_26768741
  • 2016年06月11日 12:06
  • 5433

链表面试题 解法总结

从尾打印链表 1 用递归的方法,如果当前节点不为空,继续调打印函数传过去的参数下一个节点。 If(PNode) {   Print_list(PNode->PNext);   Printf(“%d->...
  • sdoyuxuan
  • sdoyuxuan
  • 2017年04月04日 15:10
  • 759

单链表面试题集合

1、找出单链表的倒数第K个元素(仅允许遍历一遍链表)      使用指针追赶的方法。定义两个指针fast和slow,fast先走K步,然后fast和slow同时继续走。当fast到链表尾部时,sl...
  • kqZhu
  • kqZhu
  • 2017年03月17日 10:10
  • 2513

常见链表面试题

简单LinkedList 的java代码实现: public class LinkedListNode { public int value; public LinkedListNode n...
  • tanglinghui
  • tanglinghui
  • 2012年05月30日 23:31
  • 3337

【面试】链表常见试题

链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力。链表的操作也离不开指针,指针又很容易导致出错。综合多方面的原因,链表题目在...
  • baidu_39511645
  • baidu_39511645
  • 2017年11月12日 20:00
  • 107

数组的常见面试题

1排序1.1冒泡1.2选择1.3插入1.4希尔1.5快速2查找2.1线性查找2.2二分查找2.2.1迭代2.2.2递归3求最值3.1求最大值3.2求最小值3.3求次最大值3.4求次最小值4归并4.1有...
  • linux_wgl
  • linux_wgl
  • 2016年05月26日 15:00
  • 1070

链表常见面试题-C语言实现

前面的博客已经介绍过了实现链表的一些相关的功能,所以在这里就不对链表多加解释说明了。 对于链表相关面试题这里解释几个有特点的题: 1.对于求查找链表的中间结点,要求只能遍历一次链表? 方式:使用两个指...
  • IT_iverson
  • IT_iverson
  • 2017年08月03日 14:03
  • 1779

单链表面试题——基础篇

1.比较顺序表和链表的优缺点,说说它们分别在什么场景下使用 总结: 1.若线性表需要频繁查找,很少进行插入、删除操作,宜采用顺序存储结构。若需要频繁插入和删除时,宜采用单链表结构; 2.当线性表...
  • sssssuuuuu666
  • sssssuuuuu666
  • 2017年06月13日 17:37
  • 629
收藏助手
不良信息举报
您举报文章:链表的常见面试题
举报原因:
原因补充:

(最多只允许输入30个字)