清单 2 未在控制台上打印出来

List 2 not Printing out on console

代码应该打印出List of numbers user entered as list 1,告诉你这个列表有多长,让你搜索一个号码,然后删除一个号码。一旦号码被删除,它应该将其保存到列表 2,然后打印出号码。该代码一直运行到列表 2。由于某种原因,列表 1 要么没有进入列表 2,要么只是没有打印出列表 2。如果能帮助我弄清楚为什么会这样,我将不胜感激。

main.cpp

#include <iostream> 
#include "circularLinkedList.h"

using namespace std; 

void testCopyConstructor(circularLinkedList<int> oList);

int main()
{
    circularLinkedList<int> list1, list2;
    int num;

    cout << "Enter number ending with -999" << endl;
    cin >> num;

    while (num != -999)
    {
        list1.insertNode(num);
        cin >> num;
    }

    cout << endl;

    cout << "List 1: ";
    list1.print();
    cout << endl;

    cout << "Length List 1: " << list1.length() << endl;

    cout << "Enter the number to be searched:  ";
    cin >> num;
    cout << endl;

    if (list1.search(num))
        cout << num << " found in the list" << endl;
    else
        cout << num << " not in the list" << endl;

    cout << "Enter the number to be deleted: ";
    cin >> num;
    cout << endl;

    list1.deleteNode(num);

    cout << "After deleting the node, "
         << "List 1: ";
    list1.print();
    cout << endl;

    cout << "Length List 1: " << list1.length() << endl;

    list2 = list1;

    cout << "List 2: ";
    list2.print();
    cout << endl;

    cout << "Length List 2: " << list2.length() << endl;

    testCopyConstructor(list1);

    cout << "List 1: ";
    list1.print();
    cout << endl;

    return 0;
}

void testCopyConstructor(circularLinkedList<int> oList)
{
}

circularLinkedList.h

#ifndef H_circularLinkedList
#define H_circularLinkedList

#include <iostream>
#include <cassert> 
using namespace std;

template <class Type> 
struct nodeType
{
  Type info;
  nodeType<Type> *link;
};

template <class Type>
class circularLinkedList
{
public:
    const circularLinkedList<Type>& operator=
                      (const circularLinkedList<Type>&); 
    //Overloads the assignment operator.
    void initializeList(); 
    //Initializes the list to an empty state.
      //Postcondition: first = nullptr, last = nullptr,
    //                count = 0
    bool isEmptyList();
    //Function to determine whether the list is empty. 
    //Postcondition: Returns true if the list is empty;
    //               otherwise, returns false.

    void print() const;

  int length();
    //Function to return the number of nodes in the 
    //list.
    //Postcondition: The value of count is returned.
    void destroyList();
    //Function to delete all the nodes from the list.
      //Postcondition: first = nullptr, last = nullptr, 
    //               count = 0
    Type front(); 
    //Function to return the first element of the list.
    //Precondition: The list must exist and must not be
    //empty.
      //Postcondition: If the list is empty, then the 
    //               program terminates; otherwise, 
      //               the first element of the list is 
    //               returned.
    Type back(); 
       //Function to return the last element of the
       //list.
    //Precondition: The list must exist and must not
    //be empty.
    //Postcondition: If the list is empty, then the 
    //               program terminates; otherwise,
    //               the last element of the list is 
    //               returned.

  bool search(const Type& searchItem);
    //Function to determine whether searchItem is in 
    //the list.
    //Postcondition: Returns true if searchItem is found
    //               in the list; otherwise, it returns
    //               false.

    void insertNode(const Type& newitem);

    void deleteNode(const Type& deleteItem);
      //Function to delete deleteItem from the list.
    //Postcondition: If found, the node containing 
      //               deleteItem is deleted from the 
    //                list, first points to the first
    //                node, and last points to the last 
    //                node of the updated list. 

    circularLinkedList(); 
      //Default constructor
    //Initializes the list to an empty state.
    //Postcondition: first = nullptr, last = nullptr, 
    //               count = 0 

    circularLinkedList(const circularLinkedList<Type>& otherList); 
         //Copy constructor

    ~circularLinkedList();   
      //Destructor
      //Deletes all the nodes from the list.
      //Postcondition: The list object is destroyed. 

protected:
    int count;    //variable to store the number of 
          //elements in the list
    nodeType<Type> *first; //pointer to the first node of 
                           //the list
    nodeType<Type> *last;  //pointer to the last node of 
                           //the list 
private:
    void copyList(const circularLinkedList<Type>& otherList); 
    //Function to make a copy of otherList.
    //Postcondition: A copy of otherList is created 
    //               and assigned to this list.
};

template <class Type>
bool circularLinkedList<Type>::isEmptyList()
{
    return (first == NULL);
  // function to determine if list is empty
}

template <class Type>
circularLinkedList<Type>::circularLinkedList() // default constructor
{
  first = nullptr;
  count = 0;
}

template <class Type>
void circularLinkedList<Type>::destroyList()
{
      nodeType<Type> *temp;
        nodeType<Type> *current = NULL;

        if (first != NULL)
        {
            current = first->link;
            first->link = NULL;
        }

        while (current != NULL)
        {
            temp = current;
            current = current->link;
            delete temp;
        }

        first = NULL;   //initialize last to NULL; first has already
                        //been set to NULL by the while loop
        count = 0;
  // function to destroy the list
}


template <class Type>
void circularLinkedList<Type>::initializeList()
{
  destroyList(); //if the list has any nodes, delete them
}

template <class Type>
int circularLinkedList<Type>::length()
{
  return count;
  // function to find the length of the list
}  // end length

template <class Type>
Type circularLinkedList<Type>::front()
{   
    assert(first != nullptr);
    return first->link->info; //return the info of the first node 
}//end front


template <class Type>
Type circularLinkedList<Type>::back()
{   
    assert(first != nullptr);
    return first->info; //return the info of the first node 
}//end back

template <class Type>
bool circularLinkedList<Type>::search(const Type& searchItem)
{
      nodeType<Type> *current; //pointer to traverse the list
        bool found = false;

        if (first != NULL)
        {
            current = first->link;

            while (current != first && !found)
            {
                if (current->info >= searchItem)
                    found = true;
                else
                    current = current->link;

                found = (current->info == searchItem);
            }
        }

        return found;
    }
    // function to search the list for a given item
//end search

template <class Type>
void circularLinkedList<Type>::insertNode(const Type& newitem)
{
      nodeType<Type> *current; //pointer to traverse the list
        nodeType<Type> *trailCurrent; //pointer just before current
        nodeType<Type> *newNode;  //pointer to create a node

        bool  found;

        newNode = new nodeType<Type>; //create the node

        newNode->info = newitem;   //store newitem in the node
        newNode->link = NULL;      //set the link field of the node
                                   //to NULL

        if (first == NULL)  //Case 1    e.g., 3
        {
            first = newNode;
            first->link = newNode;
            count++;
        }
        else
        {
            if (newitem >= first->info)//e.g., 25 > 3
            {
                newNode->link = first->link;
                first->link = newNode;
                first = newNode;
            }
            else
            {
                trailCurrent = first; //e.g., 1 < 3
                current = first->link;
                found = false;

                while (current != first && !found)
                    if (current->info >= newitem)
                        found = true;
                    else
                    {
                        trailCurrent = current;
                        current = current->link;
                    }

                trailCurrent->link = newNode;
                newNode->link = current;
            }

            count++;
        }
  // function to insert an item into the list
}//end insertNode

template <class Type>
void circularLinkedList<Type>::deleteNode(const Type& deleteItem)
{
   nodeType<Type> *current; //pointer to traverse the list
        nodeType<Type> *trailCurrent; //pointer just before current
        bool found;

        if (first == NULL)    //Case 1; list is empty.
            cout << "Can not delete from an empty list." << endl;
        else
        {
            found = false;
            trailCurrent = first;
            current = first->link;

            while (current != first && !found)
                if (current->info >= deleteItem)
                    found = true;
                else
                {
                    trailCurrent = current;
                    current = current->link;
                }

            if (current == first)
            {
                if (first->info == deleteItem)
                {
                    if (first == first->link)
                        first = NULL;
                    else
                    {
                        trailCurrent->link = current->link;
                        first = trailCurrent;
                    }
                    delete current;

                    count--;
                }
                else
                    cout << "The item to be deleted is not in the list." << endl;
            }
            else
                if (current->info == deleteItem)
                {
                    trailCurrent->link = current->link;
                    count--;
                    delete current;
                }
                else
                    cout << "Item to be deleted is not in the list." << endl;
        } 
  // function to delete an item from the list
} //end deleteNode


  //Overloading the stream insertion operator
template <class Type>
void  circularLinkedList<Type>::print() const
{
    nodeType<Type> *current; //pointer to traverse the list

        current = first->link;

        while (current != first) //while more data to print
        {
            cout << current->info << " ";
            current = current->link;
        }

        cout << first->info << " ";
  // function to print the list
}

template <class Type>
circularLinkedList<Type>::~circularLinkedList() // destructor
{
  destroyList(); 
}//end destructor


template <class Type>
void circularLinkedList<Type>::copyList
                    (const circularLinkedList<Type>& otherList) 
{
        first = NULL;
        copyList(otherList);
   // function to copy the list
}//end copyList

  //copy constructor
template<class Type>
circularLinkedList<Type>::circularLinkedList
                    (const circularLinkedList<Type>& otherList) 
{
  first = nullptr;

  copyList(otherList);

}//end copy constructor

  //overload the assignment operator
template <class Type>
const circularLinkedList<Type>& circularLinkedList<Type>::operator=
          (const circularLinkedList<Type>& otherList)
{ 
  if (this != &otherList) //avoid self-copy
  {
    copyList(otherList);
  }//end else

  return *this; 
}

#endif

Kristina,通过让 copyList 递归调用 copyList(otherList);,您将永远循环下去。

退一步。当您创建 circularLinkedList<int> 的实例时,您已经在 main() 中默认构造了 list1list2。因此,当您调用 list2 = list1; 时,您正在调用 复制赋值 成员函数。在您当前的代码中,您的复制分配只是调用 copyList (这本身就很好)但是,您的 copyList 有点薄并且没有按照您的意图进行,例如仅包含:

template <class Type>
void circularLinkedList<Type>::copyList
                    (const circularLinkedList<Type>& otherList) 
{
        first = NULL;
        copyList(otherList);      /* what happens when you get here? */
   // function to copy the list
}//end copyList

看到问题了吗?您调用 circularLinkedList<Type>::operator=,它调用 circularLinkedList<Type>::copyList,然后您再次递归调用相同的函数 over-and-over-and-over。

(这是您在调试器中要注意的地方——在 copyList 中点击 's'(步骤)后只看到 first = NULL; 并在 copyList准备再次执行first = NULL;,有问题...)

但是,总的来说,您在程序结构和复制赋值调用方面的思考是正确的 copyList,您只需要实际复制列表...

那怎么办?您需要将 otherList 引用中的所有节点复制到新列表。您可以轻松遍历 otherList,就像您在 copyList 正上方的 print() 中所做的一样,只是您需要 insertNode 而不是输出每个值。

(在 print() 中你从 first->link 而不是 first 开始迭代的事实对于循环列表来说有点特殊,但是......这更像是一个命名问题这里最重要的是,遍历工作正常)

在您的 copyList 中遍历 otherList 并调用 insertNode 将与 print() 中的遍历完全相同。它可以像这样简单:

template <class Type>
void circularLinkedList<Type>::copyList
                    (const circularLinkedList<Type>& otherList) 
{
    nodeType<Type> *iter = otherList.first->link;

    while (iter != otherList.first) {
        this->insertNode (iter->info);
        iter = iter->link;
    }
    this->insertNode (iter->info);

} //end copyList

(你可以使用 current 而不是 iter 如果这对你来说更有意义,但我发现 iter 更能描述我对参考所做的事情,但是这只是个人喜好)。

现在您的复制赋值复制构造函数应该可以正常工作并被正确调用。在 main() 中根本不需要 testCopyConstructor。要同时测试 复制赋值 复制构造函数 ,您可以简单地在 main 中添加另一个列表实例,它会调用复制构造函数而不是复制作业,例如

    list2 = list1;           /* copy assignment called */

    cout << "List 2: ";
    list2.print();
    cout << endl;

    cout << "Length List 2: " << list2.length() << endl;

    cout << "List 1: ";
    list1.print();
    cout << endl;

    circularLinkedList<int> list3 (list2);   /* copy constructor called */
    cout << "\nList 3: ";
    list3.print();
    cout << "\n";

例子Use/Output

放在一起后,您应该能够按预期执行您的代码,例如:

$ ./bin/llcirmain
Enter number ending with -999
1 2 3 4 5 -999

List 1: 1 2 3 4 5
Length List 1: 5
Enter the number to be searched:  4

4 found in the list
Enter the number to be deleted: 3

After deleting the node, List 1: 1 2 4 5
Length List 1: 4
List 2: 1 2 4 5
Length List 2: 4
List 1: 1 2 4 5

List 3: 1 2 4 5

检查一下,如果您还有其他问题,请告诉我。 (并考虑从头文件中删除 using namespace std;,您不想在可能使用您的头文件的所有源文件中包含完整的标准名称空间)。