单链表及面试题

//.h

#pragma once
typedef int DataType;
typedef struct Node
{
 struct Node* _pNext;
 DataType _data;
}Node,*pNode;
typedef struct CListNode
{
 struct CListNode* _pNext;
 struct CListNode* _pRandom;
 DataType data;
}CListNode, *pCListNode;
void SListInit(pNode* pHead);// 链表初始化
pNode BuySListNode(DataType data); //创建新结点
void SListPushBack(pNode* pHead, DataType data);// 尾插
void printSList(pNode pHead);//打印单链表
void SListPopBack(pNode* pHead);//尾删
void SListPushFront(pNode* pHead, DataType data);//头插
void SListPopFront(pNode* pHead);//头删
pNode SListFind(pNode pHead, DataType data); //查找值为data的结点,返回该结点在链表中的位置
void SListInsert(pNode* pHead, pNode pos, DataType data);// 在链表pos位置后插入结点data
void SListErase(pNode* pHead, pNode pos);// 删除链表pos位置上的结点
void SListDestroy(pNode* pHead);// 销毁单链表
int SListSize(pNode pHead);// 求链表中结点的个数 
void SListClear(pNode* pHead);// 将链表中的结点清空
pNode SListBack(pNode pHead);// 获取链表中的最后一个结点,返回该结点的地址
//
///
void PrintListFromTailHead(pNode pHead);// 从尾到头打印单链表
void DeleteNotTailNode(pNode pos);//删除无头单链表的非尾结点,要求:不能遍历
void InsertPosFront(pNode pos, DataType data);//在无头单链表POS位置前插入值为data的结点
void JosephCircle(pNode* pHead, const int M);//用单链表模拟实现约瑟夫环
void BubbleSort(pNode pHead);// 使用冒泡排序方法对单链表进行排序
void ReverseSList(pNode* pHead);// 单链表的逆置--三个指针
void ReverseSLiseTop(pNode pHead);// 单链表的逆置--头插法
pNode MergeSList(pNode pHead1, pNode pHead2);// 合并两个有序链表,合并之后依然有序
pNode FindMiddleNode(pNode pHead);// 查找链表的中间结点,要求只能遍历一次链表
pNode FindLastKNode(pNode pHead, int k);// 查找链表的倒数第K个结点,要求只能遍历链表一次
pNode DeleteLastKNode(pNode pHead, int k);// 删除链表的倒数第K个结点,要求只能遍历链表一次
int IsCrossWithoutCircle(pNode pHead1, pNode pHead2);// 判断单链表是否相交?链表不带环
pNode GetCrossNode(pNode pHead1, pNode pHead2);// 求不带环单链表相交交点
pNode IsCircle(pNode pHead);// 判断链表是否带环
int GetCircleLen(pNode pHead);// 求环的长度
pNode GetEnterNode(pNode pHead, pNode pMeetNode);// 求环的入口点
int IsListCrossWithCircle(pNode pHead1, pNode pHead2);// 判断链表是否带环,链表可能带环
void CListNodeInit(pCListNode* pHead);// 复杂链表初始化
pCListNode BuyCListNode(DataType data);// 复杂链表获取结点
void CListNodePushBack(pCListNode *pHead, DataType data);//复杂链表的尾插
pCListNode CopyComplexList(pCListNode pHead);// 复杂链表的复制

//.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SListNode.h"
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//初始化
void SListInit(pNode* pHead)
{
 assert(pHead);
 *pHead = NULL;
}
//创建新结点
pNode BuySListNode(DataType data)
{
 pNode pNewNode = (pNode)malloc(sizeof(Node));
 if (NULL==pNewNode)
 {
  return NULL;
 }
 else
 {
  pNewNode->_data = data;
  pNewNode->_pNext = NULL;
 }
 return pNewNode;
}
//尾插
void SListPushBack(pNode* pHead, DataType data)
{
 assert(pHead);
 pNode pNewNode = BuySListNode(data);
 pNode pCur =*pHead;
 if (NULL==pCur)
 {
  *pHead= pNewNode;
  return;
 }
 while (pCur->_pNext)
 {
  pCur = pCur->_pNext;
 }
 pCur->_pNext = pNewNode;
}
void printSList(pNode pHead)//打印单链表
{
 pNode pCur = pHead;
 while (pCur)
 {
  printf("%d-->", pCur->_data);
  pCur = pCur->_pNext;
 }
 printf("NULL\n");
}
//尾删
void SListPopBack(pNode* pHead)
{
 assert(pHead);
 pNode pCur = *pHead;
 if (NULL==pCur)
 {
  return;
 }
 //一个节点
 if (NULL==pCur->_pNext)
 {
  pCur = NULL;
  free(pCur);
  return;
 }
 //多个节点
 while (pCur->_pNext->_pNext)
 {
  pCur = pCur->_pNext;
 }
 free(pCur->_pNext);
 pCur->_pNext = NULL;
}
//头插
void SListPushFront(pNode* pHead, DataType data)
{
 assert(pHead);
 pNode pNewNode = BuySListNode(data);
  if (NULL==pNewNode)
 {
  return;
 }
 pNewNode->_pNext = *pHead;
 *pHead = pNewNode;
}
//头删
void SListPopFront(pNode* pHead)
{
 assert(pHead);
 pNode pCur = *pHead;
 if (NULL==*pHead)
 {
  return;
 }
 else
 {
  *pHead = pCur->_pNext;
  free(pCur);
 }
}
// 查找值为data的结点,返回该结点在链表中的位置
pNode SListFind(pNode pHead, DataType data)
{
 assert(pHead);
 pNode pCur = pHead;
 while (pCur)
 {
  if (pCur->_data == data)
  {
   return pCur;
  }
  pCur = pCur->_pNext;
 }
 return NULL;
}
// 在链表pos位置后插入结点data
void SListInsert(pNode* pHead, pNode pos, DataType data)
{
 assert(pHead);
 pNode pCur = *pHead;
 pNode pNewNode = BuySListNode(data);
 if (NULL==pHead || NULL==pos)
 {
  return;
 }
 while (pCur)
 {
  if (pCur == pos)
  {
   pNewNode->_pNext = pos->_pNext;
   pos->_pNext = pNewNode;
  }
  pCur = pCur->_pNext;
 }
}
 //删除链表pos位置上的结点
void SListErase(pNode* pHead, pNode pos)
{
 assert(pHead);
 pNode pCur = *pHead;
 if (*pHead == NULL)
 {
  return;
 }
  if (pCur == pos)//一个结点
  {
   *pHead = pos->_pNext;
   free(pos);
   pos= NULL;
  }
  else
  {
   while (pCur && pCur->_pNext != pos)
   {
    pCur = pCur->_pNext;
   }
   if (pCur != NULL)
   {
    pCur->_pNext = pos->_pNext;
    free(pos);
    pos = NULL;
   }
  }
}
// 销毁单链表
void SListDestroy(pNode* pHead)
{
 assert(pHead);
 pNode pCur = *pHead;
 while (pCur)
 {
  pCur = pCur->_pNext;
  free(pCur);
  pCur = NULL;
 }
 *pHead = NULL;
}
// 求链表中结点的个数
int SListSize(pNode pHead)
{
 assert(pHead);
 int count = 0;
 pNode pCur = pHead;
 while (pCur)
 {
  count++;
  pCur = pCur->_pNext;
 }
 return count;
}
// 将链表中的结点清空
void SListClear(pNode* pHead)
{
 assert(pHead);
 pNode pCur = *pHead;
 while (pCur)
 {
  pCur->_pNext = *pHead;
  free(pCur);
 }
 free(*pHead);
}
//void SListClear(pNode* pHead)
//{
// assert(pHead);
// SListDestoy(pHead);
//}
// 获取链表中的最后一个结点,返回该结点的地址
pNode SListBack(pNode pHead)
{
 assert(pHead);
 pNode pCur = pHead;
 if (NULL == pHead)
 {
  return;
 }
 while (pCur->_pNext)
 {
  pCur = pCur->_pNext;
 }
 return pCur;
}
/

//面试题
void PrintFromTailHead(pNode pHead)// 从尾到头打印单链表
{
 if (pHead)
 {
  PrintFromTailHead(pHead->_pNext);
  printf("%d-->", pHead->_data);
 }
}
//删除无头单链表的非尾结点,要求:不能遍历
void DeleteNotTailNode(pNode pos)
{
 pNode pCur = NULL;
 if (NULL == pos || NULL == pos->_pNext)
 {
  return;
 }
 pCur = pos->_pNext;
 pos->_data = pCur->_data;
 pos->_pNext = pCur->_pNext;
 free(pCur);
}
//在无头单链表POS位置前插入值为data的结点
void InsertPosFront(pNode pos, DataType data)
{
 if (NULL == pos)
 {
  return;
 }
 pNode pNewpNode = BuySListNode(pos->_data);
 pNewpNode->_pNext = pos->_pNext;
 pos->_data = data;
 pos->_pNext = pNewpNode;
}
//用单链表模拟实现约瑟夫环
void JosephCircle(pNode* pHead, const int M)
{
 assert(pHead);
 pNode pCur = NULL;
 int count = 0;
 //构环
  pCur = *pHead;
 while (pCur->_pNext)
 {
  pCur = pCur->_pNext;
 }
 pCur->_pNext = *pHead;
 //删结点
 pCur = *pHead;
 while (pCur->_pNext!= pCur)
 {
  count = M;//报数
  while (--count)
  {
   pCur = pCur->_pNext;
  }
  pCur->_data = pCur->_pNext->_data;
  pCur->_pNext = pCur->_pNext->_pNext;
 }
 //解环
 pCur->_pNext = NULL;
 *pHead = pCur;
}
// 使用冒泡排序方法对单链表进行排序
//冒泡排序算法的运作如下:
//1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
//
//2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
//
//3.针对所有的元素重复以上的步骤,除了最后一个。
//
//4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
void BobbleSort(pNode pHead)
{
 int i = 0;
 int j = 0;
 int ret = 0;
 int tmp = 0;
 pNode pCur = NULL;
 if (NULL == pHead)
 {
  return;
 }
 ret = SListSize(pHead);
 for (i = 0; i < ret - 1; i++)
 {
  pCur = pHead;
  for (j = 0; j < ret - 1 - i; j++)
  {
   if (pCur->_data > pCur->_pNext->_data)
   {
    tmp = pCur->_data;
    pCur->_data = pCur->_pNext->_data;
    pCur->_pNext->_data = tmp;
   }
   pCur = pCur->_pNext;
  }
 }
}
// 单链表的逆置--三个指针
void ReverseSList(pNode* pHead)
{
 assert(pHead);
 pNode pPre = NULL;
 pNode pCur = NULL;
 pNode pNext = NULL;
 if (NULL == *pHead || NULL==(*pHead)->_pNext)//边界检测
 {
  return;
 }
 pCur = *pHead;
 while (pCur)
 {
  pNext=pCur->_pNext;
  pCur->_pNext = pPre;
  pPre = pCur;
  pCur = pNext;
 }
 *pHead=pPre;
}
// 单链表的逆置--头插法
void ReverseSListTop(pNode pHead)
{
 assert(pHead);
 pNode pNewNode = NULL;
 if (NULL == pHead)
 {
  return;
 }
 pNode pCur = pHead;
 while (pCur)
 {
  SListPushFront(&pNewNode, pCur->_data);
  pCur = pCur->_pNext;
 }
 return pNewNode;
}
// 合并两个有序链表,合并之后依然有序
pNode MergeSList(pNode pHead1, pNode pHead2)
{
 pNode pNewNode = NULL;
 pNode pTailNode = NULL;
 pNode pCur1 = pHead1;
 pNode pCur2 = pHead2;
 if (NULL == pHead1)//链表1为空的话返回链表2 
  return pHead2;
 if (NULL == pHead2)//链表2为空的话返回链表1
  return pHead1;
 //两个链表都不为空
 if (pCur1->_data <= pCur2->_data)//比较两个头结点大小
 {
  pNewNode = pCur1;
  pCur1 = pCur1->_pNext;
 }
 else
 {
  pNewNode = pCur2;
  pCur2 = pCur2->_pNext;
 }
 pTailNode = pNewNode;
 while(pCur1 && pCur2)//合并后面结点
 {
  if (pCur1->_data <= pCur2->_data)
  {
   pTailNode->_pNext = pCur1;
   pCur1 = pCur1->_pNext;
   pTailNode = pTailNode->_pNext;
  }
  else
  {
   pTailNode->_pNext = pCur2;
   pCur2 = pCur1->_pNext;
   pTailNode = pTailNode->_pNext;
  }
 }
 if (NULL==pCur1)
 {
  pTailNode->_pNext = pCur2;
 }
 if (NULL==pCur2)
 {
  pTailNode->_pNext = pCur1;
 }
 return pNewNode;
}
// 查找链表的中间结点,要求只能遍历一次链表
pNode FindMiddleNode(pNode pHead)
{
 assert(pHead);
 pNode pFast = pHead;
 pNode pSlow = pHead;
 if (NULL == pHead)
 {
  return;
 }
 while (pFast && pFast->_pNext)
 {
  pSlow = pSlow->_pNext;
  pFast = pFast->_pNext->_pNext;
 }
 return pSlow;
}
// 查找链表的倒数第K个结点,要求只能遍历链表一次
pNode FindLastKNode(pNode pHead, int k)
{
 assert(pHead);
 pNode pFast = pHead;
 pNode pSlow = pHead;
 if (NULL == pHead || k<0)
 {
  return;
 }
 while (k--)//让pFast先走k步
 {
  if (NULL == pFast)//k大于链表中结点的个数
  {
   return;
  }
  pFast = pFast->_pNext;
 }
 //两个指针同时走
 while (pFast)
 {
  pSlow = pSlow->_pNext;
  pFast = pFast->_pNext;
 }
 return pSlow;
}
// 删除链表的倒数第K个结点,要求只能遍历链表一次
pNode DeleteLastKNode(pNode pHead, int k)
{
 assert(pHead);
 pNode pCur = NULL;
 pNode pCur1 = NULL;
 pCur=FindLastKNode(pHead, k);
 if (NULL == pHead)
 {
  return;
 }
 //if删除头结点
 if (pCur == pHead)
 {
  pHead = pCur->_pNext;
  free(pCur);
  pCur = NULL;
  return NULL;
 }
 //删除其它结点
 else
 {
  pCur1 = pHead;
  if (pCur1->_pNext != pCur)
  {
   pCur1 = pCur1->_pNext;
  }
  pCur1->_pNext = pCur->_pNext;
  free(pCur);
  pCur = NULL;
  return NULL;
 }
}
// 判断单链表是否相交?链表不带环
int IsCrossWithoutCircle(pNode pHead1, pNode pHead2)
{
 pNode pCur1 = pHead1;
 pNode pCur2 = pHead2;
 int size = 0;
 if (NULL == pHead1 || NULL == pHead2)
 {
  return;
 }
 size = SListSize(pHead1) - SListSize(pHead2);
 if (size > 0)
 {
  while (size--)
  {
   pCur1 = pCur1->_pNext;
  }
  while (pCur1 && pCur2)
  {
   if (pCur1 == pCur2)
   {
    return pCur1;
   }
   pCur1 = pCur1->_pNext;
   pCur2 = pCur2->_pNext;
  }
  return NULL;
 }
 else if (size < 0)
 {
  while (size++)
  {
   pCur2 = pCur2->_pNext;
  }
  while (pCur1 && pCur2)
  {
   if (pCur1 == pCur2)
   {
    return pCur1;
   }
   pCur1 = pCur1->_pNext;
   pCur2 = pCur2->_pNext;
  }
  return NULL;
 }
 else
 {
  while (pCur1 && pCur2)
  {
   {
    return pCur1;
   }
   pCur1 = pCur1->_pNext;
   pCur2 = pCur2->_pNext;
  }
  return NULL;
 }
}
// 求不带环单链表相交交点
pNode GetCrossNode(pNode pHead1, pNode pHead2)
{
 pNode pCur = NULL;
 pCur = IsCrossWithoutCircle(pHead1, pHead2);
 return pCur;
}
// 判断链表是否带环
pNode IsCircle(pNode pHead)
{
 assert(pHead);
 pNode pFast = NULL;
 pNode pSlow = NULL;
 if (NULL == pHead)
 {
  return;
 }
 pFast = pHead;
 pSlow = pHead;
 while (pFast && pFast->_pNext)
 {
  pFast->_pNext->_pNext;
  pSlow->_pNext;
  if (pFast == pSlow)
  {
   return pSlow;
  }
 }
 return NULL;
}
// 求环的长度
int GetCircleLen(pNode pHead)
{
 assert(pHead);
 pNode pMeetNode = IsCircle(pHead);
 pNode pCur = pMeetNode;
 if (NULL == pHead)
 {
  return;
 }
 int count = 0;
 while (pCur->_pNext != pMeetNode)
 {
  count++;
  pCur = pCur->_pNext;
 }
 return count;
}
// 求环的入口点
pNode GetEnterNode(pNode pHead, pNode pMeetNode)
{
 assert(pHead);
 pMeetNode = IsCircle(pHead);
 pNode pCur = pHead;
 if (NULL == pHead)
 {
  return;
 }
 while (pCur != pMeetNode)
 {
  pCur = pCur->_pNext;
  pMeetNode = pMeetNode->_pNext;
 }
 return pCur;
}
// 判断链表是否带环,链表可能带环 ,相交返回交点
int IsListCrossWithCircle(pNode pHead1, pNode pHead2)
{
 pNode pCur1 = IsCircle(pHead1);
 pNode pCur2 = IsCircle(pHead2);
 //两个链表都不带环
 if (NULL == pCur1 && NULL == pCur2)
 {
  pNode pMeetNode = IsCrossWithoutCircle(pHead1, pHead2);
  return pMeetNode;
 }
 //两个链表都带环(环内,环外)
 else if (pCur1 != NULL && pCur2 != NULL)
 {
  pNode pMeetNode = NULL;
  pNode pEnterNode1 = GetEnterNode(pHead1, pMeetNode);
  pNode pEnterNode2 = GetEnterNode(pHead2, pMeetNode);
  int count1 = 1;
  int count2 = 1;
  int size = 0;
  pNode pCur3 = pHead1;
  pNode pCur4 = pHead2;
  //环外相交
  if (pEnterNode1 == pEnterNode2)
  {
   while (pHead1 != pEnterNode1)
   {
    count1++;
    pCur3 = pCur3->_pNext;
   }
   while (pHead2 != pEnterNode2)
   {
    count2++;
    pCur4 = pCur4->_pNext;
   }
   size = count1 - count2;
   if (size > 0)
   {
    while (size--)
    {
     pCur3 = pCur3->_pNext;
    }
    while (pCur3 && pCur4)
    {
     pCur3 = pCur3->_pNext;
     pCur4 = pCur4->_pNext;
    }
    if (pCur3 == pCur4)
    {
     return pCur3;
    }
    return NULL;
   }
   else if (size < 0)
   {
    while (size++)
    {
     pCur4 = pCur4->_pNext;
    }
    while (pCur3 && pCur4)
    {
     pCur3 = pCur3->_pNext;
     pCur4 = pCur4->_pNext;
    }
    if (pCur3 == pCur4)
    {
     return pCur3;
    }
    return NULL;
   }
   //环内相交
   else
   {
    pNode p1 = pEnterNode1;
    pNode p2 = pEnterNode2;
    while(p1 != pEnterNode1)
    {
     p1 = p1->_pNext;
     p2 = p2->_pNext->_pNext;
    }
    if (p1 == p2)
    {
     return p1;
    }
    return NULL;
   }
  }
 }
 else
 {
  return NULL;
 }
}
void CListNodeInit(pNode* pHead)
{
 assert(pHead);
 *pHead = NULL;
}
pCListNode BuyCListNode(DataType data)// 复杂链表获取结点
{
 pCListNode pNewNode = (pCListNode)malloc(sizeof(CListNode));
 if (NULL == pNewNode)
 {
  return NULL;
 }
 else
 {
  pNewNode->_pNext = NULL;
  pNewNode->_pRandom = NULL;
  pNewNode->data = data;
 }
 return pNewNode;
}
void CListNodePushBack(pCListNode *pHead, DataType data)//复杂链表的尾插
{
 assert(pHead);
 pCListNode pNewNode = BuyCListNode(data);
 pCListNode pCur = *pHead;
 if (NULL == pCur)
 {
  *pHead = pNewNode;
  return;
 }
 while (pCur->_pNext)
 {
  pCur = pCur->_pNext;
 }
 pCur->_pNext = pNewNode;
}
pCListNode CopyComplexList(pCListNode pHead)// 复杂链表的复制
{
 pCListNode p1 = NULL;
 pCListNode p2 = NULL;
 pCListNode pCur = NULL;
 pCListNode pNewNode = NULL;
 pCListNode pNext = NULL;
 if (NULL == pHead)
  return NULL;
 pCur = pHead;
 while (pCur)
 {
  pNewNode = BuyCListNode(pCur->data);   
  pNewNode->_pNext = pCur->_pNext;
  pCur->_pNext = pNewNode;
  pCur = pNewNode->_pNext;
 }
 while (p1)                     
 {
  p1 = pHead;
  p2 = p1->_pNext;
  if (p1->_pRandom != NULL)
   p2->_pRandom = p1->_pRandom->_pNext;
  p1 = p2->_pNext;
 }
 pNewNode = pHead->_pNext;
 p2 = pNewNode;
 p1 = pHead;
 //拆除
 while (p2->_pNext)                              
 {
  pNext = p2->_pNext;
  p1->_pNext = pNext;
  p2->_pNext = pNext->_pNext;
  p1 = pNext;
  p2 = pNext->_pNext;
 }
 p1->_pNext = NULL;
 p2->_pNext = NULL;
 return pNewNode;
}

//test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SListNode.h"
#include<stdio.h>
#include<stdlib.h>
void test1()
{
 pNode pHead;
 SListInit(&pHead);
 SListPushBack(&pHead, 1);//尾插
 SListPushBack(&pHead, 2);
 SListPushBack(&pHead, 3);
 SListPushBack(&pHead, 4);
 SListPushBack(&pHead, 5);
 printSList(pHead);
 SListPopBack(&pHead);//尾删
 printSList(pHead);
 SListPopBack(&pHead);
 printSList(pHead);
 SListPopBack(&pHead);
 printSList(pHead);
 SListPopBack(&pHead);
 printSList(pHead);
}
void test2()
{
 pNode pHead;
 SListInit(&pHead);
 SListPushFront(&pHead, 1);//头插
 SListPushFront(&pHead, 2);
 SListPushFront(&pHead, 3);
 SListPushFront(&pHead, 4);
 SListPushFront(&pHead, 5);
 printSList(pHead);
 SListPopFront(&pHead);//头删
 printSList(pHead);
 SListPopFront(&pHead);
 printSList(pHead);
 SListPopFront(&pHead);
 printSList(pHead);
 SListPopFront(&pHead);
 printSList(pHead);
}
void test3()
{
 pNode pHead;
 pNode pos = NULL;
 SListInit(&pHead);
 SListPushFront(&pHead, 1);//头插
 SListPushFront(&pHead, 2);
 SListPushFront(&pHead, 3);
 SListPushFront(&pHead, 4);
 SListPushFront(&pHead, 5);
 printSList(pHead);
 pos = SListFind(pHead, 3);//找到3的位置
 printf("%d\n", pos->_data);
 SListInsert(&pHead,pos,6);//在3元素的位置处插入元素6
 printSList(pHead);
 SListErase(&pHead,pos);//删除3元素位置处的元素
 printSList(pHead);
 SListDestroy(&pHead);
 printSList(pHead);
}
void test4()//查找值为data的结点,返回该结点在链表中的位置
{
 pNode pCur=NULL;
 pNode pHead;
 SListInit(&pHead);
 SListPushBack(&pHead, 1);//尾插
 SListPushBack(&pHead, 2);
 SListPushBack(&pHead, 3);
 SListPushBack(&pHead, 4);
 SListPushBack(&pHead, 5);
 printSList(pHead);
 pCur=SListFind(pHead, 4);
 printf("%p\n", pCur);
}
void test5()// 获取链表中的最后一个结点,返回该结点的地址
{
 pNode pHead;
 SListInit(&pHead);
 pNode pCur = NULL;
 SListPushBack(&pHead, 1);//尾插
 SListPushBack(&pHead, 2);
 SListPushBack(&pHead, 3);
 SListPushBack(&pHead, 4);
 SListPushBack(&pHead, 5);
 printSList(pHead);
 pCur = SListBack(pHead);
 printf("%p\n", pCur);
}
 void test6()//求链表中结点的个数
{
 pNode pHead;
 SListInit(&pHead);
 SListPushBack(&pHead, 1);//尾插
 SListPushBack(&pHead, 2);
 SListPushBack(&pHead, 3);
 SListPushBack(&pHead, 4);
 SListPushBack(&pHead, 5);
 printSList(pHead);
 int count = SListSize(pHead);
 printf("链表中节点个数为%d\n", count);
}
 void  test7()//从尾到头打印单链表
 {
  pNode pHead;
  SListInit(&pHead);
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  SListPushBack(&pHead, 5);
  printSList(pHead);
  PrintFromTailHead(pHead);
 }
 void test8()//删除无头单链表的非尾结点,要求:不能遍历
 {
  pNode pHead;
  SListInit(&pHead);
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  SListPushBack(&pHead, 5);
  printSList(pHead);
  DeleteNotTailNode(pHead);
  printSList(pHead);
  DeleteNotTailNode(pHead->_pNext);
  printSList(pHead);
 }
 void test9()//在无头单链表POS位置前插入值为data的结点
 {
  pNode pHead;
  SListInit(&pHead);
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  SListPushBack(&pHead, 5);
  printSList(pHead);
  InsertPosFront(pHead->_pNext,6);
  printSList(pHead);
 }
 void test10()//用单链表模拟实现约瑟夫环
 {
  pNode pHead;
  SListInit(&pHead);
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  printSList(pHead);
  JosephCircle(&pHead,3);
  printSList(pHead);
 }
 void test11()// 使用冒泡排序方法对单链表进行排序
 {
  pNode pHead;
  SListInit(&pHead);
  SListPushBack(&pHead, 4);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 1);
  printSList(pHead);
  BobbleSort(pHead);
  printSList(pHead);
 }
 void test12()// 单链表的逆置--三个指针
 {
  pNode pHead;
  SListInit(&pHead);
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  printSList(pHead);
  ReverseSList(&pHead);
  printSList(pHead);
 }
 void test13()// 单链表的逆置--头插法
 {
  pNode pHead;
  SListInit(&pHead);
  pNode pCur = NULL;
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  printSList(pHead);
  pCur=ReverseSListTop(pHead);
  printSList(pCur);
 }
 void test14()// 合并两个有序链表,合并之后依然有序
 {
  pNode pHead1;
  pNode pHead2;
  pNode ret = NULL;
  SListInit(&pHead1);
  SListPushBack(&pHead1, 1);//尾插
  SListPushBack(&pHead1, 5);
  SListPushBack(&pHead1, 3);
  SListPushBack(&pHead1, 8);
  printSList(pHead1);
  SListInit(&pHead2);
  SListPushBack(&pHead2, 6);//尾插
  SListPushBack(&pHead2, 7);
  SListPushBack(&pHead2, 2);
  SListPushBack(&pHead2, 4);
  printSList(pHead2);
  ret=MergeSList(pHead1,pHead2);
  printSList(ret);
 }
 void test15()// 查找链表的中间结点,要求只能遍历一次链表
 {
  pNode pHead;
  SListInit(&pHead);
  pNode ret = NULL;
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  printSList(pHead);
  ret=FindMiddleNode(pHead);
  printf("%d\n",ret->_data);
 }
 void test16()// 查找链表的倒数第K个结点,要求只能遍历链表一次
 {
  pNode pHead;
  SListInit(&pHead);
  pNode ret = NULL;
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  printSList(pHead);
  ret = FindLastKNode(pHead,2);
  printf("%d\n", ret->_data);
 }
 void test17()// 删除链表的倒数第K个结点,要求只能遍历链表一次
 {
  pNode pHead;
  SListInit(&pHead);
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  printSList(pHead);
  DeleteLastKNode(pHead, 2);
  printSList(pHead);
 }
 void test18()// 判断单链表是否相交?链表不带环
 {
  pNode pHead1;
  pNode pHead2;
  SListInit(&pHead1);
  SListPushBack(&pHead1, 1);//尾插
  SListPushBack(&pHead1, 5);
  SListPushBack(&pHead1, 3);
  SListPushBack(&pHead1, 2);
  printSList(pHead1);
  SListInit(&pHead2);
  SListPushBack(&pHead2, 6);//尾插
  SListPushBack(&pHead2, 7);
  SListPushBack(&pHead2, 2);
  SListPushBack(&pHead2, 4);
  printSList(pHead2);
  IsCrossWithoutCircle(pHead1, pHead2);
 }
 void test19()// 求不带环单链表相交交点
 {
  pNode pHead1;
  pNode pHead2;
  pNode ret = NULL;
  SListInit(&pHead1);
  SListPushBack(&pHead1, 1);//尾插
  SListPushBack(&pHead1, 5);
  SListPushBack(&pHead1, 2);
  SListPushBack(&pHead1, 8);
  printSList(pHead1);
  SListInit(&pHead2);
  SListPushBack(&pHead2, 6);//尾插
  SListPushBack(&pHead2, 7);
  SListPushBack(&pHead2, 2);
  SListPushBack(&pHead2, 4);
  printSList(pHead2);
  ret = GetCrossNode(pHead1, pHead2);
  printf("%d\n", ret->_data);
 }
 void test20()// 判断链表是否带环
 {
  pNode pHead;
  SListInit(&pHead);
  pNode ret = NULL;
  SListPushBack(&pHead, 1);
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  SListPushBack(&pHead, 5);
  ret = IsCircle(pHead);
 }
 void test21()// 求环的长度
 {
  pNode pHead;
  SListInit(&pHead);
  pNode ret = NULL;
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  SListPushBack(&pHead, 5);
  printSList(pHead);
  ret = GetCircleLen(pHead);
 }
 void test22()// 求环的入口点
 {
  pNode pHead;
  SListInit(&pHead);
  pNode ret = NULL;
  pNode pMeetNode = pHead;
  SListPushBack(&pHead, 1);//尾插
  SListPushBack(&pHead, 2);
  SListPushBack(&pHead, 3);
  SListPushBack(&pHead, 4);
  SListPushBack(&pHead, 5);
  printSList(pHead);
  ret = GetEnterNode(pHead,pMeetNode);
  printf("%d\n", ret->_data);
 }
 void test23()// 判断链表是否带环,链表可能带环
 {
  pNode pHead1;
  pNode pHead2;
  pNode ret = NULL;
  SListInit(&pHead1);
  SListInit(&pHead2);
  SListPushBack(&pHead1, 1);
  SListPushBack(&pHead1, 2);
  SListPushBack(&pHead1, 3);
  SListPushBack(&pHead1, 4);
  SListPushBack(&pHead1, 5);
  SListPushBack(&pHead2, 6);
  SListPushBack(&pHead2, 7);
  SListPushBack(&pHead2, 8);
  SListPushBack(&pHead2, 9);
  SListPushBack(&pHead2, 10);
  ret = IsListCrossWithCircle(pHead1, pHead2);
 }
 void test24()
 {
  pCListNode pHead;
  CListNodeInit(&pHead);
  pCListNode ret = NULL;
  CListNodePushBack(&pHead, 1);
  CListNodePushBack(&pHead, 2);
  CListNodePushBack(&pHead, 3);
  CListNodePushBack(&pHead, 4);
  ret = CopyComplexList(pHead);
 }

int main()
{
 //test1();//尾插   尾删
 //test2();//头插   头删
 //test3();//在3元素的位置处插入元素6     删除3元素位置处的元素
 //test4();//查找值为data的结点,返回该结点在链表中的位置
 //test5();// 获取链表中的最后一个结点,返回该结点的地址 
 //test6();//求链表中结点的个数
 //test7();//从尾到头打印单链表
 //test8();//删除无头单链表的非尾结点,要求:不能遍历
 // test9();//在无头单链表POS位置前插入值为data的结点
 //test10();//用单链表模拟实现约瑟夫环
 //test11();// 使用冒泡排序方法对单链表进行排序
 //test12();// 单链表的逆置--三个指针
 //test13();// 单链表的逆置--头插法
 //test14();// 合并两个有序链表,合并之后依然有序                                      
 //test15();// 查找链表的中间结点,要求只能遍历一次链表
 //test16();// 查找链表的倒数第K个结点,要求只能遍历链表一次
 //test17();// 删除链表的倒数第K个结点,要求只能遍历链表一次
 //test18();// 判断单链表是否相交?链表不带环                                          
 //test19();// 求不带环单链表相交交点                                                    
 //test20();// 判断链表是否带环                                                                
 //test21();// 求环的长度
 //test22();// 求环的入口点
 //test23();// 判断链表是否带环,链表可能带环
 test24();
 system("pause");
 return 0;
}

链表与顺序表区别:

1.顺序表支持随机访问,单链表不支持随机访问;

2.顺序表插入/删除数据效率很低,时间复杂度为O(N)(除尾插 尾删),单链表插入/删除效率更高,时间复杂度为O(1);

3.顺序表的CPU高速缓存效率更高,单链表CPU高速缓存效率低。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值