2016-04-25 15 views
1

私は、リンクされたリストを変更し、昇順と降順でメニューを使用して印刷することができます。以前の割り当てを拡張したもので、.datファイルをプログラムにロードして印刷する必要がありました。私たちの新しい指示は、先に指摘した新しいポインタを追加することです。私は降順で印刷する方法を失っています。私たちの教授は、ループの使用について何か言っていましたが、これがどのように機能するのか混乱しています。私はまだそれをきれいにするチャンスがなかったので、コードはちょっとうんざりです。リンクされたリストを昇順と降順に印刷

#include <iostream> 
#include <iomanip> 
#include <fstream> 

using namespace std; 

struct Part 
{ 
    int number; 
    float price; 
    Part *next; 
    Part *before; 
}; 

class Inventory 
{ 
    protected: 
    Part *start; 
    public: 
    Inventory(void); 
    void link(Part); 
    string getFileName(void); 
    bool checkFileExistence(const string& filename); 
    void getFile(string filename, ifstream& file); 
    void PrintInventory (void); 
    void PrintDescending (void); 
    void AddPart(void); 
    void loadFile(void); 
    void DeleteItem(int); 
    void DeletePart(void); 
}; 

Inventory inven; 

Inventory::Inventory(void) 
{ 
    start = NULL; 
} 

void Inventory::link(Part item) 
{ 
    Part *p, *last, *here; 
    p = new Part; 

    p->number = item.number; 
    p->price = item.price; 

    if (start == NULL) 
    { 
    start = p; 
    start -> next = NULL; 
    } 
    else 
    { 
    here = start; 
    if(p->number < here->number) 
    { 
     p->next = here; 
     start = p; 
    } 
    else 
    { 
     while(p->number > here->number && here->next != NULL) 
     { 
     last = here; 
     here = here->next; 
     } 

     if (p->number < here->number) 
     { 
     last->next = p; 
     p->next = here; 
     } 
     else 
     { 
     here->next = p; 
     p->next = NULL; 
     } 
    } 
    } 
} 

void Inventory::PrintInventory() 
{ 
    Part *travel; 
    travel = start; 
    cout.setf(ios::fixed); 
    cout.precision(2); 

    if (travel != NULL) 
    { 
     cout << "\nPart #" << setw(13) << "Price" << endl; 
    } 

    while (travel != NULL) 
    { 
     cout << setw(5) << travel->number; 
     cout << setw(8) << '$' << setw(6) << travel->price << endl; 
     travel = travel->next; 
    } 
    cout << endl; 
} 

void Inventory::loadFile() 
{ 
    string filename; 
    filename = getFileName(); 
    Part thing; 
    cout << endl; 

    if (!checkFileExistence(filename)) 
    { 
     cout << "File '" << filename << "' not found." << endl; 
     return; 
    } 

    ifstream infile; 
    infile.open(filename.c_str()); 

    while(!infile.eof()) 
{ 
    infile >> thing.number; 
    infile >> thing.price; 
    inven.link(thing); 
} 

    cout << "\n Inventory File Loaded. \n\n"; 

} 

void Inventory::PrintDescending() 
{ 

} 

int main() 
{ 

char key; 
int res; 


    do{ 
     cout << "Menu:" << endl; 
     cout << "1) Load Inventory File" << endl; 
     cout << "2) Add Item to Inventory" << endl; 
     cout << "3) Remove Item from Inventory" << endl; 
     cout << "4) Print Inventory in Ascending Order" << endl; 
     cout << "5) Print Inventory in Descending Order" << endl; 
     cout << "6) Quit" << endl << endl; 
     cout << "Option Key: "; 
     cin >> key; 

     switch (key){ 
      case '2': 
       inven.AddPart(); 
       res = 1; 
       break; 
      case '3': 
       inven.DeletePart(); 
       res = 1; 
       break; 
      case '1': 
       inven.loadFile(); 
       res = 1; 
       break; 
      case '4': 
       inven.PrintInventory(); 
       res = 1; 
       break; 
      case '5': 
       inven.PrintDescending(); 
       res = 1; 
       break; 
      case '6': 
       res = 0; 
       break; 
      default: 
       res = 1; 
       break; 
     } 

    }while(res == 1); 
} 

この部分では不要なので、アイテムの追加と削除の機能は除外しました。私たちが使用している.datファイルが含まれています

123 19.95 
46 7.63 
271 29.99 
17 .85 
65 2.45 
32 49.50 
128 8.25 
+2

あなたのリストは二重にリンクされているようです(つまり、 'next'と' before'ポインタがあります)。しかし、あなたはリンク時にこのロジックを使用していません。 'next'ポインタをリンクするだけです。二重リンクリストを逆にして印刷するのは簡単です。なぜなら、最後から始まり、 'before'ポインタに従うからです。単一リンクリストをリバースプリントする場合は、再帰的に行うか、リストを2回前向きにトラバースすることができます(最初に逆順に並べ替える、2回目に逆にしますが、 )。 – paddy

答えて

0

これは、古典的なデータ構造アルゴリズムです。 Double linked listを参照してください。しかし

:印刷しようとする前に

、あなたは前に新しいポインタを使用してコードを更新する必要があります。あなたはまた、この1つを簡略化することができます、コメントを参照してください。 だからあなたリンク機能:その後、

if (start == NULL) 
    { 
    start = p; 
    start -> next = NULL; 
    // Here : 
    start->before = NULL; 
    } 
    else 
    { 
    here = start; 
    // You can remove this if... 
    if(p->number < here->number) 
    { 
     p->next = here; 
     start = p; 
    } 
    else 
    { 
     // ... Because your condition in the next while is enough. 
     while(p->number > here->number && here->next != NULL) 
     { 
     last = here; 
     here = here->next; 
     } 

     if (p->number < here->number) 
     { 
     // Here : TODO link with the previous one 
     last->next = p; 
     p->next = here; 
     } 
     else 
     { 
     // Here : TODO link with the previous one 
     here->next = p; 
     p->next = NULL; 
     } 
    } 
    } 
} 

および印刷するには、ちょうどあなたのPrintInventory機能を取るが、前を使用して解析します。

希望します。