列表2不在控制台上打印

时间:2018-02-21 02:20:51

标签: c++ linked-list cout

代码应打印出用户输入的列表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

1 个答案:

答案 0 :(得分:0)

Kristina,通过copyList递归调用copyList(otherList);,你只需要永远循环。

退后一步。在创建list1的实例时,您已在list2中默认构建main()circularLinkedList<int>。因此,当您拨打电话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,然后你再次反复调用同一个函数。

(这是您在调试器中注意的地方 - 在's'中点击copyList(步骤)之后,只看到first = NULL;并在copyList找到您的回复再次执行first = NULL;,有些事情是错误的......)

但是,总体而言,您在程序结构方面正确思考并且复制分配调用copyList,您只需要实际复制列表......

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

(在print()中,您以first->link开头而不是first进行迭代的事实对于循环列表来说有点特殊,但是...这在这里比命名问题更重要其他任何事情,遍历工作正常)

otherList中遍历insertNode并呼叫copyList将与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更能描述我对参考做的事情,但那是只是个人偏好。)

现在,您的副本分配复制构造函数应该可以正常调用。 testCopyConstructor中完全不需要main()。要测试副本分配复制构造函数,您只需在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";

示例使用/输出

完全放入后,您应该能够按预期执行代码,例如:

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