【C语言】链表 题

Slist.h

#pragma once

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

typedef int DataType;

typedef struct ListNode
{
	DataType data;
	struct ListNode *pNext;
}SListNode, *PSListNode;

//初始化单链表(对于无头结点单链表,该函数没有意义)
void InitList(PSListNode* pHead);

// 销毁单链表
void DestroyList(PSListNode* pHead);

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

// 尾出
void PopBack(PSListNode* pHead);

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

// 头出
void PopFront(PSListNode* pHead);

// 查找元素data
PSListNode Find(PSListNode pHead, DataType data);

// 删除pos位置的结点
void  Erase(PSListNode* pHead, PSListNode pos);

// 在链表的pos位置插入元素data
void  Insert(PSListNode* pHead, PSListNode pos, DataType data);

//打印
void PrintList(PSListNode pHead);

// 从头至尾打印单链表
void PrintListTailToHead(PSListNode pHead);

// 链表的非头结点前插入元素data
void InsertNotHead(PSListNode pos, DataType data);

// 删除链表的非尾结点
void DelNotTailNode(PSListNode pos);

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

// 约瑟夫环问题
PSListNode JosephusCircle(PSListNode pHead, int M);

//反转(逆置)单链表
void ReverseList(PSListNode *pHead);

//冒泡排序链表
void BubbleSort(PSListNode pHead);

//合并两个有序链表
PSListNode MergeList(PSListNode pList1, PSListNode pList2);

//删除链表的倒数第K个结点
void DelNodeK(PSListNode* pHead, int K);

//求环的长度
int GetCyleLen(PSListNode pMeetNode);

// 判断链表是否带环,若带环返回环入口点
PSListNode CheckCycle(PSListNode pHead);

//获取环入口点
PSListNode GetCircleEntryNode(PSListNode pHead, PSListNode pMeetNode);

//判断两个链表是否相交,假设两个链表都不带环
int CheckCross(PSListNode pList1Head, PSListNode pList2Head);

//判断两个链表是否相交
int IsListCroseWithCycle(PSListNode pL1, PSListNode pL2);

SList.c

#include "SList.h"

//初始化
void InitList(PSListNode* pHead)
{
	*pHead = NULL;
}

//打印
void PrintList(PSListNode pHead)
{
	PSListNode pCurNode = pHead;
	while(pCurNode)
	{
		printf("%d->", pCurNode->data);
		pCurNode = pCurNode->pNext;
	}
	printf("NULL\n");
}

PSListNode BuyNode(DataType data)
{
	PSListNode pTemp = (PSListNode)malloc(sizeof(SListNode));
	if(NULL == pTemp)
	{
		return NULL;
	}
	pTemp->data = data;
	pTemp->pNext = NULL;
	return pTemp;
}

//尾插
void PushBack(PSListNode* pHead, DataType data)
{
	PSListNode pNode = *pHead;
	if (NULL == *pHead)//当链表是空链表时
	{
		*pHead = BuyNode(data);
	}
	else
	{
		while(pNode->pNext)
		{
			pNode = pNode->pNext;
		}

		pNode->pNext = BuyNode(data);
	}
}

// 尾出
void PopBack(PSListNode* pHead)
{
	PSListNode pCurNode = *pHead;//当前结点
	PSListNode pPreNode = pCurNode;//前一个结点
	assert(pHead);
	if(NULL == *pHead)
	{
		return;
	}
	else if((*pHead)->pNext == NULL)//只有一个结点的情况
	{
		free(*pHead);
		*pHead = NULL;
		return;
	}
	while (pCurNode->pNext)//找尾
	{
		pPreNode = pCurNode;
		pCurNode = pPreNode->pNext;
	}

	free(pCurNode);
	pPreNode->pNext = NULL;
}

//头插
void PushFront(PSListNode* pHead, DataType data)
{
	PSListNode pNewNode = NULL;
	assert(pHead);
	if(NULL == *pHead)
	{
		return;
	}
	pNewNode = BuyNode(data);
	if(pNewNode != NULL)
	{
		pNewNode->pNext = *pHead;
		*pHead = pNewNode;
	}
}

// 头出
void PopFront(PSListNode* pHead)
{
	PSListNode pCurNode = *pHead;
	assert(pHead);
	if(NULL == *pHead)
	{
		return;
	}
	*pHead = pCurNode->pNext;
	free(pCurNode);
}

// 查找元素data
PSListNode Find(PSListNode pHead, DataType data)
{
	PSListNode pCurNode = pHead;
	while(pCurNode)
	{
		if(data == pCurNode->data)
		{
			return pCurNode;
		}
		pCurNode = pCurNode->pNext;
	}
	return NULL;
}

// 删除pos位置的结点
void  Erase(PSListNode* pHead, PSListNode pos)
{
	PSListNode pPreNode = *pHead;
	assert(pHead);
	assert(pos);
	if(NULL == *pHead)
	{
		return;
	}
	if(pos == *pHead)//如果pos是头结点
	{
		*pHead =pos->pNext;
		free(pos);
		return;
	}
	while (pPreNode)
	{
		if(pPreNode->pNext == pos)
		{
			pPreNode->pNext = pos->pNext;
			free(pos);
			return;
		}
		pPreNode = pPreNode->pNext;
	}
}

// 在链表的pos位置插入元素data
void  Insert(PSListNode* pHead, PSListNode pos, DataType data)
{
	PSListNode pNewNode = NULL;
	assert(pHead);
	assert(pos);
	if(NULL == *pHead)
	{
		return;
	}
	pNewNode = BuyNode(data);
	if(NULL != pNewNode)
	{
		pNewNode->pNext = pos->pNext;
		pos->pNext = pNewNode;
	}
}

//销毁
void DestroyList(PSListNode* pHead)
{
	PSListNode pPreNode = NULL;
	PSListNode pCurNode = NULL;
	assert(pHead);
	pCurNode = *pHead;
	while (pCurNode)
	{
		pPreNode = pCurNode;
		pCurNode = pCurNode->pNext;
		free(pPreNode);
	}
	*pHead =NULL;
}

// 从头至尾打印单链表
void PrintListTailToHead(PSListNode pHead)
{
	if(NULL != pHead)
	{
		PrintListTailToHead(pHead->pNext);
		printf("%d", pHead->data);
	}
}

// 链表的非头结点前插入元素data
void InsertNotHead(PSListNode pos, DataType data)
{
	PSListNode pNewNode = NULL;
	assert(pos);
	pNewNode = BuyNode(data);
	if(NULL != pNewNode)
	{
		pNewNode->pNext = pos->pNext;
		pos->pNext = pNewNode;
		pos->data = data;
	}
}

// 删除链表的非尾结点
void DelNotTailNode(PSListNode pos)
{
	PSListNode pDelNode = NULL;
	assert(pos);
	assert(pos->pNext);
	pDelNode = pos->pNext;
	pos->data = pDelNode->pNext->data;
	pos->pNext = pDelNode->pNext;
	free(pDelNode);
}

// 查找链表的中间结点,要求只遍历一次链表
PSListNode FindMidNode(PSListNode pHead)
{
	PSListNode pFast = pHead;
	PSListNode pSlow = pHead;
	while((pFast != NULL)&&(pFast->pNext != NULL))
	{
		pFast = pFast->pNext->pNext;
		pSlow = pSlow->pNext;
	}
	return pSlow;
}

//约瑟夫环问题
PSListNode JosephusCircle(PSListNode pHead, int M)
{
	PSListNode pNode = pHead;
	PSListNode pDelNode = NULL;
	int K = M;
	if((NULL == pHead)||(M <= 0))
	{
		return NULL;
	}

	while(pNode->pNext != pNode)
	{
		K = M;
		while(--K)
		{
			pNode = pNode->pNext;
		}
		pDelNode = pNode->pNext;
		pNode->data = pDelNode->pNext->data;
		pNode->pNext = pDelNode->pNext;
		free(pDelNode);
	}
	return pNode;
}

//反转(逆置)单链表
void ReverseList(PSListNode *pHead)
{
	PSListNode pPreNode = NULL;
	PSListNode pCurNode = NULL;
	PSListNode pNewHead = NULL;
	assert(pHead);
	if((NULL == *pHead)||(NULL == (*pHead)->pNext))
	{
		return;
	}
	pCurNode = *pHead;
	while(pCurNode)
	{
		pPreNode = pCurNode;
		pCurNode = pCurNode->pNext;
		pPreNode->pNext = pNewHead;
		pNewHead = pPreNode;
	}
	*pHead = pNewHead;
}

//冒泡排序链表
void BubbleSort(PSListNode pHead)
{
	PSListNode pNode = NULL;
	PSListNode pTailNode = NULL;
	if(NULL == pHead)
	{
		return;
	}
	while(pHead != pTailNode)
	{
		pNode = pHead;
		while(pNode->pNext != pTailNode)
		{
			if(pNode->data < pNode->pNext->data)
			{
				DataType temp = pNode->data;
				pNode->data = pNode->pNext->data;
				pNode->pNext->data = temp;
			}
			pNode = pNode->pNext;
		}
		pTailNode = pNode;
	}
}

//合并两个有序链表
PSListNode MergeList(PSListNode pList1Head, PSListNode pList2Head)
{
	PSListNode pNewHead = NULL;
	PSListNode pList1Node = pList1Head;
	PSListNode pList2Node = pList2Head;
	PSListNode pNode = NULL;
	PSListNode pTailNode = NULL;
	if(NULL == pList1Head)//List1为空链表时
	{
		return pList2Head;
	}
	if(NULL == pList2Head)//List2为空链表时
	{
		return pList1Head;
	}
	if (pList1Node->data < pList2Node->data)
	{
		pNode = pList1Node;
		pList1Node = pList1Node->pNext;
	}
	else
	{
		pNode = pList2Node;
		pList2Node = pList2Head->pNext;
	}
	pNewHead = pNode;
	pTailNode = pNode;
	while(pList1Node && pList2Node)
	{
		if(pList1Node->data < pList2Node->data)
		{
			pNode = pList1Node;
			pList1Node = pList1Node->pNext;
		}
		else
		{
			pNode = pList2Node;
			pList2Node = pList2Node->pNext;
		}
		pTailNode->pNext = pNode;
		pTailNode = pTailNode->pNext;
	}
	if(NULL == pList1Node)
	{
		pTailNode->pNext = pList2Node;
	}
	else
	{
		pTailNode->pNext = pList1Node;
	}
	return pNewHead;
}

//删除链表的倒数第K个结点
void DelNodeK(PSListNode* pHead, int K)
{
	PSListNode pFast = NULL;
	PSListNode pSlow = NULL;
	if((pHead == NULL)||(K <= 0))
	{
		return;
	}
	pFast = *pHead;
	pSlow = *pHead;
	while(--K)
	{
		if(pFast == NULL)
		{
			return;
		}
		pFast = pFast->pNext;
	}
	while(pFast->pNext)
	{
		pFast = pFast->pNext;
		pSlow = pSlow->pNext;
	}
	Erase(pHead, pSlow);
}

//求环的长度
int GetCyleLen(PSListNode pMeetNode)
{
	int iLen = 1;
	PSListNode pNode = NULL;
	if(NULL == pMeetNode)
	{
		return 0;
	}
	while(pNode->pNext != pMeetNode)
	{
		iLen++;
	}
	return iLen;
}

// 判断链表是否带环,若带环返回相遇结点
PSListNode CheckCycle(PSListNode pHead)
{
	PSListNode pFast = NULL;
	PSListNode pSlow = NULL;
	if(NULL == pHead)
	{
		return NULL;
	}
	while((pFast)&&(pFast->pNext))
	{
		pFast = pFast->pNext->pNext;
		pSlow = pSlow->pNext;
		if(pFast == pSlow)
		{
			return pSlow;
		}
	}
	return NULL;
}

//获取环入口点
PSListNode GetCircleEntryNode(PSListNode pHead, PSListNode pMeetNode)
{
	PSListNode pNode1 = pHead;
	PSListNode pNodeM = pMeetNode;
	if (pHead == NULL || pMeetNode == NULL)
	{
		return NULL;
	}

	while (pNode1 != pNodeM)
	{
		pNode1 = pNode1->pNext;
		pNodeM = pNodeM->pNext;
	}

	return pNode1;
}

//判断两个链表是否相交(假设两个链表都不带环)
int CheckCross(PSListNode pList1Head, PSListNode pList2Head)
{
	PSListNode pList1Node = pList1Head;
	PSListNode pList2Node = pList2Head;
	if((NULL == pList1Head)||(NULL == pList2Head))
	{
		return 0;
	}
	while (pList1Node->pNext)
	{
		pList1Node = pList1Node->pNext;
	}
	while(pList2Node->pNext)
	{
		pList2Node = pList2Node->pNext;
	}
	if(pList1Node == pList2Node)
	{
		return 1;//相交
	}
	return 0;//不相交
}

//判断两个链表是否相交
int IsListCroseWithCycle(PSListNode pList1Head, PSListNode pList2Head)
{
	PSListNode pList1MeetNode = NULL;
	PSListNode pList2MeetNode = NULL;
	PSListNode pList1Node =pList1Head;
	PSListNode pList2Node = pList2Head;
	if ((NULL == pList1Head)||(NULL == pList2Head))
	{
		return 0;
	}
	pList1MeetNode = CheckCycle(pList1Head);
	pList2MeetNode = CheckCycle(pList2Head);
	if((NULL == pList1MeetNode)||(NULL == pList2MeetNode))//都不带环
	{
		while(pList1Node->pNext)
		{
			pList1Node = pList1Node->pNext;
		}
		while(pList2Node->pNext)
		{
			pList2Node = pList2Node->pNext;
		}
		if(pList1Node == pList2Node)
		{
			return 1;//相交
		}
		return 0;//不相交
	}
	if((NULL != pList1MeetNode)||(NULL != pList2MeetNode))//都带环
	{
		PSListNode pNode = pList1MeetNode;
		while(pNode->pNext != pList1MeetNode)
		{
			if(pNode == pList2MeetNode)
			{
				return 1;
			}
			pNode = pNode->pNext;
		}
		if(pNode == pList2MeetNode)
		{
			return 1;
		}
		return 0;
	}
	return 0;
}



你可能感兴趣的:(链表,C语言)