【问题标题】:Splitting Linklist in two parts将链表拆分为两部分
【发布时间】:2013-07-22 07:40:51
【问题描述】:

给定一个列表,将其分成两个子列表——一个用于前半部分,一个用于后半部分。如果元素的数量是奇数,则额外的元素应该放在前面的列表中。所以FrontBackSplit() 列表上的{2, 3, 5, 7, 11} 应该产生两个列表{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;
}

问题是我没有得到最好的运行时间,有时也没有得到预期的输出。

【问题讨论】:

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

标签: c algorithm linked-list


【解决方案1】:

通常,您的代码适用于偶数大小的列表。考虑 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。这正是这个函数想要的行为,不是吗?

【讨论】:

    【解决方案2】:

    还有另一种方式;

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

    如果它的一对 - 第一个列表在头(第一个元素的地址)到 i=n/2 元素之间。第二个列表介于 i=0.5n+1 个元素到最后一个元素之间。

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

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

    【讨论】:

      猜你喜欢
      • 2018-01-06
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多