【问题标题】:Merge two sorted link lists合并两个排序的链接列表
【发布时间】:2012-10-31 23:14:04
【问题描述】:

我想通过指针操作合并两个已排序的链接列表,但在这一点上卡住了。无法找出错误。请帮帮我。我认为问题出在while循环中。我想让它节省空间,不想再做一个列表。

#include<iostream>
#include<conio.h>
using namespace std;
struct s
{
   int info;
   s *next;
};

int main()
{
    int i;
    char choice = 'y';
    s *ptr1, *ptr2, *start1, *start2, *reversedHead, *temp;
    ptr1= new s;
    start1=ptr1;
    cout<<"SIZE OF A NODE IS "<<sizeof(s)<<" BYTES"<<endl<<endl;
    while(choice=='y')
    {
                  cout<<"Enter info for node: ";
                  cin>>i;
                  ptr1->info = i;
                  cout<<"Do you wish to enter more nodes.? 'y'/'n'"<<endl;
                  cin>>choice;

                  if(choice=='y')
                  {
                                 ptr1->next = new s;
                                 ptr1 = ptr1->next;
                  }
                  else
                  {
                      ptr1->next = NULL;
                  }
    }
    choice = 'y';
    ptr2= new s;
    start2=ptr2;
    cout<<"SIZE OF A NODE IS "<<sizeof(s)<<" BYTES"<<endl<<endl;
    while(choice=='y')
    {
                  cout<<"Enter info for node: ";
                  cin>>i;
                  ptr2->info = i;
                  cout<<"Do you wish to enter more nodes.? 'y'/'n'"<<endl;
                  cin>>choice;

                  if(choice=='y')
                  {
                                 ptr2->next = new s;
                                 ptr2 = ptr2->next;
                  }
                  else
                  {
                      ptr2->next = NULL;
                  }
    }

    ptr1=start1;
    ptr2=start2;
    while(ptr1->next!=NULL || ptr2->next!=NULL)
    {
                         if(ptr1->info < ptr2->info)
                         {
                                       if(ptr1->next->info < ptr2->info)
                                                           ptr1=ptr1->next;
                                       else
                                       {
                                           ptr2=temp;
                                           ptr2=ptr2->next;
                                           temp->next=ptr1->next;
                                           ptr1->next=temp;
                                       }
                         }
                         else
                         {
                             if(ptr2->next->info < ptr1->info)
                                                 ptr2=ptr2->next;
                             else
                             {
                                 ptr1=temp;
                                 ptr1=ptr1->next;
                                 temp->next=ptr2->next;
                                 ptr2->next=temp;
                             }
                         }
    }
    if(ptr1->next==NULL)
                    ptr1->next=ptr2;
    else
        ptr2->next=ptr1;
    cout<<"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";                    
    if(start1->info>start2->info)
    {
                             ptr2=start2;
                             while(ptr2!=NULL){
                                              cout<<ptr2->info<<"\t";
                                              ptr2=ptr2->next;}
    } 
    else
    {
                             ptr1=start1;
                             while(ptr1!=NULL){
                                              cout<<ptr1->info<<"\t";
                                              ptr1=ptr1->next;}
    }          



    getch();
}

【问题讨论】:

  • 到底是什么问题?你试过调试吗?
  • 如果您提供了您在应用程序中尝试过的输入、您获得的输出以及您期望的输出,这将会有所帮助。另外,您没有使用std::list 有什么特别的原因吗?
  • 如果你只是想让代码工作,使用std::list然后使用方法std::list::merge();快速简单。如果您有其他原因(例如学习),您将有更具体的原因,而不仅仅是它不起作用
  • INPUTS-> 第一个列表中的 3,5,第二个列表中的 4,6。 OUTPUT(expected)->3,4,5,6 但是执行突然结束了。
  • 我没有使用 std::list::merge() 因为我必须学习合并和指针。

标签: c++ pointers merge linked-list


【解决方案1】:

您的 while 循环条件不太正确。

while(ptr1->next!=NULL || ptr2->next!=NULL)

很好,但只有当两个列表长度相同时!。当列表的长度不同时,ptr1-&gt;nextptr2-&gt;next 将是NULL,你会得到一个分段错误。更改为 &amp;&amp; 是不正确的做法,因为您将失去其中一个列表的结尾!

使用这个:

while((ptr1 != NULL && ptr2 != NULL) && (ptr1->next!=NULL || ptr2->next!=NULL))

现在,在你的循环中,你有这样的测试:

if(ptr1->next->info < ptr2->info)

替换为

if(ptr1 != NULL && ptr1->next->info < ptr2->info)

这样不等长的列表就不会提前终止,也不会在内部出现段错误。

接下来,在您的插入操作中,您执行以下操作

ptr1=temp;
ptr1=ptr1->next

ptr2=temp;
ptr2=ptr2->next;

这很糟糕,因为temp 是未定义的,因为您永远不会向它写入任何有效数据!这里的错误是你的作业是错误的。你应该分别完成temp=ptr1temp=ptr2

最后,修复等长输入列表的清理操作需要考虑这样一个事实,即不等长输入列表可能导致ptr1ptr2 成为NULL

if(ptr1 != NULL && ptr1->next==NULL)
    ptr1->next=ptr2;
else if (ptr2 != NULL)
    ptr2->next=ptr1;

一切似乎都很好。我已经在 1 3 5,2 4 61 3,21 4,2 31 3,2 3 上测试了生成的代码,所有这些都按我的预期工作。

【讨论】:

  • 该死。我怎么可能没有注意到这样的错误。谢谢@rook。 :) :p
  • FIRST LIST-> 3,5 SECOND LIST-> 4,6 现在输出是 3->4->5 (不是 6) :( :(
  • 谢谢。 :) 帮助表示赞赏。
【解决方案2】:

没有全部检查,但让我们从这里开始:

 while(ptr1->next!=NULL || ptr2->next!=NULL)

它应该是&amp;&amp; 而不是||,因为您不想在其中一个列表中的下一个条目为空时继续比较(您确实在 while 循环中的一个 if 中使用了它的内容)

【讨论】:

  • 我会建议您使用调试器并查看@Rook 的答案
猜你喜欢
  • 2016-03-30
  • 2011-01-21
  • 2010-09-05
相关资源
最近更新 更多