2017-07-12 4 views
0

私はDijkstra's AlgorithmをC++で解決しています。私はそれを隣接関係リストを使って実装しました。別のクラスを作成するためにnewを使用するか使用しないか

私はnodeのクラス、minHeapのクラス、Graphのクラスを持っています。

class node 
{ 
    int vertex,weight; 
    node *next; 
    friend class Graph; 
    friend class minHeap; 
public: 
    node(); 
    node(int,int); 
}; 
node::node(){ 
    vertex=weight=0; 
    next=0; 
} 
node::node(int v,int wt){ 
    vertex=v; 
    weight=wt; 
    next=0; 
} 

私は(フレンド機能なし)minHeapクラスをこのように定義して、私は唯一のその関数内でオブジェクトを使用することができ、通常getDijkSP()機能でオブジェクトを作成しますか?

class minHeap 
{ 
    node *heap; 
    int heapSize,capacity,*pos; 
public: 
    minHeap(int); 
    void addElement(node); 
    node extractMin(); 
    void minHeapify(int); 
    void decreaseKey(int,int); 
}; 
minHeap::minHeap(int cap){ 
    heap=new node[capacity=cap]; 
    heapSize=-1; 
    pos=new int[cap](); 
}          //eliminating other methods 

class Graph 
{ 
    node **adjList; 
    int v; 
    bool *visited; 
public: 
    Graph(int); 
    void addEdge(int,int,int); 
    void removeEdge(int,int); 
    bool existsEdge(int,int); 
    void getDijkSP(); 
}; 
Graph::Graph(int vertices){ 
    adjList=new node*[v=vertices]; 
    for(int i=0;i<v;i++) 
     adjList[i]=NULL; 
} 
void Graph::getDijkSP(){ 
    minHeap hp(v);       //here 
    hp.addElement(node(0,0)); 
    for(int i=1;i<v;i++) 
     hp.addElement(node(i,INT_MAX)); 
    while(!hp.isempty()){ 
     node temp=hp.extractMin(); 
     cout<<temp.vertex<<" "<<temp.weight<<endl; 
     for(node *current=adjList[temp.vertex];current;current=current->next) 
      hp.decreaseKey(current->vertex,current->weight+temp.weight); 
    } 
} 

(OR)私は新しいキーワードを使用してminHeapクラスのオブジェクトを作成できるように、私は、友人の機能を持つminHeapクラスを定義していますか? (そして、これは私が、他の機能のすべての機能でそれを使用することができるように、私は、Graphクラスのスコープ内minHeapオブジェクトを定義するのに役立ちます。)私はthis読み、他のいくつかのいる

class minHeap 
{ 
    node *heap; 
    int heapSize,capacity,*pos; 
    friend class Graph;    //say like this 
public: 
    minHeap(int); 
    void addElement(node); 
    node extractMin(); 
    void minHeapify(int); 
    void decreaseKey(int,int); 
}; 
minHeap::minHeap(int cap){ 
    heap=new node[capacity=cap](); 
    heapSize=-1; 
    pos=new int[cap](); 
} 

class Graph 
{ 
    node **adjList; 
    int v; 
    bool *visited; 
    minHeap *hp;        //and do this 
public: 
    Graph(int); 
    void addEdge(int,int,int); 
    void removeEdge(int,int); 
    bool existsEdge(int,int); 
    void getDijkSP(); 
}; 
Graph::Graph(int vertices){ 
    adjList=new node*[v=vertices]; 
    for(int i=0;i<v;i++) 
     adjList[i]=NULL; 
    hp=new minHeap(v);      //dynamic allocation 
} 
void Graph::getDijkSP(){ 
    hp->addElement(node(0,0)); 
    for(int i=1;i<v;i++) 
     hp->addElement(node(i,INT_MAX)); 
    while(!hp->isempty()){ 
     node temp=hp->extractMin(); 
     cout<<temp.vertex<<" "<<temp.weight<<endl; 
     for(node *current=adjList[temp.vertex];current;current=current->next) 
      hp->decreaseKey(current->vertex,current->weight+temp.weight); 
    } 
} 

そのような種類の質問の両方の方法の利点、欠点、および適切性を知りたいと思っています。

私はクラスをより明確にするためにコンストラクタを提供しました。

+0

オブジェクトを割り当てるために 'new'を使うつもりならば、おそらくそうではないはずですが、そのようなオブジェクトごとに' delete'するデストラクタを追加する必要があります。 –

+0

はい。追加しないと申し訳ありませんが、そこにいるとしましょう。データ構造を定義するクラスを、問題を解決するようなより大きなクラスにリンクする方法を知りたいので、問題のデータ構造を使用することができます。問題に複数のデータ構造が必要な場合はどうなりますか? ..私はそのような問題の構造を定義するための最良の方法を知りたいだけです。 – revanthc97

答えて

0

短い答えはNOです。私はsmart pointersを読んでこの全体を書き直すことをお勧めします。 C++ではこれほど簡単なプロジェクトで手動割り当てを使用する本当の理由はありません。

ポインタに0またはNULLを代入する代わりにnullptrを使用します。nullptrはnullポインタのC++シンボルで、前述のCの値とは異なり、意図しないエラーを引き起こす可能性のあるint0だけです。あなたのコメントに応答する

編集:

は、だから私は、実際の現代C++の代わりに、簡単なクラスと、このCのコードを使用してコードを書き直すことにしました。あなたの全体的な例では、ポインタや動的な割り当てはほとんど必要ありません。実際のノードを誰が正確に所有すべきかを絶対に確信していなかったため、MinHeapを想定した例から説明しました。また、私はMinHeap :: posとGraph ::のポイントを私が見ることができるものからは得られませんでした。私はそのコードの任意の部分をより詳細に説明することができます。ただ質問するだけです。ここで

は、コードは次のとおりです。

class Node { 
    // Only friend class required if you insist on keeping members of Node private. 
    // If they aren't meant to change, consider declaring them as public and const. 
    template <unsigned Size> friend class Graph; 
public: 
    Node(int v, int wt) : vertex(v), weight(wt) {} 

private: 
    // Default values written in here right after declarations 
    // There is no need for a default constructor. You never call it anyway. 
    int vertex; 
    int weight; 
    Node* next = nullptr; 
}; 

// Template parameter because of internal use of std::array. 
// If the capacity shouldn't be constant, use std::vector and remove template. 
template <unsigned Capacity> 
class MinHeap { 
public: 
    // No constructor needed 
    // --------------------- 

    // One small tip: write parameter names in function declarations 
    // even if they aren't needed there for better readability of your code. 
    void addElement(Node n) { /* impl */ } 
    Node extractMin() { /* impl */ } 

    unsigned capacity() { return Capacity; } 
    bool isEmpty() { return heap.isEmpty(); } 

private: 
    // Default values written in here right after declarations 
    int heapSize = -1; 
    std::array<Node, Capacity> heap; 
}; 

// Template parameter because of internal use of std::array. 
// If the vertex count shouldn't be constant, use std::vector and remove template. 
template <unsigned Vertices> 
class Graph { 
public: 
    // No constructor needed 
    // --------------------- 

    void getDjikSP() { 
     hp.addElement({0, 0}); 
     for (unsigned i = 1; i < hp.capacity(); ++i) 
      hp.addElement({0, INT_MAX}); 

     while (!hp.isEmpty()) { 
      Node tmp = hp.extractMin(); 
      std::cout << tmp.vertex << " " << tmp.weight << std::endl; 

      for (Node* current = adjList[tmp.vertex]; current != nullptr; current = current->next) 
       hp.decreaseKey(current->vertex, current->weight + tmp.weight); 
     } 
    } 

private: 
    // Default values written in here right after declarations 
    std::array<Node*, Vertices> adjList; 
    MinHeap<Vertices> hp; 
}; 

あり多くのスペースは、このコードの改善のためにまだそれがヒープから削除された場合などのminheap :: extractMinは多分ノード& &を返すべきかconstノード&がトップへの参照を返すべきかどうかなど。すべての問題と非効率性に対処するために、これはまだすべての関数で完全なコードを見る必要があります。

+0

提案と参考に感謝します:)この問題は、私が対処したいことを示すための単なる例です。実際の問題は、問題に必要なデータ構造のクラスをどのように定義すればよいのか、問題を解決するためにクラスをどのように定義すればよいのか、どのようにリンクすればよいのでしょうか? (明らかに、あらかじめ定義されたクラスを使用するつもりがない場合)...そのような問題を基本的に解決する設計と構造化。 – revanthc97

+0

私はあなたのコメントを反映するために私の答えを更新しました。お気軽に質問してください。 –

関連する問題