【问题标题】:Printing a linked list in ascending and descending order以升序和降序打印链表
【发布时间】:2016-04-25 23:45:08
【问题描述】:

我有一个任务涉及使用菜单来修改链接列表并能够以升序和降序打印它。它是先前作业的扩展,其中我们必须将 .dat 文件加载到程序中并打印它。我们的新指令是添加一个名为 before 的新指针,该指针指向上方。我不知道如何按降序打印它。我们的教授说了一些关于使用循环的事情,但我对这一切如何工作感到困惑。代码现在有点草率,因为我还没有机会清理它。

#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

【问题讨论】:

  • 看起来您的列表是双向链接的(即有一个 next 和一个 before 指针)。但是您在链接时没有使用此逻辑。您只是链接 next 指针。使用双向链表反向打印很容易,因为您只需从末尾开始并遵循before 指针。如果要反向打印单链表,可以递归执行,也可以向前遍历列表两次(第一次,反向重新排序;第二次再次反转,但随时打印每个节点)。

标签: c++ pointers linked-list


【解决方案1】:

这是一个经典的数据结构算法。见双linked list

但是:

在尝试打印之前,您需要使用新指针before 更新您的代码。你也可以简化这个,见 cmets。 所以你的 link 功能:

  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 函数,但使用 before 进行解析。

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    相关资源
    最近更新 更多