c++实现 单链表的 反转、 拼接 、判环等操作

#include<iostream>
#include<stack>

struct ListNode {

	ListNode(int data)
		:_pNext(nullptr)
		, _data(data)
	{}
	ListNode* _pNext;
	int _data;

};
void PushBack(ListNode*& pHend, int data) {
	if (nullptr == pHend) {
		pHend = new ListNode(data);
		return;
	}
	ListNode* pCur = pHend;
	while (pCur->_pNext) {
		pCur = pCur->_pNext;
	}
	pCur->_pNext = new ListNode(data);
}
//反转一个单链表
//方法一  用栈
//void ReverseList(ListNode*& pHead) {
//	std::stack<ListNode*> s;
//	ListNode* pCur = pHead;
//	while (pCur) {
//		s.push(pCur);
//		pCur = pCur->_pNext;
//	}
//	pHead = s.top();
//	s.pop();
//	ListNode* pPre = pHead;
//	while (!s.empty()) {
//		pCur = s.top();
//		pPre->_pNext = pCur;
//		pPre = pCur;
//		s.pop();
//	}
//	pCur->_pNext = nullptr;
//
//}

//方法二  三个指针法
//void ReverseList(ListNode*& pHead) {
//	ListNode* pPre = nullptr;
//	ListNode* pCur = pHead;
//	ListNode* pNext = nullptr;
//	while (pCur) {
//		pNext = pCur->_pNext;
//		pCur->_pNext = pPre;
//		pPre = pCur;
//		pCur = pNext;
//	}
//	pHead = pPre;
//}

//方法三   头插法
void ReverseList(ListNode*& pHead) {
	ListNode* pNewHead = nullptr;
	ListNode* pCur = pHead;
	while (pCur) {
		//将pcur从原链表中删除
		pHead = pCur->_pNext;
		//pcur接到新链表
		pCur->_pNext = pNewHead;
		pNewHead = pCur;
		//更新pcur
		pCur = pHead;
	
	}
	pHead = pNewHead;
}
//返回中间结点 快指针速度是满指针2倍
//快指针走到末尾 满指针在中间
ListNode* FindMiddleNode(ListNode* pHead) {
	if (nullptr == pHead) {
		return nullptr;
	} 
	ListNode* pSlow = pHead;
	ListNode* pFast = pHead;
	while (pFast&&pFast->_pNext) {
		pFast = pFast->_pNext->_pNext;
		pSlow = pSlow->_pNext;
	}
	return pSlow;

}
//输入一个链表输出其倒数第k个结点
ListNode* FindLastKNode(ListNode* pHead, size_t k) {
	if (nullptr == pHead || k==0) {
		return nullptr;
	}
	ListNode* pFast = pHead;
	//后置-- fast先走k步
	while (k--) {
		
		//检测k》链表长度的情况
		if (nullptr == pFast) {
			return nullptr;
		}

		pFast = pFast->_pNext;
	}
	ListNode* pSlow = pHead;
	while (pFast) {
		pFast=pFast->_pNext;
		pSlow=pSlow->_pNext;

	}
	return pSlow;

}
//删除倒数第k个结点
void DeleteLastKNode(ListNode*& pHead,size_t k) {
	if (nullptr == pHead || k == 0) {
		return;
	}
	ListNode* pFast = pHead;
	//后置-- fast先走k步
	while (k--) {

		//检测k》链表长度的情况
		if (nullptr == pFast) {
			return;
		}

		pFast = pFast->_pNext;
	}
	ListNode* pSlow = pHead;
	ListNode* pPre = nullptr;
	while (pFast) {
		pFast = pFast->_pNext;
		pPre = pSlow;
		pSlow = pSlow->_pNext;

	}
	//删除节点
	if (pSlow == pHead) {
		pHead = pSlow->_pNext;
	}
	else {
		pPre->_pNext = pSlow->_pNext;
	}
	delete pSlow;


}
//返回两个有序链表拼接后的
ListNode* MergeList(ListNode* pHead1, ListNode* pHead2) {
	if (nullptr == pHead1) {
		return pHead2;
	}
	if (nullptr == pHead2) {
		return pHead1;
	}
	ListNode NewHead(0);
	ListNode* pTail = &NewHead;
	ListNode* pCur1 = pHead1;
	ListNode* pCur2 = pHead2;
	while (pCur1&&pCur2) {
		if (pCur1->_data <= pCur2->_data) {
			pTail->_pNext = pCur1;
			pCur1 = pCur1->_pNext;
		}
		else {
			pTail->_pNext = pCur2;
			pCur2 = pCur2->_pNext;
		}
		pTail = pTail->_pNext;
	}
	if (nullptr == pCur1) {
		pTail->_pNext = pCur2;
	}
	else {
		pTail->_pNext = pCur1;
	}
	return NewHead._pNext;

}
size_t GetListSize(ListNode* pHead) {
	size_t count = 0;
	ListNode* pCur = pHead;
	while (pCur) {
		count++;
		pCur = pCur->_pNext;

	}
	return count;

}
//输入两个链表 求第一个公共节点
ListNode* GetCrossNode(ListNode* pHead1, ListNode* pHead2) {
	//0.参数检测
	if (nullptr == pHead1 || nullptr == pHead2) {
		return nullptr;
	}
	//1.检测两个链表是否相交
	//检测两个链表中最后一个结点是否相同
	ListNode* pTail1 = pHead1;
	while (pTail1) {
		pTail1 = pTail1->_pNext;
	}
	ListNode* pTail2 = pHead2;
	while (pTail2) {
		pTail2 = pTail2->_pNext;
	}
	if (pTail1 != pTail2) {
		return nullptr;
	}
	//2.求交点
	int size1 = GetListSize(pHead1);
	int size2 = GetListSize(pHead2);
	int gap = size1 - size2;
	//较长链表先往后移动两个链表差值
	ListNode* pCur1 = pHead1;
	ListNode* pCur2 = pHead2;
	if (gap > 0) {
		//pcur1后移gap步
		while (gap--) {
			pCur1 = pCur1->_pNext;
		}
	}
	else {
		while (gap++) {
			pCur2 = pCur2->_pNext;
		}
	}
	//两个指针同时后移
	while (pCur1 != pCur2) {
		pCur1 = pCur1->_pNext;
		pCur2 = pCur2->_pNext;
	}
	return pCur1;
	
}
//判断链表中是否有环
//采用快慢指针 快指针每次走两步 满指针每次走一步
//如果链表不带环 快指针先走到末尾 若带环两个指针最终在环内相遇
ListNode* IsListWithCircle(ListNode* pHead) {
	ListNode* pFast = pHead;
	ListNode* pSlow = pHead;
	while (pFast&&pFast->_pNext) {
		pFast = pFast->_pNext->_pNext;
		pSlow = pSlow->_pNext;
		if (pFast == pSlow) {
			return pFast;
		}
	}
	return nullptr;

}
//求环的入口点
ListNode* GetEnterNode(ListNode* pHead) {
	ListNode* pMeetNode = IsListWithCircle(pHead);
	if (nullptr == pMeetNode) {
		return nullptr;
	}
	ListNode* pH = pHead;
	ListNode* pM = pMeetNode;
	while (pH != pM) {
		pH = pH->_pNext;
		pM = pM->_pNext;
	}
	return pH;
}

void Print(ListNode*& pHead) {
	ListNode* pCur = pHead;
	while (pCur) {
		std::cout << pCur->_data<<"-> ";
		pCur = pCur->_pNext;
	}
	std::cout <<"NULL" <<std::endl;

}

int main() {
	ListNode*  pHead1 = nullptr;
	PushBack(pHead1, 1);
	PushBack(pHead1, 2);
	PushBack(pHead1, 3);
	PushBack(pHead1, 4);
	Print(pHead1);
	ListNode* pHead2 = nullptr;
	PushBack(pHead2, 5);
	PushBack(pHead2, 6);
	PushBack(pHead2, 8);
	PushBack(pHead2, 9);

	Print(pHead2);
	ListNode* sum= MergeList(pHead1, pHead2);
	Print(sum);
	
	system("pause");
	return 0;

}

发布了78 篇原创文章 · 获赞 10 · 访问量 3843

猜你喜欢

转载自blog.csdn.net/weixin_44374280/article/details/100577759
今日推荐