1

我为教育目的编写的双链表程序遇到了一些语法问题。我在头文件中创建了一个结构,我的主程序似乎没问题,但是在 .cpp 文件中实现我的功能给我带来了巨大的困难。我无法辨别将记录插入列表的三种情况。具体来说,分配内存、初始化列表头部和尾部以及语句的顺序让我感到困惑,就像传递要添加到我的列表中的记录副本一样。

我的头文件如下:

struct rec
{
   char * id;
   char firstname[15];
   char lastname[15];
   struct rec* prev;
   struct rec* next;
};


int AddItem ( rec r );
int DeleteItem ( char* delid );
void PrintList ( int order );

我的.cpp文件,也就是难点所在,如下:

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

// These pointers refer to the head and tail of the list.
rec* first = NULL;
rec* last = NULL;

int AddItem( Rec r )
{

   rec* newRecEntry;
   rec* current = NULL;
   rec* previous = NULL;

   // Check for duplicate id
   current = first;
   while (current)
   {
     if( strcmp(current -> id, r.id) == 0)
      {
         return 0;
      }
     else
      // Create a new node
      {
         newRecEntry = new Rec;
         newRecEntry->id = new char[strlen(r.id)+1];
         strcpy(newRecEntry->id, r.id);
         strcpy(newRecEntry->firstname,r.firstname);
         strcpy(newRecEntry->lastname,r.lastname);
         newRecEntry->next = NULL;
         newRecEntry->prev = NULL;
      }
      // Find the appropriate position for the node and insert accordingly
      // Check to see if the list is empty
      if (first == NULL)
      {
         first = newRecEntry;
         last = newRecEntry;
      }
      else if ( r.lastname>last.lastname)
      {




      else
      {

   return 0;
}

/*int DeleteItem(char* ID)

我应该能够在列表的开头、中间和结尾插入。根据 ID 从列表中删除一个项目,并根据用户输入以升序或降序打印列表,但我首先只想处理将项目添加到所述列表中。我的函数定义如下,也包含一些错误

列表.cpp

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

// These pointers refer to the head and tail of the list.
   rec* first = NULL;
   rec* last = NULL;

int AddItem( Rec r )
{

   rec* newRecEntry;
   rec* current = NULL;
   rec* previous = NULL;

   // Check for duplicate id
   current = first;
   while (current)
   {
     if( strcmp(current -> id, r.id) == 0)
      {
         return 0;
      }
     else
     // Create a new node
      {
         newRecEntry = new Rec;
         newRecEntry->id = new char[strlen(r.id)+1];
         strcpy(newRecEntry->id, r.id);
         strcpy(newRecEntry->firstname,r.firstname);
         strcpy(newRecEntry->lastname,r.lastname);
         newRecEntry->next = NULL;
         newRecEntry->prev = NULL;
      }
      // Find the appropriate position for the node and insert accordingly
      // Check to see if the list is empty
      if (first == NULL)
      {
         first = newRecEntry;
         last = newRecEntry;
      }
      else if ( r.lastname>last.lastname)
      {




      else
      {

   return 0;
}

/*int DeleteItem(char* ID)
{
   rec
}
*/



/*void printList(int order)
{
loop
 {
   cout << ptr -> Id << " ";
   cout << ptr -> firstname << " ";
   cout << ptr -> lastname << " ";
   cout << ptr -> prev << " ";  // address of previous
   cout <<  ptr << " ";   // address of item
   cout << ptr -> next << " ";  //  address of next item
 }

}

主要如下:

#include <iostream>
#include "list.h"
#include <string.h>  // <string>

using namespace std;

void main (void)
{
   int choice, printorder;
   char idbuffer[100];
   rec r;


do
{
  cout << "Enter your choice 1 Add, 2 Delete, 3 Print, 0 quit "<<endl;
  cin >> choice;

   switch ( choice )
   {
      case 1:  //AddItem
         cout << "\nEnter ID ";
         cin >> idbuffer;

         r.id = idbuffer;
         cout << "\nFirst Name ";
         cin >> r.firstname;
         cout << "\nLast Name ";
         cin >>  r.lastname;
         if ( AddItem ( r ) )
         {
            cout << "\nSuccess!\n";
         }
         else
         {
            cout << "\nItem failed to be added\n";
         }

         break;
      case 2:  //Delete
         cout << "\nEnter id :";
         cin >> idbuffer;
         if ( DeleteItem ( idbuffer ) )
         {
            cout << "\nDelete OK\n";
         }
         else
         {
            cout << "\nDelete Failed for " << idbuffer;
         }
         break;
      case 3: // Print
        cout << "Enter order 0 - Ascending, 1 - Descending\n";
        cin >> printorder;
        PrintList (printorder);
        break;
      case 0:  // quit
         break;


      default: // bad choice
         break;
   } // end switch

}
while ( choice != 0 );// end do while
}  // end main
4

2 回答 2

1

它可能看起来不像,但即使是这个功能

int AddItem(Record entry)
{
   Record* newRecordPointer;
   newRecordPointer=new Record;
   strcpy(newRecordPointer->firstName,entry.firstName);
   strcpy(newRecordPointer->lastName,entry.lastName);
   newRecordPointer->ID=new char[strlen(entry.ID)+1];
   strcpy(newRecordPointer->ID, entry.ID);
   return 0;
}

正在尝试做太多事情。

让我们编写将项目添加到列表的伪代码描述:

  1. 创建一个新节点
  2. 使用提供的填充新节点
  3. 新节点附加到列表

我已经标记了所涉及的动词名词,您已经可以看到您的函数中缺少一个名词。您要求AddItem将一个项目添加到列表中......但您没有给它一个可以处理的列表。

清楚地写出您的期望也很有用:

  1. 之前AddItem被称为:
    • 它需要一个清单来处理
    • 我们没有列表容器类,只有记录,所以我们必须传递一个Record
    • 假设我们要在传入后添加新项目Record
  2. 之后AddItem被称为:
    • 无论Record我们传入什么,它Next都应该指向新节点
    • 新节点Previous应该指向传入的节点
    • 等等等等(这些是标准的双向链表插入行为)
  3. 稍后注意:我们还没有描述我们如何存储一个空列表
    • 如果它是一个循环列表,一个空列表将是一个RecordNextPrevious成员指向自身
    • 如果它是线性的,它们可能都是 NULL 而不是
    • 它可能只是一个 NULL 指针,但是将第一个节点添加到空列表需要更多的努力

因此,假设可能起作用的最小功能是:

void AddItem(Record *insert_after, Record value)
{
    Record *new_node = CreateRecord();
    CopyRecordValues(new_node, &value);
    AttachAfter(insert_after, new_node);
}

请注意,如果我们正在编写真正的 C++,前两行可以只使用复制构造函数Record *new_node = new Record(value),但要从我们开始的地方获得惯用的 C++ 代码,需要进行更多的更改。


现在,鉴于此,您能否:

  • 实现这三个功能?(CreateRecord并且CopyRecordValues已经在您当前的代码中处理)
  • 为您的其他操作编写等效的伪代码,然后自己翻译?
于 2013-03-07T18:48:32.783 回答
0

尝试改变这个:

int AddItem(Record entry);

对此:

Record* AddItem(Record entry, Record *insertion_point = NULL );

如果insertion_pointNULL,您可以假设Record是新列表的开始。

现在您有足够的信息来设置NextPrevious指针,并返回新创建的节点。

于 2013-03-07T18:04:40.330 回答