-给定一个链表和一个值x,将链表划分成两 部分,使得划分后小于x的结点在前,大于 等于x的结点在后。在这两部分中要保持原 链表中的出现顺序。
如:给定链表1→4→3→2→5→2和x = 3,返回 1→2→2→4→3→5。
分别申请两个指针p1和p2,小于x的添加到 p1中,大于等于x的添加到p2中;最后,将 p2链接到p1的末端即可。
时间复杂度是O(N),空间复杂度为O(1);该 问题其实说明:快速排序对于单链表存储结 构仍然适用。
#include <stdio.h>
#include<iostream>
using namespacestd;
typedef struct tagSNode
{
int value;
tagSNode* pNext;
tagSNode(int v):value(v),pNext(NULL){}
}SNode;
void Partition(SNode*,int);
void Print(SNode*);
void Destroy(SNode*);
int main()
{
SNode* pHead = new SNode(0);
for (int i=0; i<10; i++) {
SNode* p = new SNode(rand()%100);
p->pNext = pHead->pNext;
pHead->pNext=p;
}
Print(pHead);
Partition(pHead,50);
Print(pHead);
Destroy(pHead);
return 0;
}
void Partition(SNode* pHead,int pivotKey)
{
//两个链表的头指针
SNode* pLeftHead = new SNode(0);
SNode* pRightHead = new SNode(0);
//两个链表的当前最后一个元素
SNode* left = pLeftHead;
SNode* right = pRightHead;
SNode* p = pHead->pNext;
while (p) {
if (p->value<pivotKey) {
left->pNext = p;
left = p;
}
else{
right->pNext = p;
right = p;
}
p=p->pNext;
}
//将right连接到left尾部
left->pNext = pRightHead->pNext;
right->pNext = NULL;
pHead->pNext = pLeftHead->pNext;
delete pLeftHead;
delete pRightHead;
}
void Destroy(SNode* p)
{
SNode* next;
while (p) {
next = p->pNext;
delete p;
p=next;
}
}
void Print(SNode* p)
{
while (p->pNext) {
printf("%d->",p->value);
p=p->pNext;
}
printf("%d\n",p->value);
}