关于单链表面试的那些事儿

在这里,我把所有关于单链表的基本操作,以及面试单链表时经常遇到的操作全部实现了一遍(正文分两大部分,第一部分为单链表基本操作,第二部分为面试题)相信大家在面试时只要是问道关于单链表的题目,肯定能派上用场哦!好了,废话不多说,直接上干货。

#include<assert.h>

#define NULL 0

#include<malloc.h>

#include<stdio.h>

typedef int DataType;

typedef struct Node

{

   struct Node*next;

   struct Node*random;

   DataType data;

}Node, *pNode;

//****************************//

//***单链表基本操作****//

//****************************//

void InitList(pNode *pHead);//初始化

pNode BuyNode(DataType data);//构造一个节点

void PushBack(pNode *pHead, DataType data);//尾插

void PopBack(pNode *pHead);//尾删

void PrintList(pNode pHead);//打印单链表

void PushFront(pNode *pHead, DataType data);//头插

void PopFront(pNode *pHead);//头删

pNode Find(pNode pHead, DataType data);//查找

void Insert(pNode pos, DataType data);//任意位置插入结点

void Delete(pNode *pHead, pNode pos);//任意位置删除结点

void Remove(pNode* pHead, DataType data); //删除为date节点

void RemoveAll(pNode* pHead, DataType data);//删除所有为data的结点

size_t size(pNode pHead); //求大小

pNode Front(pNode pHead); //返回尾节点

pNode Back(pNode pHead); //返回头节点

int Empty(pNode pHead); //判空

 

 

 

void InitList(pNode* pHead) //初始化链表

{

   assert(pHead);

   *pHead = NULL;

}

 

pNode BuyNode(DataType data) //构建一个结点

{

   pNode pTemp = (pNode)malloc(sizeof(Node));

   if (pTemp)

   {

      pTemp->data = data;

      pTemp->next = NULL;

   }

   return pTemp;

}

 

 

void PushBack(pNode *pHead, DataType data)//尾插,空链表和多个结点

{

   assert(pHead);

   if (NULL == *pHead)

   {

      *pHead = BuyNode(data);

   }

   else

   {

      pNode pCur = *pHead;

      while (pCur->next)

      {

        pCur = pCur->next;

      }

      pCur->next = BuyNode(data);

   }

}

 

void PopBack(pNode *pHead)//尾删,不存在、一个结点、多个结点

{

   assert(pHead);

   if (NULL == *pHead)

   {

      return;

   }

   else if (NULL == (*pHead)->next)

   {

      free(*pHead);

      *pHead = NULL;

   }

   else

   {

      pNode pCur = *pHead;

      pNode pPre = pCur;

      while (pCur->next)

      {

        pPre = pCur;

        pCur = pCur->next;

      }

      free(pCur);

      pPre->next = NULL;

   }

}

 

void PrintList(pNode pHead) //打印单链表

{

   pNode pCur = pHead;

   while (pCur)

   {

      printf("%d->", pCur->data);

      pCur = pCur->next;

   }

   printf("NULL\n");

}

 

void PushFront(pNode *pHead, DataType data) //头插

{

   assert(pHead);

   pNode pNewNode = BuyNode(data);

   if (pNewNode)

   {

      pNewNode->next = *pHead;

      *pHead = pNewNode;

 

   }

}

 

void PopFront(pNode *pHead) //头删

{

   pNode ps = NULL;

   assert(pHead);

   if (*pHead == NULL)

      return;

   else

   {

      ps = *pHead;

      *pHead = (*pHead)->next;

      free(ps);

   }

}

 

pNode Find(pNode pHead, DataType data) //查找一个节点

{

   assert(pHead);

   pNode PcurNode = pHead;

   while (PcurNode)

   {

      if (PcurNode->data == data)

      {

        return PcurNode;

      }

      PcurNode = PcurNode->next;

   }

   return NULL;

}

 

 

void Insert(pNode pos, DataType data) //任意位置插入节点

{

   pNode pNewNode = NULL;

   if (NULL == pos)

      return;

   pNewNode = BuyNode(data);

   pNewNode->next = pos->next;

   pos->next = pNewNode;

}

 

void Delete(pNode *pHead, pNode pos) //任意位置删除节点

{

   assert(*pHead);

   if (NULL == pHead&&NULL == pos)

      return;

   if (pos = *pHead)

   {

      *pHead = pos->next;

      free(pos);

   }

   else

   {

      pNode pPre = *pHead;

      while (pPre->next != pos)

      {

        pPre = pPre->next;

      }

      pPre->next = pos->next;

      free(pos);

   }

}

 

void Remove(pNode* pHead, DataType data) //删除为data的结点

{

   assert(pHead);

   Delete(pHead, Find(*pHead, data));

}

void RemoveAll(pNode* pHead, DataType data) //删除所有为data的结点

 

{

   assert(pHead);

   pNode pCurNode = NULL;

   pNode pPreNode = NULL;

   pPreNode = *pHead;

   pCurNode = pPreNode->next;

   while (pCurNode)

   {

      if (pCurNode->data = data)

      {

        pPreNode->next = pCurNode->next;

        free(pCurNode);

        pCurNode = pPreNode->next;

      }

      else

      {

        pCurNode = pCurNode->next;

      }

   }

   if ((*pHead)->data = data)

   {

      pCurNode = *pHead;

      *pHead = (*pHead)->next;

      free(pCurNode);

   }

}

 

 

pNode Back(pNode pHead) //返回尾节点

{

   assert(pHead);

   pNode pCurNode = pHead;

   if (NULL == pHead)

      return NULL;

   while (pCurNode->next)

 

      pCurNode = pCurNode->next;

 

   return pCurNode;

}

 

 

size_t size(pNode pHead) //求大小

{

   pNode pCurNode = pHead;

   size_t Count= 0;

   while (pCurNode)

   {

      Count++;

      pCurNode = pCurNode->next;

   }

   return Count;

}


//************链表常见面试题****************//

//************链表常见面试题****************//

//************链表常见面试题****************//

voidPrintListFromTailtoHeda(pNode pHead);//从尾到头打印单链表中的内容

void DelNotTailNode(pNode pos);//删除一个单链表的非尾节电,不能遍历单链表(腾讯笔试题)

void InsertNotHead(pNode pos, DataType data);//在无头单链表的一个非头结点前插入一个结点

pNode JosephCircle(pNode pHead, size_t M);//单链表实现约瑟夫环

pNode Reverse(pNode pHead);//逆制单链表(way1)

pNode Reverse_t(pNode pHead);//逆制单链表(way2)

void Bubble(pNode pHead);//单链表冒泡排序

pNode FindMidNode(pNode pHead);//查找单链表中间结点

pNode FindLastKNode(pNode pHead, size_t K);//查找单链表倒数第K个结点

void DeleteLastKNode(pNode* pHead, size_t K);//删除单链表倒数第K个结点

pNode Combine(pNode pHead1, pNode pHead2);//合并两个有序单链表

int IsTailCross(pNode pHead1, pNode pHead2);//判断两个单链表是否相交,

pNode GetTailCross(pNode pHead1, pNode pHead2);//求两单链表相交的交点

pNode HasCircle(pNode pHead);//判断单链表是否带环

size_t GetCircleLen(pNode pMeetNode);//若单链表带环,则获取环的长度

pNode GetEnterNode(pNode pHead, pNode pMeetNode);//获取带环单链表的入口点

intHasCircleWithCircle(pNode pHead1, pNode pHead2);//判断两个链表是否相交,若相交,求交点(假设链表可能带环)

pNode CopyComplexList(pNode pHead);//拷贝复杂链表

///

voidPrintListFromTailtoHeda(pNode pHead) //从尾到头打印单链表中的内容

{

   if (pHead)

   {

      PrintListFromTailtoHeda(pHead->next);

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

   }

}

 

 

void DelNotTailNode(pNode pos) //删除一个单链表的非尾节电,不能遍历单链表(腾讯笔试题)

{

   pNode pDelNode = NULL;

   if (NULL == pos || NULL == pos->next)

      return;

   else

   {

      pDelNode = pos->next;

      pos->next = pDelNode->next;

      pos->data = pDelNode->data;

      free(pDelNode);

   }

}

 

 

void InsertNotHead(pNode pos, DataType data) //在无头单链表的一个非头结点前插入一个结点

{

   pNode pNewNode = NULL;

   if (NULL == pos)

      return;

   pNewNode = BuyNode(pos->data);

   if (pNewNode)

   {

      pNewNode->next = pos->next;

      pos->next = pNewNode;

      pos->data = data;

   }

}

 

pNode JosephCircle(pNode pHead, size_t M) //单链表实现约瑟夫环

{

   assert(pHead);

   pNode pCurNode = pHead, pDelNode;

   if (NULL == pHead)

      return NULL;

   while (pCurNode != pCurNode->next)

   {      //1.报数 

      size_t  Count = M;

      while (--Count)

      {

         pCurNode= pCurNode->next;

      }

      //2.删除结点

      pDelNode = pCurNode->next;

      pCurNode->data = pDelNode->data;

      pCurNode->next = pDelNode->next;

      free(pDelNode);

   }

   return pCurNode;

}

 

pNode Reverse(pNode pHead) //逆制单链表(way1)

{

   assert(pHead);

   pNode pPre = NULL;

   pNode pCur = NULL;

   pNode pNext = NULL;

   if (NULL == pHead&&NULL == pHead->next)

      return pHead;

   pPre = pHead;

   pCur = pPre->next;

   pNext = pCur->next;

   while (pNext)

   {

      pCur->next = pPre;

      pPre = pCur;

      pCur = pNext;

      pNext = pNext->next;

   }

   pCur->next = pPre;

   pHead->next = NULL;

   return pCur;

}

pNode Reverse_t(pNode pHead) //逆制单链表(way2)

 

{

   assert(pHead);

   pNode pPre = NULL;

   pNode pCur = NULL;

   pNode pNewHead = NULL;

   if (NULL == pHead || NULL == pHead->next)

      return pHead;

   pPre = pHead;

   pCur = pPre->next;

   while (pCur)

   {

      pPre->next = pNewHead;

      pNewHead = pPre;

      pPre = pCur;

      pCur = pCur->next;

   }

   pPre->next = pNewHead;

   pNewHead = pPre;

   return pNewHead;

}

 

void Bubble(pNode pHead) //单链表冒泡排序

 

{

   assert(pHead);

   pNode pPre = NULL;

   pNode pCur = NULL;

   pNode pTail = NULL;

   int flag = 1;

   if (NULL == pHead || NULL == pHead->next)

      return;

   while (pHead != pTail)

   {

      flag = 1;

      pPre = pHead;

      pCur = pPre->next;

      while (pCur != pTail)

      {

        if (pPre->data > pCur->data)

        {

           DataType temp = pPre->data;

           pPre->data = pCur->data;

           pCur->data = temp;

           flag= 0;

        }

        pPre = pCur;

        pCur = pCur->next;

      }

      pTail = pPre;

      if (flag)

        return;

   }

}

pNode FindMidNode(pNode pHead)

{

   pNode pSlow = pHead;

   pNode pFast = pHead;

   while (pFast && pFast->next)//结点偶数个Fast先空,结点计数个,Fast->next先空;

   {

      pSlow = pSlow->next;

      pFast = pFast->next->next;

   }

   return pSlow;//返回后一个结点,(结点为偶数个,则中间结点有两个)

}

 

pNode FindLastKNode(pNode pHead, size_t K)

{

   assert(pHead);

   pNode pFast = pHead;

   pNode pSlow = pHead;

   if (NULL == pHead || 0 == K)

      return NULL;

   while (K--)

   {

      if (NULL == pFast)

        return NULL;

      pFast = pFast->next;

   }

   while (pFast)

   {

      pFast = pFast->next;

      pSlow = pSlow->next;

   }

   return pSlow;

}

 

pNode Combine(pNode pHead1, pNode pHead2)

{

   pNode p1 = pHead1;

   pNode p2 = pHead2;

   pNode pNewHead = NULL;

   pNode pTailNode = NULL;

   if (NULL == pHead1)

      return pHead2;

   if (NULL == pHead2)

      return pHead1;

   if (p1->data < p2->data)

   {

      pNewHead = p1;

      p1 = p1->next;

      pTailNode = p1;

   }

   else

   {

      pNewHead = p2;

      p2 = p2->next;

      pTailNode = p2;

   }

   while (p1&&p2)

   {

      if (p1->data < p2->data)

      {

        pTailNode->next = p1;

        p1 = p1->next;

      }

      else

      {

        pTailNode->next = p2;

        p2 = p2->next;

      }

      pTailNode = pTailNode->next;

   }

   if (p1)

      pTailNode->next = p1;

   if (p2)

      pTailNode->next = p2;

   return pNewHead;

}

 

/

int IsTailCross(pNode pHead1, pNode pHead2)

{

   pNode pTailNode1 = pHead1;

   pNode pTailNode2 = pHead2;

   if (NULL == pHead1 || NULL == pHead2)

      return 0;

   while (pTailNode1->next)

   {

      pTailNode1 = pTailNode1->next;

   }

 

   while (pTailNode2->next)

   {

      pTailNode2 = pTailNode2->next;

   }

 

   if (pTailNode1 == pTailNode2)

      return 1;

 

   return 0;

}

 

/

pNode GetTailCross(pNode pHead1, pNode pHead2)

{

  

 

   size_t Count1 = 0;

   size_t Count2 = 0;

   int Gap = 0;

   pNode pL1 = pHead1;

   pNode pL2 = pHead2;

 

   if (0==(IsTailCross(pHead1, pHead2)))

      return NULL;

   Count1 = size(pHead1);

   Count2 = size(pHead2);

   Gap = Count1 - Count2;

   if (Gap > 0)

   {

      while (Gap--)

      pL1=pL1->next;

   }

   else

   {

      while (Gap++)

        pL2 = pL2->next;

   }

   while (pL1 != pL2)

   {

      pL1 = pL1->next;

      pL2 = pL2->next;

   }

   return pL1;

}

 

/

pNode HasCircle(pNode pHead)

{

   assert(pHead);

   pNode pFast = pHead;

   pNode pSlow = pHead;

   while (pFast &&pFast->next)

   {

      pFast = pFast->next->next;

      pSlow = pSlow->next;

      if (pFast == pSlow)

        return pFast;

   }

   return NULL;

}

 

size_t GetCircleLen(pNode pMeetNode)

{

   pNode pCurNode = pMeetNode;

   size_t Count = 1;

   if (NULL == pMeetNode)

      return 0;

   while (pCurNode->next != pMeetNode)

   {

      Count++;

      pCurNode = pCurNode->next;

   }

   return Count;

}

 

pNode GetEnterNode(pNode pHead, pNode pMeetNode)

{

   pNode pM = pHead;

   pNode pN = pMeetNode;

   if (NULL == pHead || NULL == pMeetNode)

      return NULL;

   while (pM != pN)

   {

      pM = pM->next;

      pN =pN->next;

   }

   return pM;

}

 

intHasCircleWithCircle(pNode pHead1, pNode pHead2)

{

   pNode pL1 = pHead1;

   pNode pL2 = pHead2;

   pNode pMeetNode1 = HasCircle(pHead1);

   pNode pMeetNode2 = HasCircle(pHead2);

   if (NULL == pMeetNode1&&NULL == pMeetNode2)

   {

      while (pL1->next)

      {

        pL1 = pL1->next;

      }

      while (pL2->next)

      {

        pL2 = pL2->next;

      }

      if (pL1 == pL2)

        return 1;

   }

   else if (pMeetNode1&&pMeetNode2)

   {

      pNode pCurNode = pMeetNode1;

      while (pCurNode->next != pMeetNode1)

      {

        if (pCurNode = pMeetNode2)

           return 2;

        pCurNode = pCurNode->next;

      }

      if (pCurNode = pMeetNode2)

        return 2;

   }

   return 0;

}

 

//

pNode CopyComplexList(pNode pHead)

{

   pNode p1 = pHead;

   pNode p2 = NULL;

   pNode pNewNode = NULL;

   if (NULL == pHead)

      return NULL;

   while (p1)//1、插入结点

   {

      pNewNode = BuyNode(p1->data);

      assert(pNewNode);

      pNewNode->next = p1->next;

      p1->next = pNewNode;

      p1 = p1->next->next;

   }

   p1 = pHead;

   p2 = p1->next;

   while (p2->next)//2、随机域赋值

   {

      if (NULL == p1->random)

        p2->random = NULL;

      else

        p2->random = p1->random->next;

      p1 = p2->next;

      p2 = p1->next;

   }

   if (p1->random)

      p2->random = p1->random->next;

   else

      p2->random = NULL;

   p1 = pHead;

   p2 = p1->next;

   pNewNode = p2;

   while (p2->next)//3、拆分链表

   {

      p1->next = p2->next;

      p2->next = p1->next->next;

      p1 = p1->next;

      p2 = p2->next;

   }

   p2->next = NULL;

   return pNewNode;

}

 

//

//

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值