2012-04-10 7 views
1

こんにちは私は、二重リンクリストのノードとして個々の数字を格納し、それらを一緒に追加して宿題にプリントアウトするために二重リンクリストを作成しようとしています。私はこれをうまく動作させるために多くの問題を抱えており、ポインタを正しく更新しないため、ノードの追加機能に問題があると考えています。例えば、AddToFront()関数では、前のポインタをどのように取得してその背後にあるノードを指し示すことができるのか理解できません。二重リンクリストにノードを追加する際に問題が発生しました

私はSTLを使用することはできませんし、誰もが疑問に思っている場合は、LLを実装する必要があります。ありがとう!

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <math.h> 
#include <iostream> 

using namespace std; 

/////// PART A 
template <class T> 
class List { 
private: 
    struct Node { 
     T data; 
     Node *next; 
     Node *prev; 
    }; 
    Node *front, *current, *rear; 

public: 
    List(); 
    ~List(); 
    void AddtoFront (T newthing); 
    void AddtoRear (T newthing); 
    bool FirstItem (T & item); 
    bool LastItem (T & item); 
    bool NextItem (T & item); 
    bool PrevItem (T & item); 
}; 

template <class T> 
List<T>::List() { 
    front = NULL; current = NULL; rear = NULL; 
} 
template <class T> 
List<T>::~List() { 

} 

template <class T> 
void List<T>::AddtoFront (T newthing) { 
    if (front == NULL) { 
     Node *temp; 
     temp = new Node; 
     temp->data = newthing; 
     temp->next = front; 
     temp->prev = NULL; 
     front = temp; 
    } else { 
     Node *temp; 
     temp = new Node; 
      front->prev = temp; 
     temp->data = newthing; 
     temp->next = front; 
     temp->prev = NULL; 
     front = temp; 
    } 
} 

template <class T> 
void List<T>::AddtoRear (T newthing) { 
    if (rear == NULL) { 
     Node *temp; 
     temp = new Node; 
     temp->data = newthing; 
     temp->prev = rear; 
     temp->next = NULL; 
     rear = temp; 
    } else { 
     Node *temp; 
     temp = new Node; 
      rear->next = temp; 
     temp->data = newthing; 
     temp->prev = rear; 
     temp->next = NULL; 
     rear = temp; 
    } 
} 

template <class T> 
bool List<T>::FirstItem (T & item) { 
    if (front == NULL) { return false; } 
    current = front; 
    item = front->data; 
    return true; 
} 

template <class T> 
bool List<T>::LastItem (T & item) { 
    if (rear == NULL) { return false; } 
    current = rear; 
    item = rear->data; 
    return true; 
} 

template <class T> 
bool List<T>::NextItem (T & item) { 
    if (current != NULL) current = current->next; 
    if (current == NULL) { return false; } 
    item = current->data; 
    return true; 
} 

template <class T> 
bool List<T>::PrevItem (T & item) { 
    if (current == NULL) { return false; } 
    if (current->prev != NULL) current = current->prev; 
    item = current->data; 
    return true; 
} 

/////// PART B 
class BigNumber { 
private: 
//complete here... 
//include here a List of integers, or shorts etc 
    List<int>L; 

public: 
//complete here... 
//what methods do you need? 
//e.g., ReadFromString, PrintBigNumber, AddBigNumbers 
    BigNumber(); 
    ~BigNumber(); 
    void ReadFromString(char * decstring); 
    void PrintBigNumber(); 
    void AddBigNumbers(BigNumber B1, BigNumber B2); 
}; 

BigNumber::BigNumber(){ 
// anything here? 
} 

BigNumber::~BigNumber(){ 
//you can keep that empty 
} 

void BigNumber::ReadFromString (char * decstring) { 
    //read a string, adding a new node per digit of the decimal string 
    // To translate 'digits' to integers: myinteger=decstring[index]-48 
    //You need to use the AddtoFront() 
    int temp; 
    for (unsigned i=0; i < strlen(decstring); ++i) { 
     //cin >> decstring[i]; 
     temp = decstring[i]-48; 
     //L.AddtoFront(temp); 
     L.AddtoRear(temp); 
     //cout <<"Number added!" <<endl; 
    } 
} 

void BigNumber::PrintBigNumber() { 
//complete here, print the list (i.e., use FirstItem() and NextItem()) 
    int val; 
    if (L.FirstItem(val)) { 
     cout << val; 
    } else { 
     cout << "print failed"; 
    } 
    //if (L.FirstItem(val)) { cout << "true-first";} else { cout <<"false-first";}; 
    //if (L.LastItem(val)) { cout << "true";} else { cout <<"false";}; 
    //L.FirstItem(val); 
    //cout << val; 
    /*while (L.PrevItem(val)){ 

      cout << val; 
      //cout <<"Print error!Value not here."; 
    }*/ 
} 

void BigNumber::AddBigNumbers(BigNumber B1,BigNumber B2){ 
//complete here. 
//use FirstItem(), NextItem() and AddNode() 
//to add two big numbers, what do you have to do? Be careful about the carry 
//Remember to add the last carry, the resulting number can have one more digit than B1 or B2 
} 

/////// PART C 

BigNumber B1, B2, RES; 

int main (int argc, char ** argv) { 
    //use command line arguments 
    if(argc!=3){printf("usage: executable number1 number2\n");exit(0);} 
    B1.ReadFromString(argv[1]); 
    B2.ReadFromString(argv[2]); 
    //print 
    cout << endl<< "Add the following numbers " << endl; 
    B1.PrintBigNumber(); 
    cout << " + "; 
    B2.PrintBigNumber(); 
    cout << " = " << endl; 
    //compute the addition 
    RES.AddBigNumbers(B1,B2); 
    //print the result 
    RES.PrintBigNumber(); 
    cout << endl; 
    return 0; 
} 

編集:私はAddToFront()とAddToRearの各行に追加()。これは正しい方向にあるのでしょうか?

+1

おそらく 'const T&item'引数をあなたのadd関数に使うべきです。あなたは、循環リストを実装するために使用される実際のクラスのNodeを持つことを考慮することができます。これが 'Node head'だった場合、空のリストは' head-> next = head-> prev = &head; 'となり、現在のポインタのみが分離されます。これにより、対処しなければならない特別なケースの数を減らすことができます。 –

答えて

1

AddtoFrontfrontprevポインタも更新する必要があります。それはあなたがAddtoFrontであなたのif文の二つの枝が同一であることに気づくかもしれません、あなたは現在

それはまた

temp <-> front <-> rest_of_list. 

にする必要がある

temp -> front <-> rest_of_list 

をやっている、ある... :)

関連する問題