c++11:std::partition分割,std::is_partitioned判断

序列

  vec.clear();
    for(int i =0;i<10;i++){
        vec.push_back(i);
    }

重新分割。大于1的排在后,返回第一个

std::vector<int>::iterator it = std::partition(vec.begin(),vec.end(),[](int value){return value>1;});
std::cout<<"partition:"<<*it<<std::endl;

输出

partition:1

排序后结果

 for(size_t i = 0;i<vec.size();i++){
        std::cout<<vec.at(i)<<" ";
    }

输出

9 8 2 3 4 5 6 7 1 0

除了小于1往后移动,其他原位置也已经和原来不一致

稳定排序

std::stable_partition

修改原序列,但是保持原排序

std::stable_partition(vec.begin(),vec.end(),[](int value){return value>1;});

输出

2 3 4 5 6 7 8 9 0 1

std::partition_copy

保持原序列,保持原排序,重新拷贝到两个新序列

{
        std::vector<int> vec{1,2,3,6,5,4,7,8,9,10};
        std::vector<int> vec1(10,1);
        std::vector<int> vec2(10,2);
        //返回 pair<_OIter1, _OIter2> 类型值
        auto result = std::partition_copy(vec.begin(),vec.end(),vec1.begin(),vec2.begin(),[](int n){return (0 == n%2);});
        //执向vec1的最后一个元素之后的值
        std::cout<< "vec1 first:"<<*result.first<<" size:"<<result.first-vec1.begin()<<std::endl;
        //执向vec2的最后一个元素之后的值
        std::cout<< "vec2 second:"<<*result.second<<" size:"<<result.second-vec2.begin()<<std::endl;
        for(auto it=vec1.begin();it!=result.first;it++){
             std::cout<<*it<<" ";
        }
        std::cout<<" "<<std::endl;
        for(auto it=vec2.begin();it!=result.second;it++){
             std::cout<<*it<<" ";
        }
        std::cout<<" "<<std::endl;
    }

结果

vec1 first:1 size:5
vec2 second:2 size:5
2 6 4 8 10
1 3 5 7 9

判断是否被分割排序过

  std::cout<<"is_partitioned:"<<std::is_partitioned(vec.begin(),vec.end(),[](int value){return value>1;});

输出

is_partitioned:1

注意std::is_partitioned用来判断整个序列是否被划分为两个部分,而不是只判断前一部分或后一部分是否满足条件。即用你给的第三个函数来判断

如果是分割过。可以直接找分割点

{
        std::vector<int> vec{2,4,6,8,1,3,5,7,9};
        std::vector<int>::iterator find = std::partition_point(vec.begin(),vec.end(),[](int n){return (0 == n%2);});
        for(auto it = vec.begin();it!=find;it++){
            std::cout<<*it<<" ";
        }

        std::cout<<" "<<std::endl;
        for(auto it = find;it!=vec.end();it++){
            std::cout<<*it<<" ";
        }
        std::cout<<" "<<std::endl;
    }

输出

2 4 6 8
1 3 5 7 9

扩展

std::partial_sort

std::partial_sort部分排序,即序列只对部分,比如1000万个数据排序出前面10个
例子
1.获取前4

 std::partial_sort(std::begin(vec),std::begin(vec)+4,std::end(vec));
    for(size_t i = 0;i<vec.size();i++){
        std::cout<<vec.at(i)<<" ";
    }
    std::cout<<" "<<std::endl;

自定义比较

std::partial_sort(std::begin(vec),std::begin(vec)+4,std::end(vec),[](int n1,int n2){return n1>n2;});
    for(size_t i = 0;i<vec.size();i++){
        std::cout<<vec.at(i)<<" ";
    }

结果

0 1 2 3 6 7 8 9 5 4
9 8 7 6 0 1 2 3 5 4

std::partial_sort_copy

排序到另一个容器中

    std::vector<int> vec1(5);
    std::partial_sort_copy(std::begin(vec),std::end(vec),std::begin(vec1),std::end(vec1));
    for(auto& it:vec1){
        std::cout<<it<<" ";
    }
    std::cout<<" "<<std::endl;

即vec按大小排序5个到新容器vec1中

### 如何在 C++ 中实现链表的分割操作 要实现在 C++ 中对链表进行分割的操作,可以按照如下方法完成。具体来说,可以通过创建两个新的链表来分别存储小于给定值 `x` 的节点和大于等于 `x` 的节点,之后将它们连接在一起。 以下是完整的代码示例: ```cpp #include <iostream> using namespace std; // 定义链表节点结构体 struct ListNode { int data; ListNode* next; ListNode(int val) : data(val), next(nullptr) {} }; ListNode* partition(ListNode* head, int x) { // 创建两个虚拟头结点用于构建新链表 ListNode lessDummy(0); ListNode greaterDummy(0); ListNode* lessTail = &lessDummy; // 小于部分的尾部指针 ListNode* greaterTail = &greaterDummy; // 大于等于部分的尾部指针 while (head != nullptr) { // 遍历原链表 if (head->data < x) { // 如果当前节点数据小于x lessTail->next = head; // 添加到小于部分 lessTail = lessTail->next; // 更新尾部指针 } else { // 否则添加到大于等于部分 greaterTail->next = head; greaterTail = greaterTail->next; } head = head->next; // 移动至下一个节点 } // 断开最后一个节点的指向以防形成环 greaterTail->next = nullptr; lessTail->next = greaterDummy.next; // 连接两部分链表 return lessDummy.next; // 返回重新组合后的链表头部 } void printList(ListNode* head) { while (head != nullptr) { cout << head->data << "\t"; head = head->next; } cout << endl; } int main() { // 构建测试链表: 3 -> 5 -> 8 -> 5 -> 10 -> 2 -> 1 ListNode* head = new ListNode(3); head->next = new ListNode(5); head->next->next = new ListNode(8); head->next->next->next = new ListNode(5); head->next->next->next->next = new ListNode(10); head->next->next->next->next->next = new ListNode(2); head->next->next->next->next->next->next = new ListNode(1); cout << "Original List:\n"; printList(head); int x = 5; ListNode* result = partition(head, x); cout << "Partitioned List with respect to value " << x << ": \n"; printList(result); return 0; } ``` 上述代码实现了基于指定值 `x` 对链表进行分割的功能[^4]。通过这种方式,所有小于 `x` 的节点会被放置在大于或等于 `x` 的节点之前。 #### 关键点解析 - **双链表法**:利用两个辅助链表分别保存满足条件的小于部分和大于等于部分的数据。 - **断开循环**:为了防止潜在的环形链表,在处理完成后需显式设置尾节点的 `next` 值为 `nullptr`。 - **时间复杂度**:该算法仅需一次遍历整个原始链表,因此其时间复杂度为 O(n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值