单链表的补充操作

约瑟夫环约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依规律重复下去,直到圆桌周围的人全部出列。

算法原理:约瑟夫环运作如下:
1、一群人围在一起坐成[2]  环状(如:N)
2、从某个编号开始报数(如:K)
3、数到某个数(如:M)的时候,此人出列,下一个人重新报数
4、一直循环,直到所有人出列[3]  ,约瑟夫环结束

void JosephCircle(PNode*pHead, size_tM); //约瑟夫环

 

void InsertNotHead(PNodepos, DataTypedata);// 在单链表非头结点前插入结点data

 

void PrintFromTail2Head(PNodepHead);// 使用递归实现从未到头打印单链表

 

void DeleteNotTailNode(PNodepos);// 删除单链表的非尾结点

 

PNode FindMidNode(PNodepHead);// 查找单链表的中间结点,要求只便利一次链表

 

PNode FindLastKNode(PNodepHead, size_tk);// 查找单链表的倒数第K个结点,要求只遍历一次链表

 

void BubbleSort(PNodepHead);// 使用冒泡排序对单链表进行排序

 

int IsListCross(PNodeL1, PNodeL2);// 判断两个单链表是否相交(链表不带环)

 

PNode GetCrossNode(PNodePL1, PNodePL2);// 若不带环的单链表相交,求交点


PNode ReverseList(PNode pHead);// 实现单链表的逆置:使用三个指针

 

void ReverseList_P(PNode* pHead);// 实现单链表的逆置:使用头插法

 

PNode MergeList(PNode pHead1, PNode pHead2);// 合并两个已序单链表,合并后依然有序

 

PNode HasCircle(PNode pHead);// 判断链表是否带环,若带环给出相遇点

 

size_t  GetCircleLen(PNodepMeetNode);// 求环的长度

 

PNode GetEnterNode(PNode pHead, PNode pMeetNode);// 求环的入口点

 

int IsCrossWithCircle(PNode pHead1, PNode pHead2);// 判断链表是否相交,注意:链表可能带环

List.h

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

typedef int DataType;


typedef struct Node
{
	DataType _data;
	struct Node* _pNext;
}Node, *PNode;

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

void InsertNotHead(PNode pos, DataType data);// 在单链表非头结点前插入结点data

void PrintFromTail2Head(PNode pHead);// 使用递归实现从未到头打印单链表

void DeleteNotTailNode(PNode pos);// 删除单链表的非尾结点

PNode FindMidNode(PNode pHead);// 查找单链表的中间结点,要求只便利一次链表

PNode FindLastKNode(PNode pHead, size_t k);// 查找单链表的倒数第K个结点,要求只遍历一次链表

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

int IsListCross(PNode L1, PNode L2);// 判断两个单链表是否相交(链表不带环)

PNode GetCrossNode(PNode PL1, PNode PL2);// 若不带环的单链表相交,求交点

PNode ReverseList(PNode pHead);// 实现单链表的逆置:使用三个指针

void ReverseList_P(PNode* pHead);// 实现单链表的逆置:使用头插法

PNode MergeList(PNode pHead1, PNode pHead2);// 合并两个已序单链表,合并后依然有序

PNode HasCircle(PNode pHead);// 判断链表是否带环,若带环给出相遇点

size_t  GetCircleLen(PNode pMeetNode);// 求环的长度

PNode GetEnterNode(PNode pHead, PNode pMeetNode);// 求环的入口点

int IsCrossWithCircle(PNode pHead1, PNode pHead2);// 判断链表是否相交,注意:链表可能带环


List.c

PNode Back(PNode pHead) // 返回单链表的最后一个结点的位置
{
	if(pHead == NULL)
	{
		return NULL;
	}
	else
	{
		Node* PTailNode = pHead;
		while(PTailNode->_pNext)
		{
			PTailNode = PTailNode->_pNext;
		}
		return PTailNode;
	}
}

void JosephCircle(PNode *pHead, size_t M) //约瑟夫环
{
	size_t m = 0;
	PNode PCurNode = NULL;
	PNode PTailNode = Back(*pHead);
	PTailNode->_pNext = *pHead;
	assert(pHead);
	if(*pHead == NULL || M == 1)
	{
		return;
	}
	else
	{
		PNode PCurNode = *pHead;
		while(PCurNode->_pNext != PCurNode)
		{
			PNode PDelNode = NULL;
			m = M;
			while(--m)
			{
				PCurNode = PCurNode->_pNext;
			}
			PDelNode = PCurNode->_pNext;
			PCurNode->_data = PDelNode->_data;
			PCurNode->_pNext = PDelNode->_pNext;
			free(PDelNode);
			*pHead = PCurNode;
		}
		
		PCurNode->_pNext = NULL;
        
	}
}

void InsertNotHead(PNode pos, DataType data) // 在单链表非头结点前插入结点data
{
	PNode PpreNode = NULL;
	PNode PCurNode = NULL;
	if(pos == NULL || pos->_pNext == NULL)
	{
		return;
	}
	PpreNode = BuyNode(pos->_data);
	PpreNode->_pNext = pos->_pNext;
	pos->_pNext = PpreNode;
	pos->_data = data;
}

PNode FindMidNode(PNode pHead) // 查找单链表的中间结点,要求只便利一次链表
{
	PNode pFast = NULL;
	PNode pSlow = NULL;
	PNode pre = NULL;
	if(pHead == NULL || pHead->_pNext == NULL)
	{
		return NULL;
	}
	else
	{
		pFast = pHead;
		pSlow = pHead;

		while((NULL != pFast) && (NULL != pFast->_pNext))
		{
			pFast = pFast->_pNext->_pNext;
			pre = pSlow;
			pSlow = pSlow->_pNext;
		}
		pSlow->_pNext = NULL;
		return pSlow; //偶数个的前一个中间节点
		/*if(pFast == NULL)
		{
			pre->_pNext = NULL;
			return pre;
		}
		if(pFast->_pNext == NULL)
		{
			pSlow->_pNext = NULL;
			return pSlow; //偶数个的后一个中间节点
		}*/
	}
}


PNode FindLastKNode(PNode pHead, size_t k) // 查找单链表的倒数第K个结点,要求只遍历一次链表
{
	assert(pHead);
	if(k > Size(pHead))
	{
		return NULL;
	}
	else
	{
		PNode PreNode = pHead;
		PNode PCurNode = pHead;

		while(--k)
		{
			PreNode = PreNode->_pNext;
		}

		while(PreNode->_pNext)
		{
			PreNode = PreNode->_pNext;
			PCurNode = PCurNode->_pNext;
		}
		PCurNode->_pNext = NULL;
		return PCurNode;
	}
}


void BubbleSort(PNode pHead) // 使用冒泡排序对单链表进行排序   //降序
{
	if(pHead == NULL || pHead->_pNext == NULL)
	{
		return;
	}
	else
	{
		PNode pTailNode = NULL;
		PNode PpreNode = pHead;
		PNode PCurNode = PpreNode->_pNext;
		while(PCurNode != pHead)
		{
			PpreNode = pHead;
			PCurNode = PpreNode->_pNext;
			while(PCurNode->_pNext != pTailNode)
			{
				if(PCurNode->_data > PpreNode->_data)
				{
					DataType tmp = PCurNode->_data;
					PCurNode->_data = PpreNode->_data;
					PpreNode->_data = tmp;
				}
				PpreNode = PpreNode->_pNext;
				PCurNode = PCurNode->_pNext;
			}
			pTailNode = PCurNode;
			PCurNode = PpreNode;

		}
	}
}


int IsListCross(PNode L1, PNode L2) // 判断两个单链表是否相交(链表不带环)
{
	if(L1 == NULL || L2 == NULL)
	{
		return 0;
	}
	else
	{
		PNode pTailNode1 = L1;
		PNode pTailNode2 = L2;

		while(pTailNode1->_pNext)
		{
			pTailNode1 = pTailNode1->_pNext;
		}
		while(pTailNode2->_pNext)
		{
			pTailNode2 = pTailNode2->_pNext;
		}
		if(pTailNode2 == pTailNode1)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
}


PNode GetCrossNode(PNode PL1, PNode PL2) // 若不带环的单链表相交,求交点
{
	if(PL1 == NULL || PL2 == NULL)
	{
		return NULL;
	}
	else
	{
		if(!IsListCross(PL1, PL2))
		{
			return NULL;
		}
		else
		{
			size_t size1 = Size(PL1);
			size_t size2 = Size(PL2);
			int sz = size1 - size2;
			PNode pPre1 = PL1;
			PNode pPre2 = PL2;

			if(sz<0)
			{
			    pPre1 = PL1;
				pPre2 = PL2;

				sz = -sz;
				while(sz--)
				{
					pPre2 = pPre2->_pNext;
				}
			}
			else if(sz>0)
			{
			    pPre1 = PL1;
			    pPre2 = PL2;

				while(sz--)
				{
					pPre1 = pPre1->_pNext;
				}
			}
			while(pPre1->_pNext)
			{
				if(pPre1 == pPre2)
				{
					pPre1->_pNext = NULL;
					return pPre1;
				}
				pPre1 = pPre1->_pNext;
				pPre2 = pPre2->_pNext;
			}
			if(pPre2 == pPre1)
			{
				pPre1->_pNext = NULL;
				return pPre1;
			}
			else 
			{
				return NULL;
			}
		}
	}
}
PNode ReverseList(PNode pHead)// 实现单链表的逆置:使用三个指针


{
	PNode PreNode = NULL;
	PNode PCurNode = NULL;
	PNode PNextNode = NULL;

	if(pHead == NULL || pHead->_pNext == NULL)
	{
		return NULL;
	}
	else
	{
		PreNode = pHead;
		PCurNode = PreNode->_pNext;
		PNextNode = PCurNode->_pNext;
		while(PCurNode->_pNext)
		{
			PCurNode->_pNext = PreNode;
			PreNode = PCurNode;
			PCurNode = PNextNode;
			PNextNode = PNextNode->_pNext;
		}
		PCurNode->_pNext = PreNode;
		pHead->_pNext = NULL;
		pHead = PCurNode;
		return pHead;
	}
}

// 实现单链表的逆置:使用头插法
void ReverseList_P(PNode* pHead)


{
   PNode PNewNode = NULL;
   PNode PreNode = NULL;
   PNode PCurNode = NULL;


   if(*pHead == NULL || (*pHead)->_pNext == NULL)
   {
	   return;
   }

   PreNode = *pHead;
   PCurNode = (*pHead)->_pNext;
   while(PCurNode)
   {
	   PreNode->_pNext = PNewNode;
	   PNewNode = PreNode;
	   PreNode = PCurNode;
	   PCurNode = PCurNode->_pNext;
   }
   PreNode->_pNext = PNewNode;
   PNewNode = PreNode;
   *pHead = PNewNode;
   
}



 //合并两个已序单链表,合并后依然有序
PNode MergeList(PNode pHead1, PNode pHead2)

{
	if(pHead1 == NULL && pHead2 == NULL)
	{
		return NULL;
	}
	else if(pHead1 == NULL || pHead2 == NULL)
	{
		if(pHead2 == NULL)
		{
			return pHead1;
		}
		else
		{
			return pHead2;
		}
	}
	else
	{
		PNode pH1 = pHead1;
		PNode pH2 = pHead2;
		PNode PNewNode = NULL;
		PNode TailNode = NULL;
		if(pH1->_data <= pH2->_data)
		{
			PNewNode = pH1;
			pH1 = pH1->_pNext;
		}
		else
		{
			PNewNode = pH2;
			pH2 = pH2->_pNext;
		}
		TailNode = PNewNode;
	    while(pH1 && pH2)
		{
			if(pH1->_data <= pH2->_data)
			{
				PNewNode->_pNext = pH1;
				pH1 = pH1->_pNext;
			}
			else
			{
				PNewNode->_pNext = pH2;
				pH2 = pH2->_pNext;
			}
			PNewNode = PNewNode->_pNext;
		}
		if(pH1)
		{
			PNewNode->_pNext = pH1;
		}
		else
		{
			PNewNode->_pNext = pH2;
		}
		return TailNode;
	}
}

// 判断链表是否带环,若带环给出相遇点
PNode HasCircle(PNode pHead)

{
	if(pHead == NULL)
	{
		return NULL;
	}
	else
	{

		PNode pFast = pHead;
		PNode pSlow = pHead;
		{
			while(pFast && pFast->_pNext)
			{
				pSlow = pSlow->_pNext;
				pFast = pFast->_pNext->_pNext;
				if(pFast == pSlow)
				{
					return pSlow;
				}
			}
			return NULL;
		}
	}
}

// 求环的长度
size_t  GetCircleLen(PNode pMeetNode)

{
	PNode pCurNode = pMeetNode;
	size_t count = 1;
	while(pCurNode->_pNext != pMeetNode)
	{
		pCurNode = pCurNode->_pNext;
		count++;
	}
	return count;
}

// 求环的入口点
PNode GetEnterNode(PNode pHead, PNode pMeetNode)

{
	if(pHead == NULL)
	{
		return NULL;
	}
	else 
	{
		PNode pFast = pHead;
		PNode pSlow = pMeetNode;
		{
			while(pFast != pSlow)
			{
				pSlow = pSlow->_pNext;
				pFast = pFast->_pNext;
			}
			return pSlow;
		}
	}
}

// 判断链表是否相交,注意:链表可能带环
int IsCrossWithCircle(PNode pHead1, PNode pHead2)

{
	PNode pMeetNode1 = HasCircle(pHead1);
	PNode pMeetNode2 = HasCircle(pHead2);

	if(pHead1 == NULL || pHead2 == NULL)
	{
		return 0;
	}
	else if(pMeetNode1 == NULL && pMeetNode2 == NULL)
	{
		PNode pTailNode1 = pHead1;
		PNode pTailNode2 = pHead2;

		while(pTailNode1->_pNext)
		{
			pTailNode1 = pTailNode1->_pNext;
		}
		while(pTailNode2->_pNext)
		{
			pTailNode2 = pTailNode2->_pNext;
		}
		if(pTailNode2 == pTailNode1)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
	else if(pMeetNode1 && pMeetNode2)
	{
		PNode pCurNode = pMeetNode1;
		while(pCurNode->_pNext != pMeetNode1)
		{
			if(pCurNode == pMeetNode2)
			{
				return 2;
			}
			pCurNode = pCurNode->_pNext;
		}
		return 0;
	}
	else
	{
		return 0;
	}
}


test.c

void Test6()
{
	Node *Node = NULL;
	InitList(&Node);
	PushBack(&Node, 1);
	PushBack(&Node, 2);
	PushBack(&Node, 3);
	PushBack(&Node, 4);
	PushBack(&Node, 5);
	PushBack(&Node, 6);
	PushBack(&Node, 7);
	PrintList(Node);
	JosephCircle(&Node, 3);
	PrintList(Node);
}

void Test7()
{
	Node *Node = NULL;
	InitList(&Node);
	PushBack(&Node, 1);
	PushBack(&Node, 2);
	PushBack(&Node, 3);
	PushBack(&Node, 4);
	PushBack(&Node, 5);
	PushBack(&Node, 6);
	PushBack(&Node, 7);
	PrintList(Node);
	PrintFromTail2Head(Node);
	PrintList(Node);
	InsertNotHead(Find(Node, 5),8);
	PrintList(Node);
}

void Test8()
{
	Node *Node = NULL;
	InitList(&Node);
	PushBack(&Node, 1);
	PushBack(&Node, 2);
	PushBack(&Node, 3);
	PushBack(&Node, 4);
	PushBack(&Node, 5);
	PushBack(&Node, 6);
	PushBack(&Node, 7);
	PrintList(Node);
	DeleteNotTailNode(Find(Node,4));
	PrintList(Node);
}

void Test9()
{
	Node *Node = NULL;
	InitList(&Node);
	PushBack(&Node, 1);
	PushBack(&Node, 2);
	PushBack(&Node, 3);
	PushBack(&Node, 4);
	PushBack(&Node, 5);
	PushBack(&Node, 6);
	//PushBack(&Node, 7);
	PrintList(Node);
	PrintList(FindMidNode(Node));
	PrintList(FindLastKNode(Node, 3));
}

void Test10()
{
	Node *Node = NULL;
	InitList(&Node);
	PushBack(&Node, 6);
	PushBack(&Node, 2);
	PushBack(&Node, 3);
	PushBack(&Node, 7);
	PushBack(&Node, 5);
	PushBack(&Node, 1);
	PrintList(Node);
	BubbleSort(Node);
	PrintList(Node);
}

void Test11()
{
	Node *Node1 = NULL;
	Node *Node2 = NULL;
	Node *TailNode = NULL;
	int ret = 0;
	InitList(&Node1);
	InitList(&Node2);
	PushBack(&Node1, 1);
	PushBack(&Node1, 2);
	PushBack(&Node1, 3);
	PushBack(&Node1, 4);
	PushBack(&Node1, 5);
	PushBack(&Node1, 6);
    PushBack(&Node2, 4);
    PushBack(&Node2, 5);
	TailNode = Back(Node2);
	TailNode->_pNext = Find(Node1, 2);
    ret = IsListCross(Node1, Node2);
	printf("%d\n", ret);
	TailNode = GetCrossNode(Node1, Node2);
	PrintList(TailNode);

}
void Test12()
{
	Node *Node = NULL;
	InitList(&Node);
	PushBack(&Node, 1);
	PushBack(&Node, 2);
	PushBack(&Node, 3);
	PushBack(&Node, 4);
	PushBack(&Node, 5);
	PushBack(&Node, 6);
	PrintList(Node);
	ReverseList_P(&Node);
	PrintList(Node);
}

void Test13()
{
	Node *Node1 = NULL;
	Node *Node2 = NULL;
	Node *NewNode = NULL;
	InitList(&Node1);
	InitList(&Node2);
	PushBack(&Node1, 1);
	PushBack(&Node1, 1);
	PushBack(&Node1, 3);
	PushBack(&Node1, 4);
	PushBack(&Node1, 4);
	PushBack(&Node1, 6);
	PushBack(&Node2, 2);
	PushBack(&Node2, 2);
	PushBack(&Node2, 3);
	PushBack(&Node2, 4);
	PushBack(&Node2, 5);
	PushBack(&Node2, 5);
	NewNode = MergeList(Node1, Node2);
	PrintList(NewNode);
}

void Test14()
{
	Node *Node1 = NULL;
	Node *Node2 = NULL;
	Node *TailNode = NULL;
	size_t ret = 0;
	
	InitList(&Node1);
	InitList(&Node2);
	PushBack(&Node1, 1);
	PushBack(&Node1, 2);
	PushBack(&Node1, 3);
	PushBack(&Node1, 4);
	PushBack(&Node1, 5);
	PushBack(&Node1, 6);
	
	TailNode = Back(Node1);
	TailNode->_pNext = Find(Node1, 2);
    ret = GetCircleLen(HasCircle(Node1));
	TailNode = GetEnterNode(Node1, HasCircle(Node1));
	TailNode->_pNext = NULL;
	PrintList(TailNode);
}


void Test15()
{
	Node *Node1 = NULL;
	Node *Node2 = NULL;
	Node *TailNode1 = NULL;
	Node *TailNode2 = NULL;
	size_t ret = 0;

	InitList(&Node1);
	InitList(&Node2);
	PushBack(&Node1, 1);
	PushBack(&Node1, 2);
	PushBack(&Node1, 3);
	PushBack(&Node1, 4);
	PushBack(&Node1, 5);
	PushBack(&Node1, 6);

	
	PushBack(&Node2, 0);
	PushBack(&Node2, 7);
	PushBack(&Node2, 9);
	PushBack(&Node2, 8);

	TailNode1 = Back(Node1);
	TailNode1->_pNext = Find(Node1, 4);

	TailNode2 = Back(Node2);
	TailNode2->_pNext = Find(Node1, 3);

	ret = IsCrossWithCircle(Node1, Node2);
	if(ret == 0)
	{
		printf("这两个链表不相交\n");
	}
	if(ret == 1)
	{
		printf("这两个不带环链表相交\n");
	}
	if(ret == 2)
	{
		printf("这两个带环链表相交\n");
	}
}


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









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值