比较链表,C++,相同的顺序但可以不同的抓住

Posted

技术标签:

【中文标题】比较链表,C++,相同的顺序但可以不同的抓住【英文标题】:comparing linked list , C++ , same order but can be different seize 【发布时间】:2011-04-18 05:02:07 【问题描述】:

假设我们得到了函数定义

bool sameValsOrder(node *p , node *q)

我们必须编写一个函数来比较两个链表,如果它们具有相同的顺序,则返回 true 否则返回 false [77777] 和 [77] -> 正确

[1234567] 和 [1234555567] -> 真

bool sameValsOrder (node *p , node *q)

     if ( q==NULL && p==NULL)
        return true;
     else if ((q=NULL && p != NULL)|| (p=NULL && q!= NULL))
         return false;
     else if ( q != NULL && p != NULL)
           while ( q != 0 && p != 0)
            
                if (p->data != q->data)
                    
                        return false;
                        break;
                    
                else 
                    
                  p= p-> next ;
                  q= q-> next;
                     
            
             return true;
    

上面的代码是我的答案,但我意识到了一些事情。我是否需要在 while 循环中添加更多 if 语句,以便 [77777] 和 [7] 的链接列表应该返回 true,因为它的相同顺序只是更少。

【问题讨论】:

嵌套的if 语句的else 部分缺少大括号。 我认为当前函数所做的只是告诉您列表是否具有相同的前 N ​​个数据值,其中 N 是较短列表的长度。 @larsmans - if 部分也是!也许是蟒蛇 @Brad 是的,我的问题是如何添加它,以便我可以比较不同值的长度 @larsman nice catch 我再次编辑主帖 @Brad:似乎 OP 只是编辑了问题而没有出现。当前的代码甚至不是格式良好的 C++。 【参考方案1】:

根据您所写的内容,您实际上并不关心这些值,但如果列表是有序的,您想返回 true 吗?似乎您只需要遍历列表中的每个值。只要 NEXT 值不小于 PREVIOUS 值,就继续遍历列表。如果到达末尾,则返回 true,因为列表是有序的。如果在任何时候你遇到一个小于任何先前值的值,那么就在此处返回 false。

#include <iostream>

using namespace std;

class node
public:
    node()next = NULL;
    int data;
    node * next;
;
class myList
public:
    myList()pRoot = NULL;
    void add(int data);
    node * pRoot;
;
bool sameValsOrder (node *p , node *q)

     if ( q==NULL && p==NULL) // If both lists are empty
        return true;
     else if ((q==NULL && p != NULL)|| (p==NULL && q!= NULL)) // One list is empty and the other is not
         return false;
     else if ( q != NULL && p != NULL) //Both lists contain values we must check
           
         int temp; //I am going to assume a singly linked list (no access to previous value), need this to hold previous value
         temp = p->data; 
         while (p->next != NULL) //The list still contains elements
         
            if (p->next->data < temp) //The value in the current node is LESS than our temp, then list is out of order so return false
                return false;
            else  //Otherwise move to the next node
                temp = p->data;
                p = p->next;
            
         
         temp = q->data; //Reset temp for q
         //Do the same thing for q
         while (q->next != NULL) //The list still contains elements
         
            if (q->next->data < temp) //The value in the current node is LESS than our temp, then list is out of order so return false
                return false;
            else  //Otherwise move to the next node
                temp = q->data;
                q = q->next;
            
         
     
     return true; //If we are this are then both lists should be ordered

int main()

    myList * p = new myList();
    myList * q = new myList();
    p->add(7);
    p->add(6);
    p->add(5);
    p->add(4);
    p->add(3);
    p->add(2);
    p->add(1);

    q->add(7);
    q->add(6);
    q->add(5);
    q->add(5);
    q->add(5);
    q->add(5);
    q->add(4);
    q->add(3);
    q->add(2);
    q->add(1);
    cout << sameValsOrder (p->pRoot, q->pRoot) << endl;
    return 0;

void myList::add(int data)

    node * nodeToAdd = new node();
    nodeToAdd->data = data;
    if(pRoot == NULL) //List is empty
    
        pRoot = nodeToAdd;
        pRoot->next = NULL;
    
    else //List not empty insert new node at beginning
    
        nodeToAdd->next = pRoot;
        pRoot = nodeToAdd;
    

【讨论】:

@Pete 这似乎是正确的,但下一个值必须等于前一个值,不小于或大于。例如。 [ 1 2 3 4 5 6 4 2 2] 和 [ 1 2 3 4 5 6 6 6 4 2 2 ] 没问题! @ricedragon 我将保留代码,但显然我不明白其中任何一个的顺序如何。我能看到做你想做的唯一方法是每次都检查列表直到你当前的位置,看看当前位置是否已经存在? @Pete 似乎有效,所以我需要 3 个 while 循环来检查它。这就是我失踪的原因,而且看起来还不错,我会慢慢地再次追踪它。感谢您的回复 @ricedragon 没问题。我为您提供的两个示例编写了代码。在您的原始帖子中,您给出了 [1234567] 和 [1234555567] -> true。给定这些值,我的函数应该返回 true。但是,鉴于您在此处评论的值,需要做更多的工作。 @Pete 我不明白为什么有 2 个 temp 使用相同的名称。不应该是 temp = p->data while (q->next != NULL) if (q->data != temp) return false else q->next blah .. 代码标签在那里不起作用,它的只是顺序,所以 [1 1 1 2] 等于 [1 2]。并且 temp 不应该有不同的名称,例如 temp 1 和 temp 2,这样它就不会相互覆盖?我的老师说我不明白这个问题..我在这里发帖,一半的人也不明白....叹息....【参考方案2】:
 while ( q != 0 && p != 0)
        
            if (p->data != q->data)
                    return false;
                    break;
            else 
              p= p-> next ;
              q= q-> next;
        

这是错误的,当它不相同但 p 和 q 的大小可能不同时,你返回 false [1112] [12] 将返回不应该的假

【讨论】:

【参考方案3】:
while(q!=NULL || p!=NULL)
    
    if(q->data==p->data)    
     
        p=p->next;
        break;
    
    else(q->data <  p->data)
    q=q->next;

基本上,只有当值不匹配时,您才应该在第一个链表中前进,否则遍历第二个链表直到匹配。

【讨论】:

@garima 你能修复代码吗?有点难读...谢谢 您应该首先检查两个链表的长度,然后遍历较大的链表,例如 Q... 将其与另一个链表的值进行比较,例如 P.. 如果 Q 中的值较小.. 下一步。否则 P->next..【参考方案4】:

OP 已在 cmets 中表示,他希望考虑具有相同数据的节点的“运行”作为匹配,即使这些运行在 2 个列表中具有不同的长度。这简化了(q-&gt;data == p-&gt;data) 然后跳过组成运行的节点。

这是一些伪代码; C 实现实际上并不复杂(尽管可能要多几行):

bool sameValsOrder (node *p , node *q)

    while not at the end of either list, and the current nodes are the same 

        skip run in q, taking care to deal with the NULL at the end of the list

        skip run in p, taking care to deal with the NULL at the end of the list
    

    if we've reached the end of both lists, they are equivalent

C 实现:

bool sameValsOrder (node *p , node *q)

    while (q && p && (q->data == p->data)) 
        /* find next different node in each list (ie., skip runs) */

        int tmp = q->data;  /* or whatever type `data` is */

        while (q && (q->data == tmp)) 
            q = q->next;
        

        while (p && (p->data == tmp)) 
            p = p->next;
        
    

    /*
     * we've either reached the end of one or both lists, 
     *  or have found a `data` difference
     */

    if (p == q) 
        /* should happen only when `q` and `p` are NULL */
        assert(q == NULL);
        assert(p == NULL);

        /* we've reached the end of both lists, so they're 'equivalent' */

        return true;
    

    return false;

【讨论】:

以上是关于比较链表,C++,相同的顺序但可以不同的抓住的主要内容,如果未能解决你的问题,请参考以下文章

链表适用于( )查找

java算法--链表

(王道408考研数据结构)第二章线性表-第三节5:顺序表和链表的比较

面试题:数组和顺序表链表的区别

链表是啥!那个编程语言中有的,和数组有啥区别

C语言问题,比较复杂