删除右侧值较大的节点

时间:2014-03-13 10:07:51

标签: c data-structures linked-list

删除右侧值较大的节点

给定单链表,删除右侧值较大的所有节点。

示例:

a)列表12-> 15-> 10-> 11-> 5-> 6-> 2-> 3-> NULL应改为15-> 11- > 6-> 3→NULL。请注意,已删除12,10,5和2,因为右侧有更大的值。

当我们检查12时,我们看到在12之后有一个值大于12的节点(即15),所以我们删除12。 当我们检查15时,我们发现15之后没有值大于15的节点,所以我们保留这个节点。 当我们这样做时,我们得到15-> 6-> 3

b)列表10-> 20-> 30-> 40-> 50-> 60-> NULL应该改变为60-> NULL。请注意,已删除10,20,30,40和50,因为它们在右侧都有更大的值。

c)不应更改列表60-> 50-> 40-> 30-> 20-> 10-> NULL。

我已经为它编写了函数。但它不起作用。

void remove_lower(struct node** head_ref)
{
   struct node* current = (*head_ref);

   if(current != NULL && current->next != NULL)
     return ;

   struct node* temp;

   while(current->next != NULL)
   {
      if(current->data > current->next->data)
      {
        temp = current->next;
        current = temp->next;
        free(temp);
      }
      else
         current = current->next;
   }
}

8 个答案:

答案 0 :(得分:3)

你应该跟踪"之前"项目并更新其" next"指针,否则你将在删除列表中不是第一个元素的同时打破列表。你算法也会删除所有" next"更大的元素"比当前元素。根据你的描述,你将删除"当前"元素如果右侧有更大的元素。所以你应该删除" current"元素,而不是下一个元素。

我建议使用以下方法(在ideone检查)此算法(不幸的是,O(N^2)):

void remove_lower(struct node** head_ref)
{
  struct node* current = (*head_ref);
  if(current == NULL || current->next == NULL)
    return ;

  struct node* prev = NULL, *next = NULL, *temp = NULL;
  while(current->next != NULL)
  {
    next = current->next;
    temp = next;
    /* check if there is any element greater than current */
    while(temp->next != NULL) {
        if (temp->data > current->data) {
            /* 
             * if some element is greater than current, then
             * delete current element
             */
            free(current);
            current = NULL;
            if (prev == NULL) {
                /* it was the first element, need to update the head */
                *head_ref = next;
            } else {
                prev->next = next;
            }
            break;
        }
        temp = temp->next;
    }
    /* if current element was not deleted */
    if (current != NULL) {
        prev = current;
    }
    current = next;
  }
}

输出:

输入数据:

2->7->1->36->6->0->5->-1->16->4->-2->3->-3->4->2->-4->1->-5->0->0->NULL

输出数据:

36->16->4->4->2->1->0->0->NULL

答案 1 :(得分:2)

您似乎已经改变了if语句中的条件。

if(current != NULL && current->next != NULL)
    return ;

将其更改为:

if (current == NULL || current->next == NULL)
    return ;

另一个:

  if(current->data > current->next->data)
  {

更改为:

  if(current->data < current->next->data)
  {

答案 2 :(得分:1)

这不是你的意思吗?

if(current == NULL || current->next == NULL)
  return ;

答案 3 :(得分:1)

算法以下是我的算法,其时间复杂度为O(n)

  1. 撤销列表。

  2. 遍历反向列表。保持最大化至今。如果下一个节点&lt; max,然后删除下一个节点,否则max = next node。

  3. 再次反转列表以保留原始订单。

    void reverseList(struct node **headref);
    void _delLesserNodes(struct node *head);
    
    /* Deletes nodes which have a node with greater value node
    on left side */
    void delLesserNodes(struct node **head_ref)
    {
        /* 1) Reverse the linked list */
        reverseList(head_ref);
    
        /* 2) In the reversed list, delete nodes which have a node
             with greater value node on left side. Note that head
             node is never deleted because it is the leftmost node.*/
        _delLesserNodes(*head_ref);
    
       /* 3) Reverse the linked list again to retain the
             original order */
        reverseList(head_ref);
    }
    
    /* Deletes nodes which have greater value node(s) on left side */
    void _delLesserNodes(struct node *head)
    {
        struct node *current = head;
    
        /* Initialize max */
        struct node *maxnode = head;
        struct node *temp;
    
        while (current != NULL && current->next != NULL)
        {
             /* If current is smaller than max, then delete current */
             if(current->next->data < maxnode->data)
             {
                  temp = current->next;
                  current->next = temp->next;
                  free(temp);
             }
    
             /* If current is greater than max, then update max and
                move current */
             else
             {
                  current = current->next;
                  maxnode = current;
             }
    
        }
    }
    //***********************************************
    
    void reverseList(struct node **headref)
    {
        struct node *current = *headref;
        struct node *prev = NULL;
        struct node *next;
        while(current != NULL)
        {
            next = current->next;
            current->next = prev;
            prev = current;
            current = next;
        }
        *headref = prev;
    }
    
  4. 如果有任何错误,请告诉我。

答案 4 :(得分:0)

   if(current != NULL && current->next != NULL)
     return ;

我觉得你这里有问题。这在第一步退出。你可能想写

   if(current == NULL || current->next == NULL)
     return ;

答案 5 :(得分:0)

如果你告诉我们更多关于什么不起作用的话会很有帮助,例如:输入和输出,或编译器错误,或调试器堆栈跟踪。

那就是说,我看到你正在删除下一个值,如果它小于当前(即它的前身,它的“左”),我认为这不是要求。根据要求,您是否应该删除当前,如果它小于下一个当前

答案 6 :(得分:0)

没有倒车也可以做到。

以下是代码

public void delNodes(Node n){
   Node curr = n;
   while(curr != null && curr.next != null){
      if(curr.data < curr.next.data){
          Node temp = curr.next;
          curr.data = temp.data;
          curr.next = temp.next;
          temp = null;
      }else{
          curr = curr.next;
      }
   }
}

答案 7 :(得分:0)

万一有人在寻找python实现:

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
class LinkedList:
    def __init__(self):
        self.head = None
    def push(self, new_data):
        new_node = Node(new_data)
        new_node.next = self.head
        self.head = new_node
    def printList(self):
        temp = self.head
        while (temp):
            print(temp.data, end=" ")
            temp = temp.next
        print()


def delete_nodes_with_larger_right(llist):
    current = llist.head
    prev = llist.head
    max = current.data
    while (current is not None):
        if current.data >= max:
            max = current.data
            prev = current
            current = current.next
        else:
            prev.next = current.next
            current.next = None
            current = prev.next
    return

def reverse(llist):
    current = llist.head
    next = None
    prev = None

    while (current is not None):
        next = current.next
        current.next = prev
        prev = current
        current = next
    llist.head = prev

if __name__ == '__main__':
    values_list = [[12, 15, 10, 11, 5, 6, 2, 3], [10, 20, 30, 40, 50, 60], [60, 50, 40, 30, 20, 10]]
    t = len(values_list)
    for index in range(t):
        llist = LinkedList()
        for i in values_list[index]:
            llist.push(i)
        delete_nodes_with_larger_right(llist)
        reverse(llist)
        llist.printList()
        t -= 1

根据您的测试用例更改values_list中的输入。

输入:

12 15 10 11 5 6 2 3
10 20 30 40 50 60
60 50 40 30 20 10

输出:

15 11 6 3
60
60 50 40 30 20 10