算法笔记(一)-反转链表和查找链表第一个共同节点

1、反转链表

题目:定义一个函数,输入一个链表的头结点,反转改链表并输出反转后链表的头结点。

struct ListNode
{
	int m_nKey;
	ListNode* m_pNext;
};
//反转链表
ListNode* ReverseList(ListNode* pHead)
{
	/*忽略错误输入应该加一些指针空、只有一个节点的判断*/
	
	ListNode* pReversedHead = NULL; //反转后的头结点
	ListNode* pNode = pHead;		//当前结点
	ListNode* pPrev = NULL;			//前一个结点
	
	/*
		核心思想就是要保留当前结点的前一个结点,好知道怎么反转;
		保留当前结点的下一个结点,避免链表断裂;
	*/
	while(pNode != NULL)
	{
		ListNode* pNext = pNode->m_pNext;// 当前结点的后一个结点
		if (pNext == NULL)
		{
			pReversedHead = pNode;
		}
		pNode->m_pNext = pPrev;
		pPrev = pNode;
		pNode = pNext;
	}
	return pReversedHead;
}

2、两个链表的第一个公共结点。

题目:输入两个链表,找到它们的第一个公共结点。

有两种方法,方法一:使用辅助栈,分别将链表压栈,然后同时从栈顶弹出,比较,第一个不同的结点即为第一个公共结点;

方法二:不适用辅助栈。代码如下:

//两个链表的第一个公共结点
//获取链表长度
unsigned int GetListLength(ListNode* pHead)
{
	unsigned int nLength = 0;
	ListNode* pNode = pHead;
	while(pNode != NULL)
	{
		++nLength;
		pNode = pNode->m_pNext;
	}
	return nLength;
}
ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2)
{
	//1、获取两个链表长度
	unsigned int nLength1 = GetListLength(pHead1);
	unsigned int nLength2 = GetListLength(pHead2);
	int nLengthDir = nLength1 - nLength2;
/*
	核心思想是长的链表先走k步,然后两个链表同时遍历,直到
	找到相同的一个结点
*/
	ListNode* pListHeadLong = pHead1;
	ListNode* pListHeadShort = pHead2;
	if (nLength2 > nLength1)
	{
		pListHeadLong = pHead2;
		pListHeadShort = pHead1;
		nLengthDir = nLength2 - nLength1;
	}
	// 先在长链表上走几步,再同时遍历两个链表
	for (int i = 0; i < nLengthDir; i++)
	{
		pListHeadLong = pListHeadLong->m_pNext;
	}
	while((pListHeadLong != NULL) && (pListHeadShort != NULL) && (pListHeadLong != pListHeadShort))
	{
		pListHeadLong = pListHeadLong->m_pNext;
		pListHeadShort = pListHeadShort->m_pNext;
	}
	// 得到第一个公共结点
	ListNode* pFirstCommonNode = pListHeadLong;
	return pFirstCommonNode;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峰峰小筑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值