Data structures 从链表中的最后一个元素高效地查找第n个元素

Data structures 从链表中的最后一个元素高效地查找第n个元素,data-structures,linked-list,Data Structures,Linked List,从单/双链接列表的最后一个元素中查找第n个元素的有效方法是什么?以下是从链接列表的最后一个元素中查找第n个元素的有效方法 struct Node{ int data; struct Node *next; }; int getNthFromLast(struct Node *head, int n){ struct Node *curr = head; struct Node *nthFromLast=NULL; int count=0; int

从单/双链接列表的最后一个元素中查找第n个元素的有效方法是什么?

以下是从链接列表的最后一个元素中查找第n个元素的有效方法

struct Node{
    int data;
    struct Node *next;
};

int getNthFromLast(struct Node *head, int n){
    struct Node *curr = head;
    struct Node *nthFromLast=NULL;
    int count=0;
    int value=-1;
    while(curr!=NULL){
        count++;
        curr=curr->next;
        if(count==n){
            nthFromLast=head;
        }else
            if(count>n){
                nthFromLast=nthFromLast->next;
            }
    }
    if(count>=n){
        value=nthFromLast->data;
    }
    return value;
}

此示例已用C++编写,并可在其他语言中类似地复制。该方法被传递一个指向链表的第一个节点的指针和最后一个元素的索引,它返回该元素的数据。如果位置不存在,则该方法返回-1

对于双链表和循环链表,也可以采取类似的方法

struct Node{
    int data;
    struct Node *next;
};

int getNthFromLast(struct Node *head, int n){
    struct Node *curr = head;
    struct Node *nthFromLast=NULL;
    int count=0;
    int value=-1;
    while(curr!=NULL){
        count++;
        curr=curr->next;
        if(count==n){
            nthFromLast=head;
        }else
            if(count>n){
                nthFromLast=nthFromLast->next;
            }
    }
    if(count>=n){
        value=nthFromLast->data;
    }
    return value;
}

编辑:如果是双链接列表,只需反向移动n个项目即可。完全忘记了。推荐理由:吉姆·米谢尔(Jim Mischel)

这是一种从链表的最后一个元素中查找第n个元素的有效方法

struct Node{
    int data;
    struct Node *next;
};

int getNthFromLast(struct Node *head, int n){
    struct Node *curr = head;
    struct Node *nthFromLast=NULL;
    int count=0;
    int value=-1;
    while(curr!=NULL){
        count++;
        curr=curr->next;
        if(count==n){
            nthFromLast=head;
        }else
            if(count>n){
                nthFromLast=nthFromLast->next;
            }
    }
    if(count>=n){
        value=nthFromLast->data;
    }
    return value;
}

此示例已用C++编写,并可在其他语言中类似地复制。该方法被传递一个指向链表的第一个节点的指针和最后一个元素的索引,它返回该元素的数据。如果位置不存在,则该方法返回-1

对于双链表和循环链表,也可以采取类似的方法

struct Node{
    int data;
    struct Node *next;
};

int getNthFromLast(struct Node *head, int n){
    struct Node *curr = head;
    struct Node *nthFromLast=NULL;
    int count=0;
    int value=-1;
    while(curr!=NULL){
        count++;
        curr=curr->next;
        if(count==n){
            nthFromLast=head;
        }else
            if(count>n){
                nthFromLast=nthFromLast->next;
            }
    }
    if(count>=n){
        value=nthFromLast->data;
    }
    return value;
}

编辑:如果是双链接列表,只需反向移动n个项目即可。完全忘记了。学分:吉姆·米谢尔(Jim Mischel)

有一个双链接列表,你所要做的就是从末尾向后数
n
个节点。还要注意的是,从根本上讲,这并不比完全扫描列表以找到计数,然后从头开始并向前移动
(count-n)
次效率高或低。就双链接列表点达成一致,有点忘了考虑这一点。谢谢你强调这一点。将编辑。尽管如此,如果您先找到count
(循环1)
,然后向前移动
(count-n)
次,您不会徒劳地执行
(count-n)
长度的第二个循环吗?如果,假设n的值在较小的一侧,那么实际上您必须遍历列表的一半以上,而没有任何有意义的增益。所以我想这就是第二个指针开始发挥作用的地方,它跟踪
(count-n)
th项的位置。是的,但是如果你用两次传球,你只会在循环中增加一个指针。在您的版本中,您最终在一次传递中执行
count+(count-n)
指针增量。在两遍版本中,您在一遍中进行
count
增量,在第二遍中进行
(count-n)
增量。无论哪种方式,所做的工作量都是相同的。尽管如此,对所有计算使用单个循环似乎更干净,因为它只涉及一次遍历。对于双链表,您所要做的就是从末尾向后计数
n
节点。还要注意的是,从根本上讲,这并不比完全扫描列表以找到计数,然后从头开始并向前移动
(count-n)
次效率高或低。就双链接列表点达成一致,有点忘了考虑这一点。谢谢你强调这一点。将编辑。尽管如此,如果您先找到count
(循环1)
,然后向前移动
(count-n)
次,您不会徒劳地执行
(count-n)
长度的第二个循环吗?如果,假设n的值在较小的一侧,那么实际上您必须遍历列表的一半以上,而没有任何有意义的增益。所以我想这就是第二个指针开始发挥作用的地方,它跟踪
(count-n)
th项的位置。是的,但是如果你用两次传球,你只会在循环中增加一个指针。在您的版本中,您最终在一次传递中执行
count+(count-n)
指针增量。在两遍版本中,您在一遍中进行
count
增量,在第二遍中进行
(count-n)
增量。无论哪种方式,所做的工作量都是相同的。虽然,对所有计算使用一个循环似乎更干净,因为它只涉及一次遍历。这似乎毫无意义,没有办法比平凡的方式做得更好。这似乎毫无意义,没有办法比平凡的方式做得更好。