C++ 如何指向实际元素而不仅仅是数组地址?

C++ 如何指向实际元素而不仅仅是数组地址?,c++,pointers,vector,C++,Pointers,Vector,我有一些类似的建议: struct Node{ int value; Node *left, Node *right; Node(): value(0), left(0), right(0){} } std::vector<Node> nodeList = getNodes(); 请注意节点列表[0]。左侧指向节点列表的结尾,nodeList.back()指向节点列表的开头 现在问题来了,nodeList[i]。左侧和nodeList[i]。右侧仅指向其前一个邻居的地址,但不

我有一些类似的建议:

struct Node{
 int value;
 Node *left, Node *right;
 Node(): value(0), left(0), right(0){}
}
std::vector<Node> nodeList = getNodes();
请注意节点列表[0]。左侧指向节点列表的结尾,nodeList.back()指向节点列表的开头

现在问题来了,nodeList[i]。左侧和nodeList[i]。右侧仅指向其前一个邻居的地址,但不一定指向实际的邻居对象。因此,如果要对节点列表进行排序,左指针和右指针将不再指向原始节点。相反,他们将指向新的左邻右舍。希望问题是清楚的,我怎样才能得到它,例如nodeList[1]。即使nodeList[0]被移动到了另一个位置,也会向左指向nodeList[0]?

您可以只做一个

std::vector<int> originalData = getOriginalData();
现在只需排序:

std::sort(
    itemPointers.begin(), itemPointers.end(),
    []( int const* p1, int const* p2 ) { return (*p1 < *p2); }
    );
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;
}
#包含//标准::排序
#包括
#包括//标准::开始,标准:。结束
#include//std::vector
//使用名称空间std;
std::vectorgetOriginalData()
{
静态int常量数据[]={3,1,4,1,5,9,2,6,5,4};
返回std::vector(std::begin(数据),std::end(数据));
}
int main()
{
std::vector const originalData=getOriginalData();
向量项指针;
用于(自动常量和x:原始数据)
{
itemPointers.push_-back(&x);
}
排序(
itemPointers.begin(),itemPointers.end(),
[](int const*p1,int const*p2){return(*p1<*p2);}
);

std::wcout您可以将其改为节点指针的向量。是的,这是我最初的想法,但我想知道是否可以避免。如果您使用std::sort,您不是在内存中移动节点,而是在复制它们。@VCato,是的,我正在使用std::sort。那么我的其他选项是什么?我将保留两个向量,即nodeList原样和一个
std::vector sortedNodeList
。如果您同意使用new进行分配,只需使用new即可
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;
}