给定一个数组 'a' 和一个整数 'x',排列 (就地) 的元素使得所有元素 <x come before all the elements >='x'

Given an array 'a' and an integer 'x', arrange the elements of the (in place) such that all the elements <x come before all the elements >='x'

此外,保留两个组中元素的原始相对顺序(即小于 'x' 的元素组成一组,等于或大于 'x' 的元素组成另一组。相对顺序应该在两个组中都保留。)

例1:-

a={2,6,3,5,1,7}

x=5

Output : 2 3 1 6 5 7

All the elements smaller than 5 come before 5 and the relative order of the moved elements is 
   preserved (2,3,1) & (6,5,7)

例2:-

a={1,4,2,5,3}

x=4

output : 1 2 3 4 5

最初的问题是针对单向链表的。我为一个数组编写了算法,我想知道它是否可以移植到链表变体中。另外,有更好的方法吗?

   #include <bits/stdc++.h>
using namespace std;

void swap(vector<int> &a, int i, int j)
{
    int i2 = i;
    int x = a[j];
    int temp1 = a[i];
    int temp2;
    while (i < j)
    {
        temp2 = a[i + 1];
        a[i + 1] = temp1;
        temp1 = temp2;
        i++;
    }
    a[i2] = x;
}

void solve(vector<int> &a, int num)
{
    int n = a.size();
    int i = 0, j = 1;
    while (j < n)
    {
        if (a[i] < num)
            i++;
        if (a[i] >= num && a[j] < num)
            swap(a, i, j);
        j++;
    }
}

int main()
{
    vector<int> a = {2, 6, 3, 5, 1, 7};
    int num = 5;
    solve(a, num);
    for (auto el : a)
        cout << el << " ";
    return 0;
}

在使用链表时,交换的概念对于链表来说并不是很有用。相反,您会 移动 个节点。

这是一个可能的实现:

#include <iostream>

class Node {
    public:
    int value;
    Node * next;
    
    Node(int value, Node * next) {
        this->value = value;
        this->next = next;
    }

    Node(int value) {
        this->value = value;
        this->next = nullptr;
    }

    void print() {
        Node * node = this;
        while (node != nullptr) {
            std::cout << node->value << " -> ";
            node = node->next;
        }
        std::cout << "NULL\n";
    }

    Node * partition(int pivot) {
        if (this->next == nullptr) return this; // Quick exit
        Node * preHead = new Node(0); // Dummy
        Node * preMid = new Node(0, this); // Dummy
        Node * lessTail = preHead;
        Node * prev = preMid;
        while (prev->next) {
            Node * curr = prev->next;
            if (curr->value < pivot) {
                prev->next = curr->next; // remove curr
                lessTail->next = curr; // insert curr
                lessTail = curr; 
            } else {
                prev = curr; // keep curr where it is
            }
        }
        lessTail->next = preMid->next;
        delete preMid;
        Node * head = preHead->next;
        delete preHead;
        return head;
    }
};

int main() {
    // Construct the list from example #2
    Node * head = new Node(1,
                new Node(4,
                new Node(2,
                new Node(5,
                new Node(3)))));
    head->print();  // 1 -> 4 -> 2 -> 5 -> 3 -> NULL
    head = head->partition(4);
    head->print();  // 1 -> 2 -> 3 -> 4 -> 5 -> NULL
    // ...    
}

此代码使用了两个临时节点实例,因为这使代码更容易一些。但也可以在没有这些虚拟节点的情况下进行。在那种情况下,您必须执行一些空指针检查以查看何时分配给 next 属性 或 head 变量。