2017-03-30 1 views
0

私はRedditに同じ投稿を投稿しましたが、コメントがありませんので、ここで助けてもらえるかどうかを判断しました。二重リンクリストの問題(具体的にはコピーコンストラクタと削除機能)

私の現在のプロジェクトでは、二重リンクリストの.hファイルと.cppファイルが与えられ、.cppに.hを実装する必要があります。私はリンクされたリストと本当に苦労している、私は右かちょっと右のものがうんざりであり、完全な要件を満たしていないように感じる。ここでは.hファイルには、次のとおりです。

#include <string> 
using namespace std; 

struct Node{ 
    string ssn; 
    string name; 
    Node* succ; 
    Node* pred; 
}; 

class DLL{ 
    private: 
    Node* headPtr; 
    int itemCount; 

    public: 
    DLL(); 
    DLL(DLL& n); 
    virtual ~DLL(); 
    Node* getHeadPtr(); 
    int search(string ss)const; 
    bool insert(string ss, string name, int & count); 
    bool remove(string ss, int & count); 
    int size(); 
    void display(); 
}; 

そしてここでは、.cppファイルです:

#include "DLL.h" 
#include <iostream> 
#include <string> 
using namespace std; 

// default constructor is already implemented 
// do not modify the default constructor 
DLL::DLL(){ 
    headPtr = nullptr; 
    itemCount=0; 
} 

// return the head pointer of the list 
// it is already implemented, do not modify it 
Node* DLL::getHeadPtr(){ 
    return headPtr; 
} 

// copy construct, which copies an existing list n 
// the new list is a different object from n 
// the new list and object n have the same contents 
// Please implement it 
DLL::DLL(DLL& n){ 
     /*Node *first = n.getHeadPtr(); 
    first = headPtr; 
    while(headPtr->succ) 
     headPtr = headPtr->succ; 
    while(headPtr){ 
     first->succ = headPtr->succ; 
     headPtr->succ = headPtr->succ->succ; 
    }*/ 
} 

// destructor 
// release every node of the list 
// Please implement it 
DLL::~DLL(){ 
    Node *tmp = this->headPtr; 
    Node *temp; 
    while(tmp->pred) 
     tmp = tmp->pred; 
    while(tmp) 
    { 
     temp = tmp->succ; 
     delete tmp; 
     tmp = temp; 
    } 
    tmp =NULL; 
    temp = NULL; 
} 

// if some node has SSN matcthes string ss 
// return the index value of the node 
// the index value of the first node is 0, the second node is 1, etc. 
// if there is node matching ss, return -1 
int DLL::search(string ss)const{ 
    int count = 0; 
    Node *tmp = headPtr; 
    while(tmp != NULL){ 
     count++; 
    if(tmp->ssn == ss) 
     return count -1; 
    tmp = tmp->succ; 
    } 
    return NULL; 
} 

// insert (ss, name) to the existing list 
// the SSN values are each node are organized in INCREASING order 
// if there is a node matching ss value, return false; otherwise true 
// else create a node with (ss, name), insert the node to the proper position 
// parameter count is the counter of number of valid insertion 
// when you implement this method, consider the following situations: 
// 1. list is empty 
// 2. node should be inserted to the beginning of the list 
// 3. node should be inserted to the middle of the list 
// 4. node should be inserted to the end of the list 
//I use the append function, then sort afterwards 
bool DLL::insert(string ss, string name, int & count){ 
    //Create Node 
    Node *newPtr = new Node; 
    newPtr->ssn = ss; 
    newPtr->succ = NULL; 
    //If list is empty 
    if(headPtr == NULL){ 
     headPtr = newPtr; 
     return true; 
    } 
    //If list is not empty 
    else{ 
     Node* temp = headPtr; 
     while(temp->succ != NULL){ 
      temp = temp->succ; 
      itemCount++; 
      count++; 
     } 
    temp->succ = newPtr; 
    //Following part is to sort from least to greatest (based on Lab 7) 
    //Store head to temp node 
    temp = headPtr; 
    string tempVal; 
    int counter = 0; 
    //Set temp to next, increase count 
    while (temp){ 
     temp = temp->succ; 
     counter++; 
    } 
    //Make temp head again 
    temp = headPtr; 
    //While less than count and has next node, check if val at temp is greater than val at next 
    for (int j=0; j<count; j++){ 
     while (temp->succ){ 
      if (temp->ssn > temp->succ->ssn){ 
       //Store val at temp to temp val 
       tempVal = temp->ssn ; 
       //Make temp's val the value at temp->next 
       temp->ssn = temp->succ->ssn; 
       //Make temp->next's val, temp's old val 
       temp->succ->ssn = tempVal; 
      } 
      //Make temp the next value and check again 
      temp = temp->succ; 
     } 
     //Move temp back to head  
     temp = headPtr; 
    } 
    return true; 
    } 
    return false; 
} 


// remove node containing ss value 
// if there is no node containing ss, return false; otherwise true 
// consider the following situations: 
// 1. list is empty 
// 2. node containing ss value is the first node 
// 3. node containing ss value is in the middle of the list 
// 4. node containing ss value is the last node of the list 
bool DLL::remove(string ss, int & count){ 
    /*Node *temp = headPtr; 
    while(temp){ 
     if(temp->ssn == ss){ 
      temp->pred->succ = temp->succ; 
      temp->succ->pred = temp->pred; 
      count++; 
      return true; 
     } 
     temp = temp->succ; 

    } 
    return false;*/ 
} 

// return the number of the nodes 
// it is already implemented, do not modify it 
int DLL::size(){ 
    return itemCount; 
} 

// iterate through each node 
// print out SSN and memory address of each node 
// do not modify this method 
void DLL::display(){ 
    Node* temp; 
    temp = headPtr; 
    while (temp!= nullptr) { 
     cout << temp->ssn << "\t" << temp << endl; 
     temp = temp->succ; 
    } 
} 

私は私の検索機能は結構です、と修正していないと言うコメントを持つ関数が作られていると思います教授によって彼らはうまくいきました。.hファイルも含まれていたので、これは問題ありません。私は実際にコピーコンストラクタと関数を削除すると苦労しています。私のdelete関数の現在の内容は、test.exeが到達するたびにクラッシュするため、コメントアウトされています。それでコピーコンストラクターは迷ってしまいました。私は多くの研究をして、他の投稿を読んでいましたが、私はそれを理解できません。削除機能のように、その関数に到達するたびにプログラムがクラッシュするため、私はコメントしました。私の挿入機能はすべてを順番に挿入し、挿入されていない場合は挿入しないといけないので、リストにすべての項目を追加してから順番に並べ替え、SSNがすでに入っているかどうかはチェックしません。それは機能しますが、明らかに完全ではありません。どんなアドバイスも非常に役に立ちます。というのも、二重にリンクされたリストで多くのことを苦労していると言うことができるからです。前もって感謝します。

+0

戻り値のコメントは教授のコメントであると思います**厳密に**それらに従ってください(例:値が見つからない場合は検索関数は '-1'を返します。 – ccKep

+0

@ccKep実際には見つからないときに-1を返します。私は正直なところ、理由は分かりません。なぜなら、それはすべきではないことが分かっていますが、何らかの理由でそれがあります。 – paul5345

+0

この場合、プログラムの流れを完全にデバッグして(実際にコンパイルしたコードであることを確認する必要があります)、関数が0より小さい値を生成する方法はありません。 – ccKep

答えて

0

ここで

/*Node *first = n.getHeadPtr(); 
first = headPtr; 
while(headPtr->succ) 

headPtrはnullptrであるためheadPtr->succは、ランタイムエラーを発生させますが、コンストラクタでNULLポインタに問題があるようです。

+0

実際にはコピーコンストラクタで 'headPtr'は'nullptr' - 初期化されていないので不定です。 –

+0

@MichaelBurr私は混乱していますが、関数が呼び出されたときにheadPtrがDLLのように使用されたときにはわかりません。* newList = new DLL(oldList);私はリンクされたリストで本当に苦労して申し訳ありません。 – paul5345

+0

新しいコピーを初期化するのはコピーコンストラクタの仕事です。コピーctorを実装していない場合、コンパイラは非常に基本的なものを作成しますが、リンクリストの場合は基本的なものが間違っているでしょう - あなた(プログラマ)がコピーコンストラクタを書く必要があるのです。コピーコンストラクタは、コンパイラが 'new DLL(oldList)'のような式を呼び出すものです。あなたがカスタムDLLを持っているならば(これは 'DLL'クラス - googleの3つのルールです)、すべての作業をしなければなりません。 –

関連する問題