【问题标题】:How to point to actual element not just the the array address?如何指向实际元素而不仅仅是数组地址?
【发布时间】:2012-11-20 05:16:41
【问题描述】:

我有一些这样的:

struct Node{
 int value;
 Node *left, Node *right;
 Node(): value(0), left(0), right(0){}
}
std::vector<Node> nodeList = getNodes();

我想让上面的东西做一个循环缓冲区。所以

nodeList[i].left = &nodeList[i - 1]; 
nodeList[i].right= &nodeList[i + 1];

注意nodeList[0].left指向nodeList的末尾,nodeList.back().right指向nodeList的开头;

现在问题来了,nodeList[i].left 和 nodeList[i].right 只指向其前一个邻居的地址,并不一定指向实际的邻居对象。因此,如果我要对 nodeList 进行排序,左右指针将不再指向原始节点。相反,它们将指向新的左右邻居。希望问题很清楚,我怎样才能让例如 nodeList[1].left 指向 nodeList[0] 即使 nodeList[0] 被移动到不同的位置?

【问题讨论】:

  • 你可以把它变成一个节点指针的向量。
  • 是的,这是我最初的想法,但我想知道我是否可以避免这种情况。
  • 如果你使用std::sort,你不是在移动内存中的节点,而是在复制它们。
  • @VCato,是的,我正在使用 std::sort。那么我的其他选择是什么?
  • 我会保留 2 个向量,nodeList 和一个 std::vector&lt;Node*&gt; sortedNodeList。如果你对新的分配没问题,后者就足够了

标签: c++ pointers vector


【解决方案1】:

你可以做一个

std::vector<int> originalData = getOriginalData();

然后在保留对原始顺序的访问权的同时对其进行排序,只需排序一个

std::vector<int const*> itemPointers;

你可以这样初始化:

for( auto&& x : originalData )
{
    itemPointers.push_back( &x );
}

现在只需排序:

std::sort(
    itemPointers.begin(), itemPointers.end(),
    []( int const* p1, int const* p2 ) { return (*p1 < *p2); }
    );

完整的代码还显示了访问原始数据前置项的详细信息:

#include <algorithm>        // std::sort
#include <iostream>
#include <utility>          // std::begin, std:.end
#include <vector>           // std::vector
//using namespace std;


std::vector< int > getOriginalData()
{
    static int const data[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4};
    return std::vector<int>( std::begin( data ), std::end( data ) );
}

int main()
{
    std::vector<int> const originalData = getOriginalData();

    std::vector<int const*> itemPointers;

    for( auto const& x : originalData )
    {
        itemPointers.push_back( &x );
    }

    std::sort(
        itemPointers.begin(), itemPointers.end(),
        []( int const* p1, int const* p2 ) { return (*p1 < *p2); }
        );

    std::wcout << "Sorted: ";
    for( auto const p : itemPointers )
    {
        std::wcout << *p << " ";
    }
    std::wcout << std::endl;

    std::wcout << "Predecessors in original data: ";
    for( auto const p : itemPointers )
    {
        int const* const pPred = (p == &originalData[0]? nullptr : p - 1);
        if( pPred == nullptr )
        { std::wcout << "! "; }
        else
        { std::wcout << *pPred << " "; }
    }
    std::wcout << std::endl;
}

【讨论】:

    猜你喜欢
    • 2010-11-23
    • 2011-07-05
    • 2020-05-12
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    • 2016-07-04
    相关资源
    最近更新 更多