【问题标题】:Doubly linked list .Logical error双向链表.逻辑错误
【发布时间】:2016-10-29 16:40:06
【问题描述】:

这是一个程序,它从用户那里获取学生姓名和注册号,并将其存储在双向链表中。我在最后插入节点。但是在while循环中有一个逻辑错误。它需要名称和注册。编号但随后停止。请帮助

 class dlist{

        struct node{
      string name;
      string regno;
      node *next;
      node *prev;
   };
    public:
      node *head,*tail;
      void insert(string,string);
      void search(string);
};

    void dlist::insert(string nn, string r)
{
       node *ptr,*newNode;
       tail=head;
       newNode= new node;
       newNode->name=nn;
       newNode->regno=r;
       newNode->next=NULL;
       newNode->prev=NULL;

  if(!head)
  {
      head=newNode;
       tail=head;
  }

 else 
  {
          ptr = head;
       while(ptr)
          ptr=ptr->next;
     newNode->next=tail;
     newNode->prev=ptr;
     ptr->next-newNode;
    }
  }

  void dlist::search(string n){

         node *ptr;
         ptr=head;
   while(ptr->next!=NULL)
   {
        if(ptr->name==n)
             cout<<"Name found..." <<ptr->name<<endl;
         ptr=ptr->next;
   }
  }


  int _tmain(int argc, _TCHAR* argv[])
   {
         dlist dl;
         string nn;
         string n;
         string r;
       for(int i=0;i<5;i++)
           {
              cout<<"Enter student's name: ";
              cin>>nn;
              cout<<"Enter student's Registration Number: ";
              cin>>r;
              dl.insert(nn,r);
           }
         cout<<"Enter a name to search: ";
         cin>>n;
         dl.search(n);
     }

【问题讨论】:

  • ptr-&gt;next-newNode 什么都不做......而且我们没有完整的源代码,所以我们无法帮助您(而是minimal reproducible example)。虽然这听起来很可疑:ptr-&gt;next = ptr-&gt;prev
  • 好的,我认为这可能有助于理解。对此感到抱歉。让我编辑
  • 你为什么要设置tail=head??
  • 我希望我在最后一个节点有一个链接,所以我使用了一个指针 tail.. 就像那时 newNode->next=tail
  • 我可以不用尾指针吗? else部分的while循环有问题。我想不出更好的解决方案

标签: c++ linked-list doubly-linked-list


【解决方案1】:

您在使用尾指针时遇到问题。我在下面改进了你的代码,并添加了 cmets 来解释我做了什么。如果您对我所做的事情还有任何疑问,请在 cmets 中提问,我很乐意澄清。

#include <tchar.h>
#include <string>
#include <iostream>

class dlist {

    struct node {
        string name;
        string regno;
        node* next;
        node* prev;
    };
public:
    node* head, * tail;

    void insert(string, string);

    void search(string);
    /**
     * You're using classes, so go ahead and provide a definition for the
     * constructor you're using. This one will initialize head and tail to
     * be null
     */
    dlist() : head(NULL), tail(NULL) {}

    /**
     * It's important to delete any memory you allocate so that you don't create a memory
     * leak.
     */
    virtual ~dlist() {
        while (head) {
            node* deleteMe = head;
            head = head->next;
            delete deleteMe;
        }
    }
};

void dlist::insert(string nn, string r) {
    // there is no good reason to set tail=head at this time.
    // and you don't need a ptr, that's why we have tail.
    node* newNode = new node;
    newNode->name = nn;
    newNode->regno = r;
    // no need to set newNode->prev now, as that will be taken care of later
    newNode->next = NULL;

    // if we don't have any nodes yet, we need to set head = newNode
    // and make head point to tail, which is also head.
    if (!head) {
        head = newNode;
        tail = head;
        head->next = tail;
        tail->prev = head;
        // head points to itself both ways
    } else {
        // we already have some nodes, so go ahead and
        // set newNode to go right after tail, then set tail = newNode
        // this will work even when head == tail
        tail->next = newNode;
        newNode->prev = tail;
        tail = newNode;
    }
}

void dlist::search(string n) {
    // it's nice to assign variables when you declare them, when you can
    node* ptr = head;
    // basically the same as what you had, but we are checking in the case
    // that tail has the node we want, which your code did not do.
    while (ptr) {
        if (ptr->name == n) {
            cout << "Name found... " << ptr->name << endl;
        }
        ptr = ptr->next;
    }
}


int _tmain(int argc, _TCHAR* argv[]) {
    dlist dl;
    string nn;
    string n;
    string r;
    for (int i = 0; i < 5; i++) {
        cout << "Enter student's name: ";
        cin >> nn;
        cout << nn << endl;
        cout << "Enter student's Registration Number: ";
        cin >> r;
        cout << r << endl;
        dl.insert(nn, r);
    }
    cout << "Enter a name to search: ";
    cin >> n;
    dl.search(n);
    return 0;
}

【讨论】:

  • 是的,它工作,但它不显示名称。搜索功能有问题。
  • 为什么要创建一个虚拟 dlist?没有它程序会运行吗>\??
  • @ShehlizahMalik virtual ~dlist() 是析构函数。如果您不提供析构函数,编译器将为您提供一个。但是,它不会知道在每次插入节点时删除您分配的所有内存,因此您需要自己执行此操作,否则您将拥有memory leak。至于输出不足,不知道发生了什么。它在我的电脑上运行良好。你的意见是什么?
  • 在 for 循环之后,当我输入程序停止的名称时,它会要求搜索一个名称。
  • 确切的输入是什么?如果您输入的名称不在列表中,则不会打印任何内容,程序将终止。
猜你喜欢
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
相关资源
最近更新 更多