#ifndef __LINK_LIST_H__
#define __LINK_LIST_H__
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>

typedef int DataType;

typedef struct LinkNode
{
	DataType data;
	struct LinkNode *next;
}LinkNode,*pLinkNode,*pList;

void InitLinkList(pList *pHead);//初始化链表
void PushBack(pList *pHead,DataType x);//尾插
void PopBack(pList *pHead);//尾删
void PushFront(pList *pHead, DataType x);//头插
void PopFront(pList *pHead);//头删
void PrintList(pList list);//打印

void EraseNotTail(pLinkNode pos);//删除非尾结点
void ReverseList(pList *pHead);//逆序链表

pLinkNode JoephCyele(pLinkNode *pHead, int num);//约瑟夫环
pLinkNode FindMidNode(pList plist);//找中间节点
void DelNode(pList* plist, int k);//删除倒数第k个节点(k>1&&k<总长)
pLinkNode CheckCycle(pList plist);//判断链表是否带环
int GetCircleLength(pLinkNodemeet);//求环长度
pLinkNode GetCycleEntryNode(pList plist, pLinkNode meetnode);//获取链起点

void InitLinkList(pList *pHead)
{
	assert(pHead);
	*pHead = NULL;
}

pLinkNode BuyNode(DataType x)//开辟空间
{
	pLinkNode newNode = (pLinkNode)malloc(sizeof(LinkNode));
	newNode->data = x;
	newNode->next = NULL;
	return newNode;
}

void PushBack(pList *pHead, DataType x)//尾插
{
	pLinkNode cur = *pHead;
	assert(pHead);
	pLinkNode newNode = BuyNode(x);
	
	if (cur == NULL)//若为空链表直接插入
	{
		*pHead = newNode;
		return;
	}
	
	while (cur->next)
	{
		cur = cur->next;
	}
	cur->next = newNode;
}

oid PushFront(pList* pHead, DataType x)//头插
{
	assert(pHead);
	pLinkNode newNode = BuyNode(x);
	
	if (*pHead == NULL)
	{
		*pHead = newNode;
		return;
	}
	
	newNode->next = *pHead;
	*pHead = newNode;
}

void PrintList(pList list)//打印链表
{
	pLinkNode cur=list;
	
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	
	printf("over");
}

//删除非尾结点
void EraseNotTail(pLinkNode pos)
{
	assert(pos);
	pLinkNode del = pos->next;
	pos->data = del->data;
	pos->next = del->next;
	free(del);
}

//逆序链表
void ReverseList(pList *pHead)
{
	pLinkNode pNewHead = NULL;
	pLinkNode cur = *pHead;
	pLinkNode prev = NULL;

	while (cur)
	{
		prev = cur;
		cur = cur->next;
		prev->next = pNewHead;
		pNewHead = prev;
	}
	
	*pHead = pNewHead;
}

//冒泡
void BubbleSort(pList *pHead)
{
	assert(pHead);
	
	pLinkNode cur = *pHead;
	pLinkNode end = NULL;
	
	while (cur==end)
	{
		while (cur && (cur->next != end))
		{
			if (cur->data > cur->next->data)
			{
				DataType tmp = cur->data;
				cur->data = cur->next->data;
				cur->next->data = tmp;
			}
			cur = cur->next;
		}
		end = cur;
		cur = pHead;

	}
}

//约瑟夫环
pLinkNode JoephCyele(pList *pHead, int num)
{
	assert(pHead);

	int count = 0;
	pLinkNode cur = *pHead;

	while (1)
	{
		count = num;
		if (cur->next = cur)
			break;
		while (--count)
		{
			cur = cur->next;
		}

		pLinkNode del = cur->next;
		cur->data = cur->next->data;
		cur->next = cur->next->next;
		free(del);
	}
	
	*pHead = cur;
	return cur;
}

pLinkNode FindMidNode(pList plist)//找中间节点
{
	//plist保存头结点地址,不能assert
	pLinkNode fast = plist;
	pLinkNode slow = plist;
	//if (fast->next == NULL)
	//	return NULL;
	
	while ((fast)&&(fast->next))
	{
		fast = fast->next->next;
		slow = slow->next;
	}
	return slow;
}

//删除倒数第k个节点(k>1&&k<总长)
void DelNode(pList* plist, int k)
{
	assert(k > 1);
	
	pLinkNode l1 = plist;
	pLinkNode l2 = plist;
	
	while (--k)
	{
		l1 = l1->next;
	}
	while (l1->next)
	{
		l1 = l1->next;
		l2 = l2->next;
	}
	
	pLinkNode del = l2->next;
	l2->data = del->data;
	l2->next = del->next;
	free(del);
}

//判断链表带环
pLinkNode CheckCycle(pList plist)
{
	pLinkNode fast = plist;
	pLinkNode slow = plist;
	//快慢指针相遇
	
	while ((fast) && (fast->next))
	{
		fast = fast->next->next;
		slow = slow->next;
		
		if (fast == slow)
			return slow;
	}
	return NULL;
}

//求环长度
int GetCircleLength(pLinkNode meet)
{
	pLinkNode start = meet;
	int count = 0;
	
	do
	{
		start = start->next; count++;
	} while (start != meet);
	
	return count;
}

//获取链起点
pLinkNode GetCycleEntryNode(pList plist, pLinkNode meetnode)
{
	pLinkNode entry =plist;
	pLinkNode meet= meetnode;
	
	while (entry != meet)
	{
		entry = entry->next;
		meet = meet->next;
	}
	
	return entry;
}

//判断是否相交
int Checkcross(pList list1, pList list2)
{

	if ((list1 == NULL) || (list2 == NULL))
	{
		return 0;
	}

	while (list1->next)
		list1 = list1->next;

	while (list2 = list2->next)
		list2 = list2->next;
	
	if (list1 == list2)
		return 1;
	else
		return 0;
}

//合并两链表(递归)
pLinkNode _Merge(pList list1, pList list2)
{
	if ((list1 == NULL) && (list2 == NULL))
		return NULL;
	else if ((list2 == NULL) && (list2 != NULL))
		return list2;
	else if ((list2 != NULL) && (list2 == NULL))
		return list1;
	
	pLinkNode newHead = NULL;
	
	if (list1->data < list2->data)
	{
		newHead = list1;
		newHead->next = _Merge(list1->next, list2);
	}
	else
	{
	
		newHead = list2;
		newHead->next = _Merge(list1, list2->next);
	}
	return newHead;
}

#endif //__LINK_LIST_H__