代码之家  ›  专栏  ›  技术社区  ›  Kristina Woods

列表2未在控制台上打印

  •  0
  • Kristina Woods  · 技术社区  · 6 年前

    代码应该打印出用户作为列表1输入的数字列表,告诉您列表有多长,让您搜索一个数字,然后删除一个数字。删除号码后,应将其保存到列表2中,然后打印出号码。代码一直运行到列表2。出于某种原因,列表1要么没有进入列表2,要么就是没有打印出列表2。如果能帮助我弄清楚为什么会发生这种情况,我将不胜感激。

    主要的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)
    {
    }
    

    循环链接列表。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
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   David C. Rankin    6 年前

    克里斯蒂娜 copyList 呼叫 copyList(otherList); 递归地,您将永远循环。

    后退一步。您已经默认构造了 list1 list2 在里面 main() 创建的实例时 circularLinkedList<int> . 所以当你打电话的时候 list2 = list1; 您正在调用 复制分配 成员函数。在当前代码中,复制分配只需调用 版权列表 (这本身很好)然而 版权列表 有点薄,不符合您的意愿,例如,仅包含:

    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 然后递归地反复调用同一个函数。

    (这是调试器中需要注意的地方--在点击 's' (步进)英寸 版权列表 只有看到 first = NULL; 找到你的后背 版权列表 准备好执行 第一个=空; 再说一次,出了点问题……)

    但是,总的来说,您在程序结构方面的思维是正确的,并且可以调用拷贝分配 版权列表 ,您只需要实际复制列表。。。

    那么该怎么办呢?您需要从 otherList 对新列表的引用。您可以轻松地遍历 其他列表 ,就像你在 print() 正上方 版权列表 ,除了输出每个值之外,您需要 insertNode .

    (事实上 打印() 您以开始迭代 first->link 而不是 first 对于循环列表来说有点奇怪,但是。。。这更像是一个命名问题,遍历工作正常)

    横向移动 其他列表 和呼叫 插入节点(insertNode) 在您的 版权列表 将与中的遍历完全相同 打印() . 它可以简单到:

    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 更详细地描述我对引用所做的操作,但这只是个人喜好)。

    现在您的 复制分配 复制构造函数 应正常工作并正确调用。你不需要 testCopyConstructor 在所有 main() . 要测试 复制分配 复制构造函数 ,您可以简单地在main中添加另一个list实例,该实例将调用复制构造函数,而不是复制赋值,例如。

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

    使用/输出示例

    总而言之,您应该能够按预期执行代码,例如:

    $ ./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; 在头文件中,您不希望在可能使用头文件的源文件中包含完整的标准命名空间)。