删除右侧值较大的节点
给定单链表,删除右侧值较大的所有节点。
示例:
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;
}
}
答案 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)
撤销列表。
遍历反向列表。保持最大化至今。如果下一个节点&lt; max,然后删除下一个节点,否则max = next node。
再次反转列表以保留原始订单。
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 :(得分: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