//=============================QUESTION =================================
// Rearrange a list in such a way: given x, all nodes with val >= x should come after those with val < x.
// for example, given x = 5, a list {0 , 3 , 6 , 2 , 5} should be transformed into : { 0 , 3, 2, 6 , 5}. Of course, {0 , 3 , 2 , 5 ,6 } also meets the requirement.
// =====================================================================
#include <iostream>
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
//***** using second-order pointer can solve this question beautifully. ****
//in fact, second-order pointer can handle almost all list structure problems neatly.
ListNode* rearrange(ListNode* pHead, int x)
{
ListNode* smaller = NULL, **smaller_to_fill = &smaller;
ListNode* bigger = NULL, **bigger_to_fill = &bigger;
while(pHead)
{
if (pHead->val >= x)
{
*bigger_to_fill = pHead;
bigger_to_fill = &(pHead->next);
}
else
{
*smaller_to_fill = pHead;
smaller_to_fill = &(pHead->next);
}
pHead = pHead->next;
}
*smaller_to_fill = bigger;
*bigger_to_fill = NULL;
return smaller;
}
TEST
using namespace std;
int main(int argc, const char * argv[]) {
ListNode* head, **p_to_fill = &head;
//create a linklist
for (int i = 0; i < 30; i++) {
ListNode* new_node = new ListNode( (i * 101) % 31);
*p_to_fill = new_node;
p_to_fill = &(new_node->next);
}
//before rearrangement
ListNode* p = head;
while(p)
{
cout << p->val << " ";
p = p->next;
}
cout << "\n\n\n\n";
ListNode* p_rearranged = rearrange(head, 15);
//after rearrangement
p = p_rearranged;
while(p)
{
cout << p->val << " ";
p = p->next;
}
//delete the list
ListNode** p_to_delete = &head;
while(*p_to_delete)
{
ListNode* node = *p_to_delete;
p_to_delete = &(node->next);
delete node;
}
return 0;
}