2016-04-25 26 views
1

Ich habe eine Zuordnung, die ein Menü verwendet, um eine verknüpfte Liste zu ändern und in aufsteigender und absteigender Reihenfolge drucken zu können. Es ist eine Erweiterung einer früheren Aufgabe, in der wir eine .dat-Datei in das Programm laden mussten und es ausdrucken würde. Unsere neuen Anweisungen fügen einen neuen Zeiger hinzu, der zuvor aufgerufen wurde und nach oben zeigt. Ich weiß nicht, wie ich es in absteigender Reihenfolge ausdrucken soll. Unser Professor sagte etwas über die Verwendung einer Schleife, aber ich bin verwirrt darüber, wie das alles funktionieren würde. Der Code ist momentan etwas schlampig, da ich noch keine Chance hatte, ihn zu bereinigen.Drucken einer verketteten Liste in aufsteigender und absteigender Reihenfolge

#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); 
} 

Ich habe die Funktionen zum Hinzufügen und Löschen von Elementen weggelassen, da sie für diesen Teil nicht notwendig sind. Die von uns verwendete .dat-Datei enthält:

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

Es sieht so aus, als ob Ihre Liste doppelt verknüpft ist (d. H. Es gibt einen 'next' und einen' before' Zeiger). Aber Sie verwenden diese Logik nicht beim Verknüpfen. Sie verknüpfen nur die "nächsten" Zeiger. Das Drucken in umgekehrter Richtung mit einer doppelt verketteten Liste ist einfach, weil Sie einfach am Ende beginnen und den 'Vorher'-Zeigern folgen. Wenn Sie eine einfach verkettete Liste umgekehrt drucken möchten, können Sie dies entweder rekursiv tun oder Sie können die Liste zweimal durchlaufen (beim ersten Mal wird die Reihenfolge umgekehrt, beim zweiten Mal wird sie umgekehrt, aber Sie drucken jeden Knoten wie gewohnt). – paddy

Antwort

0

Dies ist ein klassischer Datenstrukturalgorithmus. Siehe Double linked list.

jedoch:

Bevor Versuch zu drucken, müssen Sie den Code mit dem neuen Zeiger vor aktualisieren. Sie können dies auch vereinfachen, sehen Sie sich die Kommentare an. So Ihre Link Funktion:

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; 
     } 
    } 
    } 
} 

Und dann drucken zu, nur nehmen Sie Ihre PrintInventory Funktion, sondern analysieren vor verwenden.

Ich hoffe, es hilft.

Verwandte Themen