链表相关练习题

#include<iostream>
#include<stack>
#include<assert.h>
using namespace std;

typedef struct Node
{
	Node* _pNext;
	int _data;
}*PNode;


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


//查找单链表的中间节点,只能遍历一次链表
//设置一个快指针和一个慢指针,当快指针到最后一个节点的时候
//慢指针的位置正好的中间节点
PNode FindMidNode(PNode pHead)
{
	PNode pSlow = pHead;
	PNode pFast = pHead;
	while (pFast && pFast->_pNext)
	{
		pSlow = pSlow->_pNext;
		pFast = pFast->_pNext->_pNext;
	}
	return pSlow;
}


//查找链表的倒数第k个节点,只能遍历一次链表
//定义一个快指针和一个慢指针,让快指针比慢指针先走k个节点,然后一起走
//快指针走到最后一个节点的时候慢指针的位置就是倒数第k个节点
PNode FindLastKNode(PNode pHead, size_t k)
{
	if (NULL == pHead || 0 == k)
		return NULL;

	PNode pFront = NULL;
	PNode pBack = NULL;

	while (--k)
	{
		if (NULL == pFront)
			return NULL;

		pFront = pFront->_pNext;
	}
	while (pFront)
	{
		pFront = pFront->_pNext;
		pBack = pBack->_pNext;
	}
	return pBack;
}

//删除链表的倒数第k个节点,只能遍历一次链表
void DeleteLastKNode(PNode* pHead, size_t k)
{
	assert(pHead);
	if (NULL == *pHead || 0 == k)
		return ;
	//找到第k个节点
	if (NULL == pHead || 0 == k)
		return ;

	PNode pFront = NULL;
	PNode pBack = NULL;

	while (k--)
	{
		if (NULL == pFront)
			return ;

		pFront = pFront->_pNext;
	}
	PNode pPreBack = NULL;
	while (pFront)
	{
		pFront = pFront->_pNext;
		pPreBack = pBack;
		pBack = pBack->_pNext;
	}

	//删除
	if (pBack == *pHead)
	{
		*pHead = (*pHead)->_pNext;
		delete pBack;
	}
	else
	{
		pPreBack->_pNext = pBack->_pNext;
		delete pBack;
	}

}

//判断单链表是否带环
//定义一个快指针一个慢指针,如果链表带环,快指针可以在一圈内追上慢指针
bool HasCircle(PNode pHead)
{
	PNode pFast = pHead;
	PNode pSlow = pHead;

	while (pFast&&pSlow->_pNext)
	{
		if (pFast == pSlow)
			return true;

		pFast = pFast->_pNext->_pNext;
		pSlow = pSlow->_pNext;
	} 
}


//求环的长度
//定义一个相遇节点,然后让链表往后走,定义一个计数++
//链表指针到达相遇节点的时候,count的数量就是节点数
int GetCircleLen(PNode pMeetNode)
{
	if (NULL == pMeetNode)
		return 0;

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

//找环的入口节点
//思路参考公式
	PNode GetEnterNode(PNode pHead, PNode pMeetNode)
	{
		if (NULL == pHead || NULL == pMeetNode)
			return NULL;

		PNode pH = pHead;
		PNode pM = pMeetNode;

		while (pH != pM)
		{
			pH = pH->_pNext;
			pM = pM->_pNext;
		}
		return pM;
	}


//判断链表是否相交
	bool IsListCross(PNode pHead1, PNode pHead2)
	{
		if (NULL == pHead1 || NULL == pHead2)
			return false;

		PNode pLastNode1 = pHead1;
		while (pLastNode1->_pNext)
			pLastNode1 = pLastNode1->_pNext;

		PNode pLastNode2 = pHead2;
		while (pLastNode2->_pNext)
			pLastNode2 = pLastNode2->_pNext;

		if (pLastNode2 == pLastNode2)
			return true;

		return false;
	}


//求环的长度
	int Size(PNode pHead)
	{
		int count = 0;
		PNode pCur = pHead;
		while (pCur)
		{
			count++;
			pCur = pCur->_pNext;
		}
		return count;
	}

//求两个环的相交节点
	PNode GetCrossNode(PNode pHead1, PNode pHead2)
	{
		if (!IsListCross(pHead1, pHead2))
			return NULL;

		int len1 = Size(pHead1);
		int len2 = Size(pHead2);
		int gap = len1 - len2;

		PNode pCur1 = pHead1;
		PNode pCur2 = pHead2;
		//head1长
		if (gap >= 0)
		{
			while (gap--)
				pCur1 = pCur1->_pNext;
		}
		//head2长
		else
		{
			while (gap++)
				pCur2 = pCur2->_pNext;
		}
		while (pCur1 != pCur2)
		{
			pCur1 = pCur1->_pNext;
			pCur2 = pCur2->_pNext;
		}
		return pCur1;
	}


//逆序打印链表1 -> 2 -> 3 -> 4 -> NULL
//法一:递归,分情况:1.链表存在 2.链表不存在
/*void PrintListFromTail2Head(PNode pHead)
{
	if (pHead)
	{
		PrintListFromTail2Head(pHead->_pNext);
		cout << pHead->_data << "" << endl;
	}
	else
}*/

//法二:循环。栈:后进先出
void PrintListFromTail2Head(PNode pHead)
{
	if (NULL == pHead)
		return;

	stack<Node*> s;
	PNode pCur = pHead;
	while (pCur)
	{
		s.push(pCur);
		pCur = pCur->_pNext;
	}
	while (!s.empty())
	{
		pCur = s.top();
		cout << pCur << "";
		s.pop();
	}
}



//删除一个无头单链表的非尾结点(不能遍历链表)
//1->2->3->NULL  替换
void Delete(PNode pos,PNode pdel)
{
	assert(pos);
	pos->_data = pdel->_data;
	pos->_pNext = pdel->_pNext;
	delete pdel;
}




//在无头单链表的一个非头结点前插入一个结点(不能遍历链表)
void InsertNode(PNode pos)
{
	assert(pos);
	 PNode pNewNode = new Node;
	 pNewNode->_pNext = pos->_pNext;
	 pos->_pNext = pNewNode;
}


//头插
void PushFront(PNode pHead)
{
	PNode pNewNode = new Node;
	pNewNode->_pNext = pHead;
	pHead = pNewNode;
}


//返回最后一个结点
PNode Back(PNode pHead)
{
	if (NULL == pHead)
		return NULL;

	PNode pCur = pHead;
	while (pCur->_pNext)
		pCur = pCur->_pNext;

	return pCur;
}


//单链表实现约瑟夫环 1->2->3->4->5->6->NULL
PNode JosephCircle(PNode& pHead, int M)
{
	//把单链表构成环
	Back(pHead)->_pNext = pHead;
	Node* pCur = pHead;
	while (pCur->_pNext == pCur)
	{
		//1.报数
		while (--M)
			pCur = pCur->_pNext;
		//2.删除(替换法)
		PNode pDel = pCur->_pNext;
		pCur->_data = pDel->_data;
		pCur->_pNext = pDel->_pNext;
		delete pDel;
	}
	//解环
	pCur->_pNext = NULL;
	pHead = pCur;
	return pCur;
}




//逆置/反转单链表 1->2->3->4->NULL,三个指针
//法一:替换法
/*
PNode ReserverList(PNode& pHead)
{
	if (pHead == NULL || NULL == pHead->_pNext)
		return pHead;

	PNode pCur = pHead;
	PNode pCurPre = NULL;
	PNode pCurNext = pCur->_pNext;
	while (pCurNext)
	{
		pCur->_pNext = pCurPre;
		pCurPre = pCur;
		pCur = pCurNext;
		pCurNext = pCur->_pNext;
	}
	pCur->_pNext = NULL;
	pHead = pCur;
}
*/




//法二:构建一个新链表,让原来的链表头插进来
PNode ReserverList(PNode& pHead)
{
	PNode pNewNode = NULL;
	PNode pCur = pHead;
	PNode pCurNext = NULL;
	while (pCur)
	{
		pCurNext = pCur->_pNext;
		pCur->_pNext = pNewNode;
		pNewNode = pCur;
		pCur = pCurNext;
	}
	return pNewNode;
}




//冒泡排序
void BubbleSort(PNode pHead)
{
	if (pHead == NULL || NULL == pHead->_pNext)
		return;
	PNode pCur =NULL ;
	PNode pCurNext = NULL;
	PNode pTail = NULL;
	bool isChange = false;
	while (pHead != pTail)
	{
		while (pCurNext != pTail)
		{
			if (pCur->_data > pCurNext->_data)
			{
				swap(pCur->_data, pCurNext->_data);
				isChange = true;
			}
		} 
		pCur = pCurNext;
		pCurNext = pCur->_pNext;
	}
	pTail = pCur;
	if (!isChange)
		return;
}



//合并有序链表,合并后依然有序
PNode MergeList(PNode pHead1, PNode pHead2)
{
	//法一:
	if (pHead1 == NULL)
		return pHead2;
	if (pHead2 == NULL)
		return pHead1;
   //法二:
	/*
	if (NULL == pHead1 || NULL == pHead2)
		return (NULL == pHead1) ? pHead2 : pHead1;
		*/
	PNode pL1 = pHead1;
	PNode pL2 = pHead2;
	PNode pNewHead = NULL;
	PNode pTail = NULL;
	if (pL1->_data <= pL2->_data)
	{
		pNewHead = pL1;
		pTail = pNewHead;
		pL1 = pL1->_pNext;
	}
	while (pL1 && pL2)
	{
		if (pL1->_data <= pL2->_data)
		{
			pTail->_pNext = pL1;
			pL1 = pL1->_pNext;
		}
		else
		{
			pTail->_pNext = pL2;
			pL2 = pL2->_pNext;
		}
		pTail = pTail->_pNext;
	}
	if (pL1)
		pTail->_pNext = pL1;
	if (pL2)
		pTail->_pNext = pL2;
}




//递归逆向销毁链表
void Destroy(PNode& pHead)
{
	if (pHead)
	{
		Destroy(pHead->_pNext);
		delete pHead;
	}
}




//递归逆向查找元素是否存在
bool Find(PNode pHead, int data)
{
	if (pHead->_pNext)
	{
		while (pHead->_data == data)
		{
			pHead = pHead->_pNext;
		}
		return;
	}
}




int main()
{
	PNode pHead = NULL;
	InitList(&pHead);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_36229332/article/details/78514074