链表分割问题

来源:互联网 发布:物联网农业数据平台 编辑:程序博客网 时间:2024/06/13 22:27

题目:编写代码,以给定的x为基准值将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前。

解法一:交换结点法,回想学习快速排序的时候,也是以基准值将一组数划分成两部分,小于基准值的排在前面,大于基准值的排在后半部分。因此解决这个问题也可以使用两个指针。如果链表头结点开始遍历,第一个需要移动的结点是第一个大于或等于基准值的结点,例如链表1->3->6->7->2->1->5,基准值设为4,那么第一个指针滑到6的时候应该停止,它需要被交换到后面,因为6前面的结点值都是小于基准值的,所以和它交换的结点应该在它后面,需要找到一个小于基准值的结点交换到前面去,于是找到了结点2。交换结点6和2。然后两个指针同时后移一位,在寻找需要交换的结点过程中指针一直滑到链表结尾时,表明链表中已经没有需要交换的结点,这时候直接返回,循环结束。

void Partition(ListNode* pHead, int n){if(pHead == NULL)return;ListNode *pCurr, *pNext;pCurr = pHead;while(pCurr->m_nValue < n){pCurr = pCurr->m_pNext;if(pCurr == NULL)return;}pNext = pCurr;while(pNext->m_nValue >= n){pNext = pNext->m_pNext;if(pNext == NULL)return;}while(pCurr != NULL && pNext != NULL){while(pCurr->m_nValue < n){pCurr = pCurr->m_pNext;if(pCurr == NULL)return;}while(pNext->m_nValue >= n){pNext = pNext->m_pNext;//替换注释部分if(pNext == NULL)return;}int tmp = pCurr->m_nValue;pCurr->m_nValue = pNext->m_nValue;pNext->m_nValue = tmp;pCurr = pCurr->m_pNext;pNext = pNext->m_pNext;}}
解法二:先分割再合并。创建两个链表,before和after,before保存小于基准值的结点,after保存大于或等于基准值的结点,最后将两个链表合并。

void Partition(ListNode** pHead, int n){if(pHead == NULL)return;ListNode *beforeHead, *beforeEnd, *afterHead;beforeHead = beforeEnd = afterHead = NULL;ListNode* pNode = *pHead;while(pNode != NULL){ListNode* node = pNode->m_pNext;if(pNode->m_nValue < n){if(beforeHead == NULL){beforeHead = pNode;beforeEnd = pNode;beforeEnd->m_pNext = NULL;}else{pNode->m_pNext = beforeHead;beforeHead = pNode;}}else{if(afterHead == NULL){afterHead = pNode;afterHead->m_pNext = NULL;}else{pNode->m_pNext = afterHead;afterHead = pNode;}}pNode = node;}if(beforeHead == NULL){*pHead = afterHead;return;}beforeEnd->m_pNext = afterHead;*pHead = beforeHead;}




0 0