删除单链表中的第二大元素

时间:2017-06-15 08:38:37

标签: c++ c data-structures linked-list singly-linked-list

我目前正在尝试为自己编写数据结构框架。在普通情况下,从单链表中删除第二大节点可以完美地工作。但在特定的一个失败。这是我已经尝试过的:

//node.h
typedef struct Node {
    int value;
    struct Node *nextNode;
} Node;

//linkedlist.h
typedef struct LinkedList{
    Node *head;
    int count;
} LinkedList;

//liblinkedlist.c
int deleteSecondLargest(LinkedList *list){
    if(list->count==0)
        return 1;
    if(list->count==1)
        return 2;
    Node *temp = list->head;
    Node *largest = temp;
    Node *prev = NULL;
    Node *prev1 = NULL;
    Node *ptr = temp;

    //finding the second largest node
    while(temp!=NULL){
        if(temp->value > largest->value){
            largest = temp;
        }
        else if((temp->value!=largest->value) && (temp->value > ptr->value)){//here's the code failing
            prev1 = prev;
            ptr = temp;
        }
        prev = temp;
        temp = temp->nextNode;
    }

    //deleting it
    if(ptr==list->head)
        list->head = list->head->nextNode;
    else
        prev1->nextNode = ptr->nextNode;
    free(ptr);
    list->count--;
    return 0;
}
每当列表中的项目按照1332-> 34-> N的顺序时,代码在注释块中失败。 我可以理解它失败的原因,因为tempptr都持有1332而else if在第二次迭代中返回false,但我无法找到任何解决方案。此外,函数所在的文件已在函数定义上方进行了注释。 有什么帮助吗?

1 个答案:

答案 0 :(得分:1)

据我所知,您的代码的第一部分存在问题:在单链表中找到第二大元素。

事实上,此代码中存在三个问题:

  1. 使用第一个元素初始化ptr,第一个元素可能太大而不是第二个元素。
  2. 没有节点从largest降级为ptr。这意味着,对于列表34 -> 1332 -> N,您的代码也不起作用。
  3. 如果两个最大值具有相等的值,则忽略第二个。这意味着,对于列表123 -> 123 -> N,您的代码也不起作用。
  4. 找到两个最大值的算法如下:

    1. 初始化:使用最低可能值初始化两个当前最大值或特殊"未初始化"标志。
    2. 循环遍历所有元素:
      1. 使用当前值更新两个最大值。
    3. 实现:

      // Initialization
      Node *largest = nullptr; // for maximum, nullptr means "not initialized"
      Node *largest2 = nullptr; // for second maximum, nullptr means "not initialized"
      Node *prev_largest = nullptr; // for previous node for maximum
      Node *prev_largest2 = nullptr; // for previous node for second maximum
      
      // Iterations
      for (Node *cur = list->head, *prev = nullptr; // start of the loop: current node is head, prev is null
          cur != nullptr; // end of the loop: current node is null
          prev = cur, cur = cur->nextNode) { // loop iteration: move both current and prev nodes forward
      
          if (largest == nullptr || cur->value > largest->value) { // check if we need to update maximum
              // the node which was maximum is now second maximum
              prev_largest2 = prev_largest;
              largest2 = largest;
              // current node is now maximum
              prev_largest = prev;
              largest = cur;
          } else if (largest2 == nullptr || cur->value > largest2->value) { // check if we need to update second maximum
              // current node is now second maximum
              prev_largest2 = prev;
              largest2 = cur;
          }
      }
      // End of algorithm
      // Second maximum is now in variable largest2
      // Previous node for second maximum is now in variable prev_largest2
      

      另外,请注意,即使您的列表包含少于2个元素,此算法也会有效(在这种情况下,largest2最后会nullptr)。