我有一个由
节点组成的链表struct Node{
Node(string k , string v , Node * n){
key = k;
val = v;
next_hash = n;
}
string key;
string val;
Node *next_hash = NULL;
Node *next_node = NULL;
Node *prev_node = NULL;
};
我正在创建双链表(对于此示例,next_hash将保持为NULL);
我已经创建了一个使用。添加节点的方法。
void add(string k , string v){
Node *tmp = new Node( k , v , NULL);
if( first == NULL ){
first = tmp;
last = tmp;
}else{
last -> next_node = tmp;
tmp -> prev_node = last;
last = tmp;
}
}
我想创建一个交换节点的方法。我创建了
void swap( string k , string l){
size_t klucik = hashfn(k);
size_t kluc = hashfn(l);
Node *one = first;
Node *two = first;
while( one ){
if( one -> key == k ){
break;
}
one = one -> next_hash;
}
while ( two ){
if( two -> key == l ){
break;
}
two = two -> next_hash;
}
Node *two_temp = two -> prev_node;
Node *two_tmp = two -> next_node;
if( one -> prev_node){
one -> prev_node -> next_node = two;
two -> prev_node = one -> prev_node;
}
else{
first = two;
two -> prev_node = NULL;
}
if( one -> next_node){
one -> next_node -> prev_node = two;
two -> next_node = one -> next_node;
}else{
two -> next_node = NULL;
last = one;
}
if( two_temp ){
two_temp -> next_node = one;
one -> prev_node = two_temp;
}
else{
first = one;
one -> prev_node = NULL;
}
if( two_tmp ){
two_tmp-> prev_node = one;
one -> next_node = two_tmp;
}
else{
last = one;
one -> next_node = NULL;
}
}
如果我交换的是不在其他节点旁边的节点,则此方法有效。 如果我这样做,它会抛出指向自身的infnte循环。
是否有任何优雅的方法可以创建通用交换方法,该方法可以计算链表中节点的所有可能位置,而不需要大量的if条件?
我试过,因为评论建议首先交换节点然后使用指针在节点内部 void swap(string k,string l){
Node *one = first;
Node *two = first;
while( one ){
if( one -> key == k ){
break;
}
one = one -> next_node;
}
while ( two ){
if( two -> key == l ){
break;
}
two = two -> next_node;
}
Node *two_temp = two -> prev_node;
Node *two_tmp = two -> next_node;
if( one -> prev_node)
one -> prev_node -> next_node = two;
else
first = two;
if( one -> next_node)
one -> next_node -> prev_node = two;
else
last = two;
if( two -> prev_node )
two -> prev_node -> next_node = one;
else
first = one;
if( two -> next_node )
two -> next_node -> prev_node = one;
else
last = one;
if( one -> next_node == two ){
two -> next_node = one;
two -> prev_node = one -> prev_node;
one -> next_node = two_tmp;
one -> prev_node = two_temp;
}
else if(one -> prev_node == two ){
two -> next_node = one -> next_node;
two -> prev_node = one;
one -> next_node = two;
one -> prev_node = two_temp;
}
else{
two -> next_node = one -> next_node;
two -> prev_node = one -> prev_node;
one -> next_node = two_tmp;
one -> prev_node = two_temp;
}
}
使用此测试数据
one.add("one","1");
one.add("two","2");
one.add("three","3");
one.add("four","4");
one.swap("one","two");
one.print(); // outputs 2 1 3 4
cout << " ============ " << endl;
one.swap("three","two");
one.print(); // outputs 2 4
我似乎无法找到交换节点的正确方法。
答案 0 :(得分:1)
使用指针指针将简化逻辑,并且在交换(* p ...,* p ...)期间不会改变它们。交换了内容(指向节点的指针),但没有交换指针的指针。
Node **pnpone; // ptr to next ptr to one
Node **pppone; // ptr to prev ptr to one
Node **pnptwo; // ptr to next ptr to two
Node **ppptwo; // ptr to prev ptr to two
// ...
if(one->prev_node)
pnpone = &(one->prev_node->next_node);
else
pnpone = &first;
if(one->next_node)
pppone = &(one->next_node->prev_node);
else
pppone = &last;
if(two->prev_node)
pnptwo = &(two->prev_node->next_node);
else
pnptwo = &first;
if(two->next_node)
ppptwo = &(two->next_node->prev_node);
else
ppptwo = &last;
std::swap(*pnpone, *pnptwo);
std::swap(*pppone, *ppptwo);
std::swap(one->prev_node, two->prev_node);
std::swap(one->next_node, two->next_node);