C 将链接列表拆分为两部分

C 将链接列表拆分为两部分,c,algorithm,linked-list,C,Algorithm,Linked List,给定一个列表,将其拆分为两个子列表-一个用于前半部分,另一个用于后半部分。如果元素的数量是奇数,那么额外的元素应该放在前面的列表中。因此,列表{2,3,5,7,11}上的FrontBackSplit()应该生成两个列表{2,3,5}和{7,11} 代码是这个 void FrontBackSplit(Node *head, Node **front, Node **back) { if (!head) return; // Handle empty list Node *front_la

给定一个列表,将其拆分为两个子列表-一个用于前半部分,另一个用于后半部分。如果元素的数量是奇数,那么额外的元素应该放在前面的列表中。因此,列表
{2,3,5,7,11}
上的
FrontBackSplit()
应该生成两个列表
{2,3,5}
{7,11}

代码是这个

void FrontBackSplit(Node *head, Node **front, Node **back) {
  if (!head) return;  // Handle empty list
  Node *front_last_node;
  Node *slow = head;
  Node *fast = head;
  while (fast) {
    front_last_node = slow;
    slow = slow->next;
    fast = (fast->next) ? fast->next->next : NULL;
  }
  front_last_node->next = NULL;  // ends the front sublist
  *front = head;
  *back = slow;
}

问题是我并没有得到最佳的运行时和有时期望的输出。

一般来说,您的代码对于大小均匀的列表效果良好。考虑4个元素的列表A-->B->C>>D->NULL,并查看算法跟踪。

A    slow, fast, head
B
C
D
NULL

A    front_last_node, head
B    slow
C    fast
D
NULL

A    head
B    front_last_node
C    slow
D
NULL fast
然后删除链接B->C并返回两个列表:A->B和C->D。这正是此函数想要的行为,不是吗?

还有另一种方法

使用循环计算链表中有多少个元素

如果其耦合,则第一个列表位于head(第一个元素的地址)和i=n/2元素之间。第二个列表介于i=0.5n+1元素和最后一个元素之间

否则,第一个列表在头到i=0.5n+1元素之间,第二个列表在i=0.5n+2到最后一个元素之间


为了方便起见,当您运行循环计算元素数时,请使用一个变量来保留最后一个元素和中间一个元素的位置,以便在需要时使用它们。

是否准备好列表长度?如果是,除以2,前进那么多节点,然后分割。有什么问题?调用函数时会发生什么?如何确定“不是最佳运行时”以及输出有什么问题?
(!head)
表示列表为空?正在检查条件。@HenkHolterman。。。如果元素的数量是偶数,那么就不能将它们平均分成两部分。