Algorithm 在给定块大小时反转单链表
有一个单独连接的链表,并且给出了一个块大小。例如,如果我的链表是Algorithm 在给定块大小时反转单链表,algorithm,linked-list,space-complexity,Algorithm,Linked List,Space Complexity,有一个单独连接的链表,并且给出了一个块大小。例如,如果我的链表是1->2->3->4->5->6->7->8-NULL,并且我的块大小是4,那么将第一个4元素和第二个4元素颠倒过来。问题的输出应该是4->3->2->1->8->7->6->5-NULL 我正在考虑将链表分成大小为4的段,然后将其反转。 但是那样的话,我不得不使用很多额外的节点,这是完全不需要的。 空间复杂度应保持在最低限度 如果有人能提供一个更好的解决方案,将额外节点的使用量保持在最低限度,这将是非常值得赞赏的。您可以提前将当前
1->2->3->4->5->6->7->8-NULL
,并且我的块大小是4
,那么将第一个4
元素和第二个4元素颠倒过来。问题的输出应该是4->3->2->1->8->7->6->5-NULL
我正在考虑将链表分成大小为4
的段,然后将其反转。
但是那样的话,我不得不使用很多额外的节点,这是完全不需要的。
空间复杂度应保持在最低限度
如果有人能提供一个更好的解决方案,将额外节点的使用量保持在最低限度,这将是非常值得赞赏的。您可以提前将当前元素替换为接下来的3次:1234、2134、2314、2341。然后做两次,得到3421。然后一次拿到4321。然后前进4步,对下一个块重复这个过程。我试过这个……似乎很好
node* reverse(node* head) // function to reverse a list
{
node* new_head = NULL;
while(head != NULL)
{
node* next = head->next;
head->next = new_head;
new_head = head;
head = next;
}
return new_head;
}
node* reverse_by_block(node* head, int block)
{
if(head == NULL)
return head;
node* tmp = head;
node* new_head = head;
node* new_tail = NULL;
int count = block;
while(tmp != NULL && count--)
{
new_tail = tmp;
tmp = tmp->next;
}
new_tail->next = NULL;
new_tail = new_head;
new_head = reverse(new_head);
new_tail->next = reverse_by_block(tmp,block);
return new_head;
}
这可以在线性时间内完成,且空间恒定。 以下是简要说明:
int split(node* head, node** listA, node** listB size_t block_size)
{
node* cur = head;
while(block_size && cur)
{
cur = cur->next;
--block_size;
}
if(!cur) { /* error : invalid block size */ return -1; }
*listA = head;
*listB = cur->next;
cur->next = NULL; /* terminate list A */
return 0;
}
cur = *listA;
/* goto last but one element of listA */
while(cur->next) cur = cur->next;
cur->next = *listB;
我必须反转节点,而不仅仅是数据元素。是的。要交换A和B,P是A之前的节点(扫描时跟踪此节点),请执行P.next=B,A.next=B.next,B.next=A。明白了。您的prg正在使用5个额外的节点,需要处理该节点。节点只是指针…重点是没有使用xtra内存。
cur = *listA;
/* goto last but one element of listA */
while(cur->next) cur = cur->next;
cur->next = *listB;