【问题标题】:How to remove an arbitrary node while traversing a singly linked list?如何在遍历单链表时删除任意节点?
【发布时间】:2012-03-14 01:29:32
【问题描述】:

我有一个包含 x 个节点的单链表,其中一些节点是重复的。我需要在遍历列表时删除重复项,所以我最终得到一个只包含唯一节点的新列表。但是,我还需要计算所有重复项的平均值,以便唯一列表将包含这些平均值。

示例 1: 假设我有一个这样的列表: a[1] -> b[2] -> c[3] -> a[2] -> a[3] -> b[2] -> null

遍历列表后,我应该得到这个列表: a[2] -> b[2] -> c[3] -> 空

示例 2: 假设我有一个这样的列表: a[2] -> a[2] -> a[5] -> b[2] -> b[4] -> c[3] -> null

遍历列表后,我应该得到这个列表: a[3] -> b[3] -> c[3] -> null

我想我需要一种方法来删除重复节点,因为我正在遍历列表,但我不知道如何。有人可以指导我如何实现这一目标吗?一些伪代码会很棒。谢谢。

编辑:解决了我的问题。详情见答案...

【问题讨论】:

  • 您说要删除重复项,但您发布的示例有所不同。
  • 就像 Jakub 说的,我不明白为什么 a[1] 是重复的 a[2] 如果他们有不同的密钥。我错过了什么?
  • StackOverflow 不会为你做作业。关于从链表中删除节点有大量问题可供参考。遍历一个列表找到一个平均值也比较简单。有很多方法可以解决这个问题,但你的分配可能还有一些你没有列出的约束,比如有多少唯一符号,以及是否允许你将它复制到中间数据结构。写一些代码,问一个更具体的问题。
  • @KarlBielefeldt:这不是家庭作业,否则我会这样标记它。我没有要求任何代码,只是一些想法/伪代码如何解决我的问题。
  • Jakub & lucholes:对不起,如果我的问题不清楚。该节点有两个字段,即a [1]:id = a,value = 1。所以我想找到所有具有相同id的节点并平均它们的值。最后,我应该得到一个仅包含唯一 id 节点及其平均值的列表。

标签: c linked-list


【解决方案1】:

我找到了解决问题的方法。只是为了分享其他人将来是否面临同样的问题。

回顾一下,问题如下:我有一个单链表,其中包含 x 个节点(x 是任意的)。每个节点都有两个字段,即 id 和 value。在这个列表中,一些节点是重复的,即它们具有相同的 id。每个 id 的重复数也是任意的。我需要删除所有重复项,同时平均它们的值。最后,我应该得到一个仅包含唯一 id 节点(及其各自的平均值)的列表。唯一节点的数量也是任意的(事先不知道)。

示例 1:之前:a[1] -> b[2] -> c[3] -> a[2] -> a[3] -> b[2] -> null。之后:a[2] -> b[2] -> c[3] -> null

示例 2:之前:a[2] -> a[2] -> b[6] -> b[2] -> b[4] -> null。之后:a[2] -> b[4] -> null

伪代码:

  1. 将第一个 id 和 value 保存到变量中,即 id=head->id, val=head->val;
  2. 如果不为空则列表,即 head != null;
  3. 将 head 分配给当前指针并将 head->next 分配给下一个指针,即 currPtr=head; nextPtr=head->下一个;
  4. 当我们使用 next 指针遍历列表时,它不为空,即 nextPtr != null;
  5. 将 nextPtr 指向的节点与 id 进行比较。

    如果它们相同,则将节点的值添加到 val 中,即 val += nextPtr->val。设置当前下一个指针指向下一个下一个指针,即 currPtr->next = nextPtr->next。免费下一个Ptr。然后设置next指针指向当前的next指针,即nextPtr = currPtr->next.

    否则,将当前指针设置为下一个指针,将下一个指针设置为下一个下一个指针,即 currPtr=nextPtr;下一个点=下一个点->下一个;

  6. 一旦列表被 next 指针完全遍历,平均 val(如果需要可以添加到新列表中)。

  7. 删除第一个节点,所以现在 head 指向旧列表中的下一个节点。
  8. 重复步骤 2-7。

代码:

struct node {
    char id[32];
    int val;
    struct node *nextNode;
}; 

void deleteNode(struct node **startPtr) {
    struct node *currentPtr = *startPtr;

    *startPtr = currentPtr->nextNode;
    free(currentPtr);
}

.... //other functions

int main () {
    ...
    char id[32];
    int val, cnt;
    struct node *head = NULL, *currPtr, *nextPtr;

    .... //ask user to input the list 

    while (head!=NULL) {
        strcpy(id,head->id);
        val = head->val;
        cnt = 1;
        nextPtr = head->nextNode;
        currPtr = head;
        while (nextPtr != NULL) {
            if (strcmp(nextPtr->id,id)==0) {
                val += next->val;   
                cnt++;
                currPtr->nextNode = nextPtr->nextNode;
                free(nextPtr);
                nextPtr = currPtr->nextNode;
            } else {
                currPtr = nextPtr;
                nextPtr = nextPtr->nextNode;
            }
        }
        deleteNode(&head);
        printf("Node: %s, Value: %d\n",id,val/cnt); //or save into another list
    }

    .... //do other things
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-11
    • 2020-08-11
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    相关资源
    最近更新 更多