单链表中的一些经典问题--约瑟夫环,逆序,查找,复杂链表复制,链表带环问题

对于单链表中一些经典问题的总结,所涉及的问题主要包括以下几点:

     1. 从尾到头打印单链表-->2. 删除无头单链表的非尾结点-->3. 在无头单链表pos位置前插入值为结点data的结点-->4. 用单链表模拟实现约瑟夫环-->5. 使用冒泡排序方法对单链表进行排序-->6. 单链表的逆置--三个指针-->7. 单链表的逆置--头插法-->8. 合并两个有序链表,合并之后依然有序-->9. 查找链表的中间结点,要求只能遍历一次链表-->10. 查找链表的倒数第K个结点(遍历一次链表)--->11. 删除链表的倒数第K个结点-->12. 判断单链表是否相交?链表不带环 -->13. 求不带环单链表相交交点-->14. 判断链表是否带环-->15. 求环的长度-->16. 求环的入口点-->17. 判断链表是否带环,链表可能带环-->18. 复杂链表的复制-->19. 求两个已排单链表中相同的数据

下面是一些C语言代码的实现:

slist.c

 
 
#define _CRT_SECURE_NO_WARNINGS 0;
#include "slist.h"

// 链表初始化 
void SListInit(pNode* pHead)
{
	assert(pHead);
	*pHead = NULL;
}
// 获取结点 
pNode BuySListNode(DataType data)
{
	pNode pNewNode = (pNode)malloc(sizeof(Node));
	if (NULL == pNewNode)
		exit(EXIT_FAILURE);

	pNewNode->_pNext = NULL;
	pNewNode->_data = data;
	return pNewNode;
}

//打印单链表
void printSList(pNode pHead)
{
	pNode pCur= pHead;
	if (NULL == pHead)
		return;

	while (pCur)
	{
		printf("%d->", pCur->_data);
		pCur=pCur->_pNext;
	}
	printf("NULL\n");
}
// 尾插 
void SListPushBack(pNode* pHead, DataType data)
{
	assert(pHead);
	pNode pCur = NULL;
	pNode pNewNode = BuySListNode(data);
	if (NULL == *pHead)
	{
		*pHead = pNewNode;
	}
	else
	{
		pCur = *pHead;
		while (pCur->_pNext)
		{
			pCur = pCur->_pNext;
		}
		pCur->_pNext = pNewNode;
	}
}

// 从尾到头打印单链表  
void PrintListFromTail2Head(pNode pHead)
{
	pNode pCur = pHead;
	if (pCur)
	{
		PrintListFromTail2Head(pCur->_pNext);
		printf("%d->", pCur->_data);
	}
}

// 删除无头单链表的非尾结点,要求:不能遍历链表 
void DeleteNotTailNode(pNode pos)
{
	pNode pCur = NULL;
	if (NULL == pos || NULL==pos->_pNext)
		return;

	pCur = pos->_pNext;
	pos->_data=pos->_pNext->_data;
	pos->_pNext = pos->_pNext->_pNext;
	free(pCur); 
}
// 在无头单链表pos位置前插入值为结点data的结点 (不遍历链表)
void InsertPosFront(pNode pos, DataType data)
{
	pNode pNewNode = NULL;
	if (NULL == pos)
		return;

	pNewNode = BuySListNode(pos->_data);
	pNewNode->_pNext = pos->_pNext;
	pos->_pNext = pNewNode;
	pos->_data = data;
}

// 用单链表模拟实现约瑟夫环 
void JosephCircle(pNode* pHead, const int M)
{
	assert(pHead);
	pNode pCur = NULL;
	int count = 0;
	SListPushBack(pHead, 1);    //开始构环
	SListPushBack(pHead, 2);
	SListPushBack(pHead, 3);
	SListPushBack(pHead, 4);
	pCur = *pHead;
	while (pCur->_pNext)
	{
		pCur = pCur->_pNext;
	}
	pCur->_pNext = *pHead;

	pCur = *pHead;
	while (pCur->_pNext!=pCur)
	{
		count = M;       //报数 -->删结点
		while (--count)
		{
			pCur = pCur->_pNext;
		}
		DeleteNotTailNode(pCur);
	}
	pCur->_pNext = NULL;   // 解环
	*pHead = pCur;
}


// 求链表中结点的个数 
int SListSize(pNode pHead)
{
	int count = 0;
	if (NULL == pHead)
		return count;
	else
	{
		while (pHead)
		{
			count++;
			pHead = pHead->_pNext;
		}
		return count;
	}
}
// 使用冒泡排序方法对单链表进行排序 
void BubbleSort(pNode pHead)
{
	int ret = 0;
	int i = 0,j = 0,cur=0;
	pNode pCur = NULL;
	if (NULL == pHead)
		return;
  
	ret = SListSize(pHead);
	
	for (i = 0; i < ret - 1; i++)
	{
		cur = 0;
		pCur = pHead;
		for (j = 0; j < ret - 1 - i; j++)
		{
			if ((pCur->_data)>(pCur->_pNext->_data))
			{
				cur = 1;
				int tmp = pCur->_data;
				pCur->_data = pCur->_pNext->_data;
				pCur->_pNext->_data = tmp;
			}
			pCur = pCur->_pNext;
		}

		if (cur == 0)
			return;
	}
}

// 单链表的逆置--三个指针 
void ReverseSList(pNode* pHead)
{
	assert(pHead);
	pNode pCur = NULL;
	pNode pPre = NULL;
	pNode pNext = NULL;
	if (NULL == pHead)
		return;

	pCur = *pHead;
	while (pCur)
	{
		pNext = pCur->_pNext;
		pCur->_pNext = pPre;
		pPre = pCur;
		pCur = pNext;
	}
	*pHead = pPre;
}
// 头插 
void SListPushFront(pNode* pHead, DataType data)
{
	assert(pHead);
	pNode pNewNode = BuySListNode(data);

	pNewNode->_pNext = *pHead;
	*pHead = pNewNode;
}
// 单链表的逆置--头插法 
pNode ReverseSListOP(pNode pHead)
{
	pNode pNewNode = NULL;
	pNode pCur = pHead;

	while (pCur)
	{
		SListPushFront(&pNewNode,pCur->_data);
		pCur = pCur->_pNext;
	}
	return pNewNode;
}

// 合并两个有序链表,合并之后依然有序 
pNode MergeSList(pNode pHead1, pNode pHead2)
{
	pNode pCur1 = NULL;
	pNode pCur2 = NULL;
	pNode pNewNode = NULL;
	pNode pTail = NULL;
	if (NULL == pHead1)     //链表1为空的话返回链表2
		return pHead2;
	if (NULL == pHead2)    //链表2为空的话返回链表1
		return pHead1;

	pCur1 = pHead1;
	pCur2 = pHead2;
	if ((pCur1->_data) < (pCur2->_data))    //比较两个头结点大小,让pNewNode指针指向值小的结点
	{
		pNewNode = pCur1;
		pCur1 = pCur1->_pNext;
	}
	else
	{
		pNewNode = pCur2;
		pCur2 = pCur2->_pNext;
	}

	pTail = pNewNode;
	while (pCur1 && pCur2)                //开始合并后面的结点
	{
		if ((pCur1->_data) < (pCur2->_data))
		{
			pTail->_pNext = pCur1;
			pTail = pTail->_pNext;
			pCur1 = pCur1->_pNext;
		}
		else
		{
			pTail->_pNext = pCur2;
			pTail = pTail->_pNext;
			pCur2 = pCur2->_pNext;
		}
	}
	if (pCur1)                          //链表1不为空
	{
		pTail->_pNext = pCur1;
	}
	if (pCur2)                         //链表2不为空
	{
		pTail->_pNext = pCur2;
	}

	return pNewNode;
}


// 查找链表的中间结点,要求只能遍历一次链表 
pNode FindMiddleNode(pNode pHead)
{
	assert(pHead);
	pNode pFast = pHead;
	pNode pSlow = pHead;

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

	while (K--)
	{
		pFast = pFast->_pNext;
	}
	while (pFast)
	{
		pFast = pFast->_pNext;
		pSlow = pSlow->_pNext;
	}
	return pSlow;
}
// 删除链表的倒数第K个结点,要求只能遍历链表一次 
void DeleteLastKNode(pNode *pHead, int K)
{
	assert(pHead);
	pNode pCur = NULL;
	pNode pTest = NULL;	
	pCur=FindLastKNode(*pHead, K);
	if (NULL == pCur)
		return;

	if (pCur == *pHead)  //假如是删除头结点
	{
		*pHead = pCur->_pNext;
		free(pCur);
		pCur = NULL;
		return;
	}
	else            //删除其他结点
	{
		pTest = *pHead;
		while (pTest->_pNext != pCur)
		{
			pTest = pTest->_pNext;
		}
		pTest->_pNext = pCur->_pNext;
		free(pCur);
	}
}
// 判断单链表是否相交?链表不带环 --(三种情况: 1-->尾点相交2-->中间任意位置结点相交, 3-->头结点相交)  
pNode IsCrossWithoutCircle(pNode pHead1, pNode pHead2)
{
	int size = 0;
	pNode pCur1 = NULL;
	pNode pCur2 = NULL;
	if (NULL == pHead1 || NULL==pHead2)
		return NULL;

	pCur1 = pHead1;
    pCur2 = pHead2;
	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)
		{
			if (pCur1 == pCur2)
				return pCur1;

			pCur1 = pCur1->_pNext;
			pCur2 = pCur2->_pNext;
		}
		return NULL;
	}
}
// 求不带环单链表相交交点 
pNode GetCrossNode(pNode pHead1, pNode pHead2)
{
	pNode pCur=IsCrossWithoutCircle(pHead1, pHead2);
	return pCur;
}
// 判断链表是否带环 
pNode IsCircle(pNode pHead)
{
	pNode pFast = NULL;
	pNode pSlow = NULL;
	if (NULL == pHead)
		return NULL;

	pFast = pHead;
	pSlow = pHead;
	while (pFast && pFast->_pNext)
	{
		pFast = pFast->_pNext->_pNext;
		pSlow = pSlow->_pNext;
		if (pFast == pSlow)
			return pSlow;
	}
	return NULL;
}
// 求环的长度 
int GetCircleLen(pNode pHead)
{
	pNode pRet=IsCircle(pHead);
	pNode pCur = pRet;
	int count = 1;
	if (NULL == pRet)
		return 0;

	while (pCur->_pNext != pRet)
	{
		count++;
		pCur = pCur->_pNext;
	}
	return count;
}

// 求环的入口点
pNode GetEnterNode(pNode pHead)
{
	pNode pRet=IsCircle(pHead);
	pNode pCur1 = pHead;
	pNode pCur2 = pRet;
	if (NULL == pRet)
		return NULL;

	while (pCur1 != pCur2)
	{
		pCur1 = pCur1->_pNext;
		pCur2 = pCur2->_pNext;
	}
	return pCur2;
}

// 判断链表是否相交,若相交求交点
pNode IsListCrossWithCircle(pNode pHead1, pNode pHead2)
{
	pNode pCur1 = IsCircle(pHead1);   //判断是否带环
	pNode pCur2 = IsCircle(pHead2);
	if (NULL == pCur1 && NULL == pCur2)  //两个都不带环
	{
		pNode pRet=IsCrossWithoutCircle(pHead1, pHead2);
		return pRet;
	}
	else if (pCur1 != NULL && pCur2 != NULL)  //两个都带环 (可能情况:环内相交,环外相交)
	{
		pNode pEnterNode1= GetEnterNode(pHead1);
		pNode pEnterNode2 = GetEnterNode(pHead2);
		int count1 = 1;
		int count2 = 1;
		int size = 0; 
		pNode pCur3 = pHead1;
		pNode pCur4 = pHead2;
		if (pEnterNode1 == pEnterNode2)  //环外相交
		{
			while (pHead1 != pEnterNode1)
			{
				count1++;
				pHead1 = pHead1->_pNext;
			}
			while (pHead2 != pEnterNode1)
			{
				count2++;
				pHead2 = pHead2->_pNext;
			}
			size = count1 - count2;

			if (size > 0)
			{
				while (size--)
				{
					pCur3 = pCur3->_pNext;
				}

				while (pCur3 && pCur4)
				{
					if (pCur3 == pCur4)
						return pCur3;

					pCur3 = pCur3->_pNext;
					pCur4 = pCur4->_pNext;
				}
				return NULL;
			}
			else if (size < 0)
			{
				while (size++)
				{
					pCur4 = pCur4->_pNext;
				}

				while (pCur4 && pCur3)
				{
					if (pCur3 == pCur4)
						return pCur3;

					pCur3 = pCur3->_pNext;
					pCur4 = pCur4->_pNext;
				}
				return NULL;
			}
		}
		else                          //环内相交
		{
			pNode pE1 = pEnterNode1;
			pNode pE2 = pEnterNode2;
			do
			{
				if (pE1 == pE2)
					return pE1;

				pE1 = pE1->_pNext;
				pE2 = pE2->_pNext->_pNext;
			}while (pE1!= pEnterNode1);

			return NULL;
		}
	}
	else                          //其他情况
		return NULL;
}
// 复杂链表初始化 
void CListNodeInit(PCListNode* pHead)
{
	assert(pHead);
	*pHead = NULL;
}
// 复杂链表获取结点 
PCListNode BuyCListNode(DataType data)
{
	PCListNode pNewNode = (PCListNode)malloc(sizeof(CListNode));
	if (NULL == pNewNode)
		exit(EXIT_FAILURE);

	pNewNode->_pNext = NULL;
	pNewNode->_pRandom = NULL;
	pNewNode->data = data;
	return pNewNode;
}
//复杂链表的尾插
void CListNodePushBack(PCListNode *pHead, DataType data)
{
	assert(pHead);
	PCListNode pCur = NULL;
	PCListNode pNewNode = BuyCListNode(data);
	if (NULL == *pHead)
	{
		*pHead = pNewNode;
	}
	else
	{
		pCur = *pHead;
		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);    //复制数据到data
		pNewNode->_pNext = pCur->_pNext;
		pCur->_pNext = pNewNode;
		pCur = pNewNode->_pNext;
	}

	p1 = pHead;
	while (p1)                        //给random赋值
	{
		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;
}

//两个已排单链表中相同的数据
pNode UnionSet(pNode pHead1, pNode pHead2)
{
	pNode pNewNode = NULL;
	pNode pCur1 = NULL;
	pNode pCur2 = NULL;
	pNode pTail = NULL;
	int data = 0;
	if (NULL == pHead1 || NULL == pHead2)
		return NULL;

	pCur1 = pHead1;
	pCur2 = pHead2;
	pTail = pNewNode;
	while (pCur1 && pCur2)
	{
		if ((pCur1->_data) < (pCur2->_data))        
		{
			pCur1 = pCur1->_pNext;
		}
		else if ((pCur1->_data) > (pCur2->_data))
		{
			pCur2 = pCur2->_pNext;
		}
		else
		{
			if (NULL == pNewNode)           //判断新结点是否为空
			{
				pNewNode = BuySListNode(pCur2->_data);
				pTail = pNewNode;
				pCur1 = pCur1->_pNext;
				pCur2 = pCur2->_pNext;
			}
			else                           //新链表非空
			{
				pTail = pTail->_pNext;
				pTail = BuySListNode(pCur1->_data);
				pCur1 = pCur1->_pNext;
				pCur2 = pCur2->_pNext;
			}
		}
	}
	return pNewNode;
}


test.c

 
 
#define _CRT_SECURE_NO_WARNINGS 0;
#include "slist.h"

void testSListPushBack()
{
	pNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	SListPushBack(&pHead, 5);
}
void testPrintListFromTail2Head()
{
	pNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	SListPushBack(&pHead, 5);
	PrintListFromTail2Head(pHead);
}

void testDeleteNotTailNode()
{
	pNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	SListPushBack(&pHead, 5);
	DeleteNotTailNode(pHead->_pNext);
	DeleteNotTailNode(pHead);
	DeleteNotTailNode(pHead->_pNext->_pNext);

}
void testInsertPosFront()
{
	pNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	SListPushBack(&pHead, 5);
	printSList(pHead);
	InsertPosFront(pHead->_pNext->_pNext->_pNext->_pNext, 0);
	printSList(pHead);
	InsertPosFront(pHead, 0);
	printSList(pHead);
	InsertPosFront(pHead->_pNext->_pNext, 6);
	printSList(pHead);

}
void testJosephCircle()
{
	pNode pHead;
	SListInit(&pHead);         
	JosephCircle(&pHead, 3);
	printSList(pHead);

}
void testBubbleSort()
{
	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);
	printSList(pHead);
	BubbleSort(pHead);
	printSList(pHead);
}

void testReverseSList()
{
	pNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	printSList(pHead);
	ReverseSList(&pHead);
	printSList(pHead);
}
void testReverseSListOP()
{
	pNode pHead;
	pNode pCur = NULL;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	printSList(pHead);
	pCur=ReverseSListOP(pHead);
	printSList(pCur);
}

void testFindMiddleNode()
{
	pNode pHead;
	pNode pCur = NULL;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	printSList(pHead);
	pCur=FindMiddleNode(pHead);
	printf("%d\n", pCur->_data);
}
void testFindLastKNode()
{
	pNode pHead;
	pNode pCur = NULL;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	printSList(pHead);
	pCur=FindLastKNode(pHead, 1);
	pCur = FindLastKNode(pHead,3);
	pCur = FindLastKNode(pHead, 4);
	printf("%d\n", pCur->_data);
}
void testDeleteLastKNode()
{
	pNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	printSList(pHead);
	DeleteLastKNode(&pHead, 4);
	DeleteLastKNode(&pHead, 1);
	DeleteLastKNode(&pHead, 3); 
	printSList(pHead);;
}
void testIsCrossWithoutCircle()
{
	pNode pHead;
	pNode pHead2;
	pNode ret = NULL;
	pNode pCur = NULL;
	pNode pCur2 = NULL;
	SListInit(&pHead);
	SListInit(&pHead2);
	SListPushBack(&pHead, 1); 
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);

	SListPushBack(&pHead2, 1);
	SListPushBack(&pHead2, 2);
	SListPushBack(&pHead2, 3);
	SListPushBack(&pHead2, 4);
	pCur = pHead;
	pCur2 = pHead2;
	while (pCur->_pNext)
	{
		pCur = pCur->_pNext;
	}
	pCur->_pNext = pCur2;   //头结点相交场景
	pCur->_pNext = pCur2->_pNext->_pNext;   //中间结点相交场景
	while (pCur2->_pNext)
	{
		pCur2 = pCur2->_pNext;
	}
	pCur->_pNext = pCur2;      //尾点相交场景
	ret=IsCrossWithoutCircle(pHead, pHead2);  //测试构造不相交场景
	ret = IsCrossWithoutCircle(pHead, pHead2);//测试尾点相交场景
	ret = IsCrossWithoutCircle(pHead, pHead2);//测试中间结点相交
	ret = IsCrossWithoutCircle(pHead, pHead2);//测试头结点相交
	ret = IsCrossWithoutCircle(pHead, pHead2);//测试一个链表位空

}

void testIsCircle()
{
	pNode pHead;
	pNode pRet = NULL;
	pNode pCur = NULL;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	pCur = pHead;
	while (pCur->_pNext)
	{
		pCur = pCur->_pNext;
	}
	pCur->_pNext = pHead; //指向头结点
	pCur->_pNext = pHead->_pNext->_pNext;  //指向中间结点
	pRet=IsCircle(pHead); //测试没有环的场景
	pRet= IsCircle(pHead);//测试指向中间结点
	pRet = IsCircle(pHead);//测试指向头结点
}
void testGetCircleLen()   //测试环的长度以及环的入口点
{
	pNode pHead;
	int ret = 0;
	pNode pCur = NULL;
	pNode pRet = NULL;
	SListInit(&pHead);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	pCur = pHead;
	while (pCur->_pNext)
	{
		pCur = pCur->_pNext;
	}
	pCur->_pNext = pHead->_pNext->_pNext;  //指向中间结点
	pCur->_pNext = pHead; //指向头结点
	ret=GetCircleLen(pHead);
	pRet = GetEnterNode(pHead);
}
void testIsListCrossWithCircle()
{
	pNode pHead;
	pNode pHead2;
	pNode pRet = NULL;
	pNode pCur1 = NULL;
	pNode pCur2 = NULL;
	SListInit(&pHead);
	SListInit(&pHead2);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 2);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 4);
	

	SListPushBack(&pHead2, 5);
	SListPushBack(&pHead2, 6);
	SListPushBack(&pHead2, 7);
	SListPushBack(&pHead2, 8);
	SListPushBack(&pHead2, 9);
	SListPushBack(&pHead2, 0);
	SListPushBack(&pHead2, 10);
	 pCur1 = pHead;
	 pCur2 = pHead2;
	while (pCur1->_pNext)     
	{
		pCur1 = pCur1->_pNext;
	}
	while (pCur2->_pNext)
	{
		pCur2 = pCur2->_pNext;
	}
	pCur2->_pNext = pHead2->_pNext->_pNext;//测试一个带环一个不带环
	pCur2->_pNext = pHead2->_pNext->_pNext;        //测试两带环环内相交场景                                                  
	pCur1->_pNext = pHead2->_pNext->_pNext->_pNext;
	pCur2->_pNext = pHead2->_pNext->_pNext->_pNext;  //测试两带环环外相交场景
	pCur1->_pNext = pHead2->_pNext->_pNext;
	pCur1->_pNext = pHead;  //测试两带环链表不相交场景
	pCur2->_pNext = pHead2;  
	pCur1->_pNext = pCur2->_pNext;//不带环中间结点相交
	pCur1->_pNext = pHead2; //不带环指向头结点
	pCur1->_pNext = pCur2;  //不带环尾结点相交
	pRet=IsListCrossWithCircle(pHead, pHead2);
}
void testCopyComplexList()
{
	PCListNode pHead;
	PCListNode pCur = NULL;
	PCListNode pRet = NULL;
	CListNodeInit(&pHead);
	CListNodePushBack(&pHead, 1);
	CListNodePushBack(&pHead, 2);
	CListNodePushBack(&pHead, 3);
	CListNodePushBack(&pHead, 4);
	pCur = pHead;
	pCur->_pRandom = pCur->_pNext->_pNext;          //给链表random赋值
	pCur->_pNext->_pRandom = pCur;
	pCur->_pNext->_pNext->_pRandom = pCur->_pNext->_pNext;
	pCur->_pNext->_pNext->_pNext->_pRandom = NULL;
	pRet=CopyComplexList(pHead);
}

void testMergeSList()
{
	pNode pHead;
	pNode pHead2;
	pNode pRet = NULL;
	SListInit(&pHead);
	SListInit(&pHead2);
	SListPushBack(&pHead, 11);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 5);
	SListPushBack(&pHead, 7);
	printSList(pHead);

	SListPushBack(&pHead2, 1);
	SListPushBack(&pHead2, 4);
	SListPushBack(&pHead2, 6);
	SListPushBack(&pHead2, 8);
	SListPushBack(&pHead2, 10);
	printSList(pHead2);
	pRet=MergeSList(pHead, pHead2);
	printSList(pRet);
}
void testUnionSet()
{
	pNode pHead;
	pNode pHead2;
	pNode pRet = NULL;
	SListInit(&pHead);
	SListInit(&pHead2);
	SListPushBack(&pHead, 1);
	SListPushBack(&pHead, 3);
	SListPushBack(&pHead, 5);
	SListPushBack(&pHead, 7);
	printSList(pHead);

	SListPushBack(&pHead2, 1);
	SListPushBack(&pHead2, 2);
	SListPushBack(&pHead2, 3);
	SListPushBack(&pHead2, 6);
	SListPushBack(&pHead2, 7);
	printSList(pHead2);
	pRet=UnionSet(pHead, pHead2);
	printSList(pRet);
}
void testSlist()
{
	testSListPushBack();
	testPrintListFromTail2Head();
	testDeleteNotTailNode();
	testInsertPosFront();
	testJosephCircle();
	testBubbleSort();
	testReverseSList();
	testReverseSListOP();
	testFindMiddleNode();
	testFindLastKNode();
	testDeleteLastKNode();
	testIsCrossWithoutCircle();
	testIsCircle();
	testGetCircleLen();
	testIsListCrossWithCircle();
	testCopyComplexList();
	testMergeSList();
	testUnionSet();

}
int main()
{
	testSlist();
	system("pause");
	return 0;
}


slist.h

 
 
#pragma once

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

typedef int DataType;
typedef struct CListNode
{
	DataType data;
	struct CListNode* _pNext;
	struct CListNode* _pRandom;
}CListNode, *PCListNode;

typedef struct ListNode
{
	DataType _data;
	struct ListNode* _pNext;
}Node,*pNode;

void SListInit(pNode* pHead);
void printSList(pNode pHead);
void SListPushBack(pNode* pHead, DataType data);
pNode BuySListNode(DataType data);
void PrintListFromTail2Head(pNode pHead);
void DeleteNotTailNode(pNode pos);
void InsertPosFront(pNode pos, DataType data);
void JosephCircle(pNode* pHead, const int M);
void BubbleSort(pNode pHead);
int SListSize(pNode pHead);
void ReverseSList(pNode* pHead);
pNode ReverseSListOP(pNode pHead);
void SListPushFront(pNode* pHead, DataType data);
pNode MergeSList(pNode pHead1, pNode pHead2);
pNode FindMiddleNode(pNode pHead);
pNode FindLastKNode(pNode pHead, int K);
void DeleteLastKNode(pNode *pHead, int K);
pNode IsCrossWithoutCircle(pNode pHead1, pNode pHead2);
pNode IsCircle(pNode pHead);
int GetCircleLen(pNode pHead);
pNode GetEnterNode(pNode pHead);
pNode IsListCrossWithCircle(pNode pHead1, pNode pHead2);
void CListNodeInit(PCListNode* pHead);
PCListNode BuyCListNode(DataType data);
void CListNodePushBack(PCListNode *pHead, DataType data);
PCListNode CopyComplexList(PCListNode pHead);
pNode UnionSet(pNode pHead1, pNode pHead2);


顺序表和链表的一些区别:

1--->顺序表支持随机访问,而单链表并不支持;

2-->顺序表插入和删除数据效率很低,时间复杂度为o(N)(尾插尾删除外),单链表插入和删除效率更高;

3-->顺序表CPU高速缓存效率更高,单链表CPU高速缓存效率低;

4--->顺序表尾插尾删还是很方便滴;

5-->链表容易造成内存碎片


猜你喜欢

转载自blog.csdn.net/eternal_01/article/details/79759473