2012-02-20 9 views
1

私は自分のリストクラスを実装しようとしていますが、私のリストの一部を逆転させるのに問題があります。二重リンクリストの逆の部分

Revelantコード:

void List<T>::reverse(ListNode * & head, ListNode * & tail) 
{ 

    ListNode* t; 
    ListNode* curr = head; 
    ListNode * funtail = tail; 
    int stop=0; 
    while(stop==0) 
    { 
     if(curr==funtail) 
     { 
      stop = 1; 
     } 
     t = curr->prev; 
     curr->prev = curr->next; 
     curr->next = t; 
     curr = curr->prev; 
    } 
    t = tail; 
    tail = head; 
    head = t; 
} 

私はリスト

1 2 3 4 5 6 7 8 9 10 

で開始し、私は1と4へのポインタを渡す場合、リストは

4 3 2 1 5 6 7 8 9 10 

のようになります。問題は、私のリストはちょうど

として戻ることです
1 

残りのリストは失われています(私のグローバルテール変数からはまだアクセスできます)。何か案は?私の方法は間違っていますか?

+0

'while'ループの最初の反復で、' curr-> prev'を 't'に割り当てます。前のノードがないところで頭を逆にし始めるとどうなりますか? – jrok

答えて

0

head->prevは、forループの最初にNULLを指している必要があります。あなたはより効果的に考えることができます。 t->next->next =t->nextが必要です。

+0

しかし、t-> nextがNULL(リストの最後の項目)のときは、t-> next-> nextでsegfaultしません。私は紙でそれを図式化しました。そして、作業ノードが頭であるときに特殊なケースを追加すると、うまく動作するかのように見えます。 – Adam

-1

メソッドパラメータでは、「参照」と「ポインタ」を混合しています。

void List::reverse(ListNode * & head, ListNode * & tail) 

多分あなたはどういう意味ですか?

void List::reverse(ListNode* head, ListNode* tail) 
+0

これは質問に答えません。また、彼がパラメータを再割り当てすることに注意してください。そのため、ポインタへの参照です。ベストプラクティスではありませんが、彼のコードはあなたの提案と共にすべて機能しません。 – vidstige

2

あなたは[最初に、最後の]のセグメントを逆にした場合、あなたのコードがするように、あなたは、last->nextに、ではないfirst->prevfirst->nextセットをしたいです。

0

ノード1のprevポインタがNULLで、ノード1の次に割り当てるため、問題は最初のノードで発生します。ノード5の隣に1を割り当てる必要があります

+0

私は作業ノードがtail-> next(1 - > nextは5)の次のノードを設定するときに特別なケースを追加しましたが、今では内部番号を失いつつあり、 2: <2 1 5 6 7 8 9 10> – Adam

+0

ヘッドノードと最後のノードを処理する必要があります。残りのノードでは、使用したロジックが機能するはずです。これらの3つのシナリオは、次の点で注意が必要です:1)ヘッドノードは次のテールノードを指す必要があります 2)テールノードはヘッドノードを指し示す必要があります 3)次にノードの残りのノード - > nextがnode - > prev – girish

+0

あなたは結果を出したコードを投稿することもできます<2 1 5 6 7 8 9 10>。私は問題は、変数の停止が1の間に設定されることになると思うので、反復は完全ではありません。 – girish

0

より簡単な解決策です。

/** 
* Traverses half of the list and swaps a node with another node(
    here by termed as the reflection node) 
* which lies at a position = listSize - (i +1) for every i. 
* Reassignment of element is not needed, hence a soul saver from 
* the copy constructor thing ('=' assignment operator stuff). 
*/ 
template <typename E> void DLinkedList<E>::reverse(){ 
    int median = 0; 
    int listSize = size(); 
    int counter = 0; 

    if(listSize == 1) 
     return; 

/** 
* A temporary node for swapping a node and its reflection node 
*/ 
DNode<E>* tempNode = new DNode<E>(); 

for(int i = 0; i < listSize/2 ; i++){ 
    DNode<E>* curNode = nodeAtPos(i); 
    // A node at 'i'th position 
    DNode<E>* reflectionNode = nodeAtPos(listSize - (i + 1)); 
// Reflection of a node considering the same distance from the median 

     /** 
     * swap the connections from previous and next nodes for current and 
      * reflection nodes 
     */ 
     curNode->prev->next = curNode->next->prev = reflectionNode; 

     reflectionNode->prev->next = reflectionNode->next->prev = curNode; 

     /** 
     * swapping of the nodes 
     */ 
     tempNode->prev = curNode->prev; 
     tempNode->next = curNode->next; 

     curNode->next = reflectionNode->next; 
     curNode->prev = reflectionNode->prev; 

     reflectionNode->prev = tempNode->prev; 
     reflectionNode->next = tempNode->next; 
    } 

    delete tempNode; 
} 

template <typename E> int DLinkedList<E>::size(){ 
    int count = 0; 
    DNode<E>* iterator = head; 

    while(iterator->next != tail){ 
     count++; 
     iterator = iterator->next; 
    } 
    return count; 
} 

template <typename E> DNode<E>* DLinkedList<E>::nodeAtPos(int pos){ 
    DNode<E>* iterator = head->next; 
    int listSize = size(); 
    int counter = 0; 
    while(counter < pos){ 
     iterator = iterator->next; 
     counter++; 
    } 

    return iterator; 
} 
関連する問題