2012-04-17 14 views
-1

MergeSortクラスで分割関数に問題があります。最初の数回は動作しますが、セグメント化エラーが発生します。私はそれが私のforループであり、正しい中間ノードを選択していると思いますが、私はそれを理解できません。MergeSortとリンクリスト - 分割関数C++

すべてのヘルプは高く評価され、ここに私のコードは次のとおりです。


ヘッダー:

#ifndef MERGE_LIST 
#define MERGE_LIST 

#include <iostream> 
using namespace std; 

class mergeList { 
    public: 
     struct node { 
      int data; 
      struct node* next; 
     }; 

     mergeList(); 
     void push(struct node** head_ref, int new_data); 
     void printList(struct node * nptr); 
     //void merge(struct node** headRef); 
     struct node* SortedMerge(struct node* a, struct node* b); 
     void merge(struct node** headRef); 

    private: 
     int size; 
     //void merge(struct node** headRef, int s); 
     //void split(struct node* headRef, struct node** a, struct node** b, int mid); 
     void split(struct node* source, struct node** frontRef, struct node** backRef, int s); 
     void merge(struct node** headRef, int s); 
}; 

#endif 

出典:

#include "mergeList.h" 
#include "stdlib.h" 

mergeList::mergeList() { 
    size = 0; 
} 

void mergeList::push(struct node** head_ref, int new_data) { 

    struct node* new_node = (struct node*) malloc(sizeof(struct node)); 
    new_node->data = new_data; 
    new_node->next = (*head_ref);  
    (*head_ref) = new_node; 
    size++; 
} 

void mergeList::printList(struct node * nptr) { 

    while(nptr) { 
     cout << nptr->data << " "; 
     nptr=nptr->next; 
    } 
    cout << endl; 
} 

void mergeList::merge(struct node** headRef) { 
    merge(headRef, size); 
} 

void mergeList::merge(struct node** headRef, int s) 
{ 

    if(s < 2) 
     return; 

    struct node* a; 
    struct node* b; 
    struct node* head = *headRef; 

    bool addOne = false; 
    int mid = s/2; 

    if(s % 2 != 0) 
     addOne = true; 

    cout << "B4 SPLIT!" << endl; 
    cout << "AddOne: " << addOne << endl; 
    cout << "s: " << s << endl; 

    split(head, &a, &b, s); 

    merge(&a, mid); 

    //if(addOne) 
    // mid++; 

    merge(&b, mid); 

    *headRef = SortedMerge(a, b); 
} 

//Use a pointer to split the list 
void mergeList::split(struct node* headRef, struct node** _a, struct node** _b, int s) { 

    struct node* a; 
    //struct node* b; 
    if (s < 2) { 
     *_a = headRef; 
     *_b = NULL; 
    } 
    else { 
     a = headRef; 

    if(s != 2) { 
     for(int i = 0; i < s/2; i++) 
      a = a->next; 
    } 
      *_a = headRef; 
      *_b = a->next; 
     a->next = NULL; 
    } 
} 

struct mergeList::node* mergeList::SortedMerge(struct node* a, struct node* b) { 

    struct node* result = NULL; 

    if (a == NULL) 
     return b; 
    else if (b == NULL) 
     return a; 
    if(a->data <= b->data) { 
     result = a; 
     result->next = SortedMerge(a->next, b); 
    } 
    else { 
     result = b; 
     result->next = SortedMerge(a, b->next); 
    } 

    return(result); 
} 

答えて

0

は、あなたがそのようにgdbなどのデバッガで実行しましたまたはdbxを使用してsegfaultingを確認しますか?

+0

私はそれを使用する方法を実際にはわかりませんが、forループの前後でどこか知っています – dajee

+0

@Davidこれはデバッグツールを使用することを学ぶ良い機会だと考えてください。あなたがプログラミングを続けるなら、ある時点で学ばなければならないでしょう。 – kappamaki

+0

カッパマキと同じ気持ち。彼らは、segfaultをキャッチするか、無限ループがどこにあるかを把握するなどの簡単な処理を行うのに非常に使いやすいです。 Googleの "gdbチートシート"を使い始める。コンパイラにデバッグ情報を残すように指示するには、-gフラグを指定してコンパイルする必要があります。これにより、問題のある行が正確に表示され、ソースを注ぐ時間やデバッグ文を追加する時間を節約できます。 デバッガを使用する=怠け者のような種類の、学習を止める=悪い怠惰な種類。 – djechlin