链表面试题

总结链表和顺序表的优缺点:  

1.首先我们从2种结构的结构上来进行分析:

        (1)对于顺序表。不论是静态的还是动态的,他们都是连续的存储空间,在读取上时间效率比较快,可以通过地址之间的运算来进行访问,但是在插入和删除操作会出现比较麻烦的负载操作。

        (2)对于链表,因为他是链式存储。在我们需要的时候才在堆上开辟空间,对于插入查找的方式比较便携。但是对于遍历的话需要多次的空间跳转。

    2.从2中结构的空间申请方式来看:

        (1)顺序表的空间开辟是在满的时候进行多空间的申请开辟。往往存在着2^n的开辟原则。在开辟次数比较多的时候,会出现比较大的空间浪费。

        (2)链表的空间开辟是针对于单个节点的空间开辟访问,不存在多余的空间浪费。并且在碎片内存池的机制下。可以有效地利用空间。

    通过上面的总结,可以分析出顺序表往往用于查找遍历操作比较频繁的情况下使用。链表则针对于数据删除修改的多操作性上的情况下使用。

    分别是空间上和时间上的优势与缺陷的不同。

(链表面试题从350行开始
Slist.h
#pragma once

#include <stdio.h>
#include <assert.h>
#include <malloc.h>


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;

//不带头结点的单链表// 
// .h 
// 链表初始化 
void SListInit(PNode* pHead); 

// 尾插 
void SListPushBack(PNode* pHead, DataType data); 

// 尾删 
void SListPopBack(PNode* pHead); 

// 头插 
void SListPushFront(PNode* pHead, DataType data); 

// 头删 
void SListPopFront(PNode* pHead); 

// 查找值为data的结点,返回该结点在链表中的位置 
PNode SListFind(PNode pHead, DataType data); 

// 在链表pos位置后插入结点data 
void SListInsert(PNode* pHead, PNode pos, DataType data); 

// 删除链表pos位置上的结点 
void SListErase(PNode* pHead, PNode pos); 

// 销毁单链表 
void SListDestroy(PNode* pHead); 

// 求链表中结点的个数 
int SListSize(PNode pHead); 

// 将链表中的结点清空 
void SListClear(PNode* pHead); 

// 获取结点 
PNode BuySListNode(DataType data); 

// 获取链表中的最后一个结点,返回该结点的地址 
PNode SListBack(PNode pHead); 

//输出链表元素
void PrintList(PNode pHead);
/// 
// 以下链表的面试题,放在下次作业中交,在底下先实现 
// 删除链表的非尾结点,要求不能遍历链表 
void DeleteNotTailNode(PNode pos); 

// 在链表pos位置前插入值为data的结点 
void InsertPosFront(PNode pos, DataType data); 

// 约瑟夫环 
void JosephCircle(PNode* pHead, const int M); 

// 使用冒泡方式对单链表进行排序 
void BubbleSort(PNode pHead); 

// 单链表的逆序---三个指针 
void ReverseSList(PNode* pHead); 

// 单链表的逆序---使用头插法 
PNode ReverseSListOP(PNode pHead); 

// 合并两个有序链表,合并起来依然要有序 
PNode MergeSList(PNode pHead1, PNode pHead2); 

// 查找链表的中间结点,要求只能遍历一次链表 
PNode FindMiddleNode(PNode pHead); 

// 查找链表的倒数第K个结点 
PNode FindLastKNode(PNode pHead, int K); 

// 判断两个单链表是否相交---链表不带环 
int IsCrossWithoutCircle(PNode pHead1, PNode pHead2); 

// 判断两个单链表是否相交---链表可能带环 
int IsCross(PNode pHead1, PNode pHead2);

// 如果相交 获取交点 
PNode GetCrossNode(PNode pHead1, PNode pHead2);

//单链表是否带环
PNode IsCircle(PNode pHead);

//两个带环单链表是否相交
PNode IsCross2WithCircle(PNode pHead1,PNode pHead2);

//求得 带环链表的环长
int GetCirclelength(PNode pHead);

//找到带环链表的 入口节点
PNode GetEnterNode(PNode pHead);

//获取复杂链表节点
PCListNode BuyCSListNode(DataType data);

//初始化复杂链表
void CSListInit(PCListNode* pHead);

// 复杂链表的复制 
PCListNode CopyComplexList(PCListNode pHead);

//复制链表的尾插
void CSListPushBack(PCListNode* pHead, DataType data);

//在当前节点后插新节点(复杂链表)
void CSListInsert(PCListNode* pHead,PCListNode pos,DataType data);

// 查找值为data的结点,返回该结点在链表中的位置(复杂链表中) 
PCListNode CSListFind(PCListNode pHead, DataType data);

//打印复杂链表
void PrintCSList(PCListNode pHead);



//初始化链表
void SListInit(PNode* pHead)   
{
	assert(pHead);
	*pHead=NULL;
}

// 尾插 
void SListPushBack(PNode* pHead, DataType data)
{
	PNode pCur=*pHead;
	PNode pNew=NULL;
	assert(pHead);
	pNew=BuySListNode(data);
	if(NULL==(*pHead))              //链表为空
	{                                                               
         *pHead=pNew;                                             
		 return;
	}
	while(pCur->_pNext)            //链表不为空
         pCur=pCur->_pNext;
	pCur->_pNext=pNew;
}

// 尾删 
void SListPopBack(PNode* pHead)
{
    PNode pCur=NULL;
	PNode pPre=NULL;
	assert(pHead);
	if(NULL==*pHead)                //链表为空直接退出
		return;
	if((*pHead)->_pNext==NULL)      //只有一个结点
	{	
		free(*pHead);
		*pHead=NULL;
		return;
	}
	pCur=*pHead;
	while(pCur->_pNext)
	{
		pPre=pCur;
		pCur=pCur->_pNext;
	}
	free(pCur);
	pCur=NULL;
	pPre->_pNext=NULL;
}

// 头插 
void SListPushFront(PNode* pHead, DataType data)
{
   PNode pNew=NULL;
   assert(pHead);
   pNew=BuySListNode(data);
   if(NULL==(*pHead)||((*pHead)->_data==0)&&(*pHead)->_pNext==NULL)        //链表为空或者链表只是初始化了
   {   
	   *pHead=pNew;
	   return;
   }
   pNew->_pNext=*pHead;                //有一个或者多个结点
   *pHead=pNew;

}

// 头删 
void SListPopFront(PNode* pHead)
{
	PNode pDel=*pHead;
	assert(pHead);
	if(NULL==*pHead)        //链表为空,直接退出
		return;
    if((*pHead)->_pNext==NULL)      //链表只有一个结点
	{
		free(*pHead);
	    *pHead=NULL;
		return;
	}
    *pHead=pDel->_pNext;     //有多个结点
	free(pDel);
	pDel=NULL;
}

// 查找值为data的结点,返回该结点在链表中的位置 
PNode SListFind(PNode pHead, DataType data)
{
   assert(pHead);
   while (pHead)
   {
       if(pHead->_data==data)
		   return pHead;
	   pHead=pHead->_pNext;
   }
   if(NULL==pHead)             //pHead指向NULL,即没找到值为data的结点
	  printf("Not find data!\n");
   return pHead;
}

// 在链表pos位置后插入结点data 
void SListInsert(PNode* pHead, PNode pos, DataType data)
{
	PNode pNew=BuySListNode(data);         //创建data新结点
	PNode pCur=pos->_pNext;                //保存pos的下个结点的地址            //
	assert(pHead);
	//链表为空,直接头插或者尾插
	if(NULL==*pHead)                      
	{
		SListPushFront(pHead,data);
		return;
	}
	//有多个结点
	pos->_pNext=pNew;                       
	pNew->_pNext=pCur;
}

// 删除链表pos位置上的结点 
void SListErase(PNode* pHead, PNode pos)
{
	PNode pPre=NULL,pCur=*pHead,pNext=NULL;
	assert(pHead);
	if(NULL==*pHead)     //链表为空,直接返回
		return;
    while (!(pCur==pos)&&pCur->_pNext)    //找到pos结点,或者遍历链表也没找到
    {
         pPre=pCur;
		 pCur=pCur->_pNext;
    }
	pNext=pCur->_pNext;
	free(pCur);
	pPre->_pNext=pNext;
}

// 销毁单链表 
void SListDestroy(PNode* pHead)
{
	PNode pNext=NULL,pDel=NULL;
	assert(pHead);
	if(NULL==*pHead)
		return;
	while (*pHead)
	{
		pNext=(*pHead)->_pNext;
		pDel=*pHead;
		free(*pHead);
		pDel=NULL;
        *pHead=pNext;
	}
}

// 求链表中结点的个数 
int SListSize(PNode pHead)
{
	int count=0;
	if(NULL==pHead)
		return 0;
    while (pHead)
    {
      count++;
      pHead=pHead->_pNext;
    }
	return count;
}

// 将链表中的结点清空 
void SListClear(PNode* pHead)
{
	PNode pCur=*pHead;
	assert(pHead);
	if(NULL==*pHead)
		return;
	while (pCur)
	{
		pCur->_data=0;
		pCur=pCur->_pNext;
	}
}

// 获取结点 
PNode BuySListNode(DataType data)
{
	PNode pHead;
	pHead=(PNode)malloc(sizeof(Node));
	if(NULL==pHead)
		return NULL;
	pHead->_pNext=NULL;
	pHead->_data=data;
	return pHead;
}

// 获取链表中的最后一个结点,返回该结点的地址 
PNode SListBack(PNode pHead)
{
	PNode pCur=pHead;
	if(NULL==pHead)
		return NULL;
    while (pCur->_pNext)
		pCur=pCur->_pNext;
	return pCur;
}

void PrintList(PNode pHead)
{
	while (pHead)
	{
        printf("%d---->",pHead->_data);
		pHead=pHead->_pNext;
	}
	printf("NULL\n");
}

/// 
// 以下链表的面试题,放在下次作业中交,在底下先实现 
// 删除链表的非尾结点,要求不能遍历链表 
void DeleteNotTailNode(PNode pos)
{
	PNode pDel=NULL;
	if(NULL==pos||NULL==pos->_pNext)
		return;
	pos->_data=pos->_pNext->_data;
	pDel=pos->_pNext;
	pos->_pNext=pos->_pNext->_pNext;
	free(pDel);
	pDel=NULL;
}

// 在链表pos位置前插入值为data的结点 
void InsertPosFront(PNode pos, DataType data)
{
    PNode pNew=BuySListNode(pos->_data);
    PNode pNext=pos->_pNext;
	pos->_pNext=pNew;
	pNew->_pNext=pNext;
	pos->_data=data;
}

// 约瑟夫环 
void JosephCircle(PNode* pHead, const int M)
{
	PNode pTail=NULL,pCur=NULL,pDel=NULL;
    assert(pHead);
	if(NULL==*pHead || NULL==(*pHead)->_pNext)    //如果链表为空或者只有一个节点,直接返回 
        return;
	pTail=*pHead;
	pCur=*pHead;
	while (pTail->_pNext)
	   pTail=pTail->_pNext;
	pTail->_pNext=*pHead;                      //先构环
	while (pCur!=pCur->_pNext)
	{
		 int count=M;
         while (--count)
            pCur=pCur->_pNext;      //pCur指向报数为M的节点
		 pDel=pCur->_pNext;
     	 if(pDel==*pHead)
			 *pHead=(*pHead)->_pNext;    //如果要删的节点是头节点,就将头节点移向下下一个节点
		 pCur->_data=pDel->_data;
		 pCur->_pNext=pDel->_pNext;
		 free(pDel);
		 pDel=NULL;
	}
}


// 使用冒泡方式对单链表进行排序 
void BubbleSort(PNode pHead)
{
	int i=0,j=0,count=0;
	PNode pCur=NULL,pNext=NULL;
	if(NULL==pHead || NULL==pHead->_pNext)       //如果链表为空,或者只有一个节点,直接返回,不用排
		return;
	pCur=pHead;
	pNext=pCur->_pNext;
    while(pCur)
	{
		count++;
		pCur=pCur->_pNext;
	}
	
    for (i=0;i<count;i++)
    {
	   pCur=pHead;
	   pNext=pCur->_pNext;
       for (j=0;j<count-i-1;j++)
       {
           if (pCur->_data>pNext->_data)       //
           {
			   DataType tmp=0;
			   tmp=pCur->_data;
			   pCur->_data=pNext->_data;
			   pNext->_data=tmp;
           }
           pCur=pNext;
		   pNext=pNext->_pNext;
       }
    }
}

// 单链表的逆序---三个指针 
void ReverseSList(PNode* pHead)
{
	PNode pCur=NULL, pNext=NULL, pPre=NULL;  
    assert(pHead);
	if(NULL==*pHead)
		return;
	pCur = *pHead;  
	while(pCur)  
	{  
		pNext=pCur->_pNext;  
		pCur->_pNext=pPre;  
		pPre=pCur;
		pCur = pNext;
	}  
	*pHead=pPre;
}

// 单链表的逆序---使用头插法 
PNode ReverseSListOP(PNode pHead)
{
	PNode s;                                //创建新链表
	PNode pCur=NULL;
	if(NULL==pHead || NULL==pHead->_pNext)
		return NULL;
	pCur=pHead;
    SListInit(&s);
    while (pCur)
    {
		SListPushFront(&s,pCur->_data);
		pCur=pCur->_pNext;
    }
    return s; 
}

// 合并两个有序链表,合并起来依然要有序 
PNode MergeSList(PNode pHead1, PNode pHead2)
{
	PNode pCur1=NULL,pCur2=NULL;//pNewNode=NULL;
	assert(pHead1);
	assert(pHead2);
	pCur1=pHead1;
	pCur2=pHead2;
    //pNewNode=pHead1;
	while(pCur1)
	{
		if (NULL!=pCur2)            //链表2不为空
		{
			if(pCur2->_data<=pCur1->_data)
			{
				InsertPosFront(pCur1,pCur2->_data);
				pCur2=pCur2->_pNext;
			}
			else
				pCur1=pCur1->_pNext;
		}
		else                        //链表2为空
			break;
	}
	if (NULL==pCur1 && pCur2!=NULL)
	{
		InsertPosFront(pCur1,pCur2->_data);
		pCur2=pCur2->_pNext;
	}
    return pHead1;
}

// 查找链表的中间结点,要求只能遍历一次链表 
PNode FindMiddleNode(PNode pHead)
{
	PNode pFast=NULL,pSlow=NULL;
	if(NULL==pHead)
		return NULL;
    pFast=pHead;
	pSlow=pHead;
	while (pFast && pFast->_pNext)
	{
		pFast=pFast->_pNext->_pNext;
		pSlow=pSlow->_pNext;
	}
	return pSlow;                      //如果有偶数个节点,返回的中间节点是靠后的那个
}

// 查找链表的倒数第K个结点 
PNode FindLastKNode(PNode pHead, int K)
{
	PNode pFast=NULL,pSlow=NULL;
	if(NULL==pHead)
		return NULL;
	pFast=pHead;
	pSlow=pHead;
    while (--K)
        pFast=pFast->_pNext;          //此时pFast指向的k个节点
	while (pFast && pFast->_pNext)
	{
		pFast=pFast->_pNext;          //快慢一起走
		pSlow=pSlow->_pNext;
	}
	return pSlow;
}

// 判断两个单链表是否相交---链表不带环 
int IsCrossWithoutCircle(PNode pHead1, PNode pHead2)
{
    PNode pTail1=pHead1,pTail2=pHead2;
	if(NULL==pHead1 || NULL==pHead2)
	   return 0;
    while(pTail1->_pNext)
		pTail1=pTail1->_pNext;
	while(pTail2->_pNext)
		pTail2=pTail2->_pNext;
    if (pTail1==pTail2)
        return 1;
	else
		return 0;
}

// 判断两个单链表是否相交---链表可能带环 
int IsCross(PNode pHead1, PNode pHead2)
{
    PNode pMeet1=NULL,pMeet2=NULL,pCur=NULL;
	if(NULL==pHead1 || NULL==pHead2)
		return 0;
    //是否带环
	pMeet1=IsCircle(pHead1);
	pMeet2=IsCircle(pHead2);
	pCur=pMeet1;
	if (pMeet1 && pMeet2)         //两个链表都带环(交点在:①环外(一个交点),②环内(即两个链表的入环节点,两个交点))
	{
        do 
        {
			if(pCur==pMeet2)
               return 1;
			pCur=pCur->_pNext;
        } while (pCur!=pMeet1);
	}
	else if(IsCrossWithoutCircle(pHead1,pHead2))    // 两个链表都不带环
	      return 1;
    return 0;
}
// 如果相交 获取交点 
PNode GetCrossNode(PNode pHead1, PNode pHead2)
{
    PNode pCur1=pHead1,pCur2=pHead2;
	int size1=0,size2=0,gap=0;
    while(pCur1)
	{
		size1++;
		pCur1=pCur1->_pNext;
	}
	while (pCur2)
	{
		size2++;
		pCur2=pCur2->_pNext;
	}
	gap=size1-size2;
    pCur1=pHead1,pCur2=pHead2;
	if (gap>=0)
	{ 
		while(gap--)                   //size1>=size2,pCur1先走gap步
			pCur1=pCur1->_pNext;
		while (pCur1!=pCur2)
		{
			pCur1=pCur1->_pNext;
			pCur2=pCur2->_pNext;
		}
		return pCur1;
	}
	else
	{
		while (gap--)                  //size1<size2,pCur2先走gap步
		   pCur2=pCur2->_pNext;
		while (pCur1!=pCur2)
		{
			pCur1=pCur1->_pNext;
			pCur2=pCur2->_pNext;
		}
		return pCur1;
	}
}


//单链表是否带环
PNode IsCircle(PNode pHead)     
{
  PNode pFast=pHead,pSlow=pHead;
  if(NULL==pHead)
	  return NULL;
  while (pFast && pFast->_pNext)
  {
	  pFast=pFast->_pNext->_pNext;
	  pSlow=pSlow->_pNext;
	  if(pFast==pSlow)
		  return pFast;          //返回快慢指针相遇节点
  }
  return NULL;
}

//求得 带环链表的环长
int GetCirclelength(PNode pHead)
{
   PNode pMeetNode=IsCircle(pHead);     //将判断链表是否带环时 快慢指针的相遇节点返回
   PNode pCur=pMeetNode;
   int count=1;
   while (pCur->_pNext!=pMeetNode)
   {
	   count++;
	   pCur=pCur->_pNext;
   }
   return count;
}

//找到带环链表的 入口节点
PNode GetEnterNode(PNode pHead)
{
    PNode pMeetNode=NULL;
	if(NULL==pHead)
	   return NULL;
    pMeetNode=IsCircle(pHead);       //找到快慢指针 相遇节点
    while (pHead!=pMeetNode)
    {
		pHead=pHead->_pNext;
		pMeetNode=pMeetNode->_pNext;
    }
	return pMeetNode;
}

//获取复杂链表节点
PCListNode BuyCSListNode(DataType data)
{
	PCListNode pNew;
	pNew=(PCListNode)malloc(sizeof(CListNode));
	if(NULL==pNew)
		return NULL;
	pNew->_data=data;
	pNew->_pNext=NULL;
	pNew->_pRandom=NULL;
	return pNew;
}

//初始化复杂链表
void CSListInit(PCListNode* pHead)
{
   assert(pHead);
   *pHead=NULL;
}
//在当前节点后插新节点(复杂链表)
void CSListInsert(PCListNode* pHead,PCListNode pos,DataType data)
{
   PCListNode pNew=NULL;
   PCListNode pNext=NULL;
   assert(pHead);
   if(NULL==(*pHead))
   {

   }
   pNew=BuyCSListNode(data);
   pNext=pos->_pNext;

   pos->_pNext=pNew;
   pNew->_pNext=pNext;
}
//复制链表的尾插
void CSListPushBack(PCListNode* pHead, DataType data)
{
	PCListNode pCur=*pHead;
	PCListNode pNew=NULL;
	assert(pHead);
	pNew=BuyCSListNode(data);
	if(NULL==(*pHead))              //链表为空
	{                                                               
		*pHead=pNew;                                             
		return;
	}
	while(pCur->_pNext)            //链表不为空
		pCur=pCur->_pNext;
	pCur->_pNext=pNew;
}

// 查找值为data的结点,返回该结点在链表中的位置(复杂链表中) 
PCListNode CSListFind(PCListNode pHead, DataType data)
{
	assert(pHead);
	while (pHead)
	{
		if(pHead->_data==data)
			return pHead;
		pHead=pHead->_pNext;
	}
	if(NULL==pHead)             //pHead指向NULL,即没找到值为data的结点
		printf("Not find data!\n");
	return pHead;
}
// 复杂链表的复制 
PCListNode CopyComplexList(PCListNode pHead)
{
	PCListNode pCur=NULL,pNext=NULL,pos=NULL;
	PCListNode pNew;
	if(NULL==pHead)
		return NULL;
    pCur=pHead;
	while (pCur)            //完成链表的节点copy
	{
		pNext=pCur->_pNext;
		CSListInsert(&pHead,pCur,pCur->_data);
		pCur=pNext;
	}
	pCur=pHead;
	pNew=pCur->_pNext;
	while (pCur)
	{
		pNext=pCur->_pNext;
		if(pCur->_pRandom!=NULL)
		{
			 pNext->_pRandom=pCur->_pRandom->_pNext;
		}
        pCur=pNext->_pNext;
		
	}
	pCur=pHead;
	while (pCur)
	{
		pNext=pCur->_pNext;
		pCur->_pNext=pNext->_pNext;
		if (pCur!=NULL)
		{
			pNext->_pNext=pCur->_pNext;
		}
		pCur=pNext->_pNext;
	}
	
	return pNew;
}

//打印复杂链表
void PrintCSList(PCListNode pHead)
{
	while (pHead)
	{
		printf("%d---->",pHead->_data);
		pHead=pHead->_pNext;
	}
	printf("NULL\n");
}
//测试函数

///
void testSListPushPop()           //测试头插/尾插/头插/头删函数
{
	PNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead,1);       //尾插
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	//SListPopBack(&pHead);         //尾删
	//SListPushFront(&pHead,0);       //头插
	PrintList(pHead);
	SListPopFront(&pHead);          //头删
	PrintList(pHead);
}

//测试约瑟夫环JosephCircle
void testJosephCircle()
{
	PNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead,1);      
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	SListPushBack(&pHead,6);      
	SListPushBack(&pHead,7);
	SListPushBack(&pHead,8);
	SListPushBack(&pHead,9);
	SListPushBack(&pHead,10);
    JosephCircle(&pHead,3);
	printf("%d \n",pHead->_data);
}

//测试冒泡排序BubbleSort
void testBubbleSort()
{
	PNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead,10);      
	SListPushBack(&pHead,9);
	SListPushBack(&pHead,8);
	SListPushBack(&pHead,7);
	SListPushBack(&pHead,6);
	SListPushBack(&pHead,5);      
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,1);
	BubbleSort(pHead);
	PrintList(pHead);
}

//测试单链表的逆置---三个指针法ReverseSList
void testReverseSList()
{
	PNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead,10);      
	SListPushBack(&pHead,9);
	SListPushBack(&pHead,8);
	SListPushBack(&pHead,7);
	SListPushBack(&pHead,6);
	SListPushBack(&pHead,5);      
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,1);
	printf("逆置之前:\n");
	PrintList(pHead);
    ReverseSList(&pHead);
	printf("逆置之后:\n");
	PrintList(pHead);
}


// 单链表的逆序---使用头插法 
void  testReverseSListOP()
{
	PNode pHead;
	PNode pNew;
	SListInit(&pHead);
	SListPushBack(&pHead,10);      
	SListPushBack(&pHead,9);
	SListPushBack(&pHead,8);
	SListPushBack(&pHead,7);
	SListPushBack(&pHead,6);
	SListPushBack(&pHead,5);      
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,1);
	printf("逆置之前:\n");
	PrintList(pHead);
	pNew=ReverseSListOP(pHead);
	printf("逆置之后:\n");
	PrintList(pNew);
}

//CopyComplexList   测试复杂链表复制函数
void testCopyComplexList()
{
	PCListNode pHead;
	PCListNode pNew;
	PCListNode pCur=NULL,pos=NULL;
        CSListInit(&pHead);
	CSListPushBack(&pHead,1);
	CSListPushBack(&pHead,2);
	CSListPushBack(&pHead,3);
	CSListPushBack(&pHead,4);
	
	pCur=CSListFind(pHead,1);
	pos=CSListFind(pHead,3);
	pCur->_pRandom=pos;
	pCur=CSListFind(pHead,2);
	pos=CSListFind(pHead,1);
	pCur->_pRandom=pos;
	pCur=CSListFind(pHead,3);
	pCur->_pRandom=pCur;
	pNew=CopyComplexList(pHead);
	printf("原链表:");
	PrintCSList(pHead);
	printf("新链表:");
	PrintCSList(pNew);
}
// 合并两个有序链表,合并起来依然要有序 
//PNode MergeSList(PNode pHead1, PNode pHead2)
void testMergeSList()
{
	PNode s1;
	PNode s2;
	PNode pNew;
	SListInit(&s1);
	SListInit(&s2);
	SListPushBack(&s1,2);
	SListPushBack(&s1,4);
	SListPushBack(&s1,6);
	SListPushBack(&s1,8);
	printf("链表1:");
    PrintList(s1);
	SListPushBack(&s2,1);
	SListPushBack(&s2,3);
	SListPushBack(&s2,5);
	SListPushBack(&s2,7);
	printf("链表2:");
	PrintList(s2);
	pNew=MergeSList(s1,s2);
	printf("合并后:");
	PrintList(pNew);
}

//SListInsert  InsertPosFront
void testSListInsert()              //测试pos位置后插入值为data   pos位置前插入值为data
{
	PNode pHead;
	PNode pos=NULL;
	SListInit(&pHead);
	SListPushBack(&pHead,1);       //尾插
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	SListPushBack(&pHead,6);
	PrintList(pHead);
	pos=SListFind(pHead,4);
	//SListInsert(&pHead,pos,9);
	InsertPosFront(pos,10);
	PrintList(pHead);
}


void testSListErase()             //测试任意位置删除函数
{
	PNode pHead;
	PNode pos=NULL;
	SListInit(&pHead);
	SListPushBack(&pHead,1);       //尾插
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	PrintList(pHead);
	printf("结点数=%d\n",SListSize(pHead));
	pos=SListFind(pHead,4);
	SListErase(&pHead,pos);
	PrintList(pHead);
	printf("结点数=%d\n",SListSize(pHead));
	//SListDestroy(&pHead);            //销毁链表
	SListClear(&pHead);                //清空链表
	PrintList(pHead);
	printf("结点数=%d\n",SListSize(pHead));
}

void testDeleteNotTailNode()            //测试 删除非尾结点函数
{
	PNode pHead;
	PNode pos=NULL;
	SListInit(&pHead);
	SListPushBack(&pHead,1);       //尾插
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	PrintList(pHead);
	printf("结点数=%d\n",SListSize(pHead));
	pos=SListFind(pHead,3);
	DeleteNotTailNode(pos);
	PrintList(pHead);
	printf("结点数=%d\n",SListSize(pHead));
}
//FindMiddleNode找中间节点
void testFindMiddleNode()
{
	PNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead,1);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	//SListPushBack(&pHead,5);
	printf("%d \n",FindMiddleNode(pHead)->_data);
}

//FindLastKNode找倒数第k个节点
void testFindLastKNode()
{
	PNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead,1);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	SListPushBack(&pHead,6);
	SListPushBack(&pHead,7);
	SListPushBack(&pHead,8);
    printf("%d \n",FindLastKNode(pHead,2)->_data);
}
void testIsCrossWithoutCircle()                //测试 判断链表是否相交--不带环
{
	PNode pHead1,pHead2,pos1=NULL,pos2=NULL,pCross=NULL;
	SListInit(&pHead1);
	SListInit(&pHead2);
	SListPushBack(&pHead1,1);       //尾插
	SListPushBack(&pHead1,2);
	SListPushBack(&pHead1,3);
	SListPushBack(&pHead1,4);
	SListPushBack(&pHead1,5);

	pos1=SListBack(pHead1);

	SListPushBack(&pHead2,6);       //尾插
	SListPushBack(&pHead2,7);
	SListPushBack(&pHead2,8);
	SListPushBack(&pHead2,9);
	SListPushBack(&pHead2,10);

	pos2=SListFind(pHead2,7);
	pos1->_pNext=pos2;           //此时链表已相交
	//PrintList(pHead1);  
	if(IsCrossWithoutCircle(pHead1,pHead2))
	{  
		printf("链表相交\n");
		pCross=GetCrossNode(pHead1,pHead2);
	}
	else
		printf("链表不相交\n");
}

void testIsCross()                //测试 判断链表是否相交--可能带环
{
	PNode pHead1,pHead2,pos1=NULL,pos2=NULL,pCross=NULL;
	SListInit(&pHead1);
	SListInit(&pHead2);
	SListPushBack(&pHead1,1);       //尾插
	SListPushBack(&pHead1,2);
	SListPushBack(&pHead1,3);
	SListPushBack(&pHead1,4);
	SListPushBack(&pHead1,5);

	pos1=SListBack(pHead1);

	SListPushBack(&pHead2,6);       //尾插
	SListPushBack(&pHead2,7);
	SListPushBack(&pHead2,8);
	SListPushBack(&pHead2,9);
	SListPushBack(&pHead2,10);

	pos2=SListFind(pHead2,7);
	pos1->_pNext=pos2;           //此时链表已相交(Y型)

	pos1=SListBack(pHead2);
	pos1->_pNext=pHead2;         //此时链表带环相交
	//PrintList(pHead1); 
	//PrintList(pHead1);
	if(IsCross(pHead1,pHead2))
	{  
		printf("链表相交\n");
	}
	else
		printf("链表不相交\n");
}
//
void testIsCircle()              //测试 判断链表是否带环-->求环长--->找入口点
{
	PNode pHead,pos1=NULL,pos2=NULL,pEnterNode=NULL;
	SListInit(&pHead);
	SListPushBack(&pHead,1);       //尾插
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	SListPushBack(&pHead,6);
	SListPushBack(&pHead,7);
	SListPushBack(&pHead,8);
	SListPushBack(&pHead,9);
	SListPushBack(&pHead,10);

	//pos1=SListBack(pHead);
	//pos2=SListFind(pHead,5);
	//pos1->_pNext=pos2;              //此时链表已带环        
	if(IsCircle(pHead))
	{	
		printf("链表带环\n");
		printf("环长是%d\n",GetCirclelength(pHead));
		pEnterNode=GetEnterNode(pHead);

	}
	else
		printf("链表不带环\n");
}

testSlist.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Slist.h"

int main()
{
	//testSListPushPop();
	//testJosephCircle();
	//testBubbleSort();
	//testReverseSList();
	//testReverseSListOP();
	testCopyComplexList();
	//testMergeSList();
	//testSListInsert();
	//testSListErase();
	//testFindMiddleNode();
	//testFindLastKNode();
	//testDeleteNotTailNode();
	//testIsCrossWithoutCircle();  
        //testIsCircle();
	//testIsCross();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值