a,编与一个非递归过程以 O(N)时间反转单链表。 b,使用常数附加空间编写一个过程以((N)时间反转单链长 用c语言写两段代码
时间: 2024-09-27 19:09:11 浏览: 31
LinkList单文件_一个简单单链表_
a. 编写一个非递归的O(n)时间复杂度反转单链表的过程,我们需要借助三个指针,一个指向当前节点,一个向前移动一个位置(即前驱),另一个则保存前驱节点的下一个节点,然后逐步完成链表节点的交换。以下是这个过程的大致思路:
```c
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode *prev = NULL, *curr = head;
while (curr != NULL) {
struct ListNode *temp = curr->next; // 保存当前节点的下一个节点
curr->next = prev; // 将当前节点指向前一个节点
prev = curr; // 移动前驱到当前节点
curr = temp; // 移动当前到下一个节点
}
return prev; // 返回新的头节点(原尾部)
}
```
在这个过程中,每个节点都被处理一次,所以时间复杂度是线性的O(n)。
b. 使用常数附加空间(即O(1)空间复杂度),我们可以利用原地翻转的方式来达到这个目标,但这种方法稍微复杂一些,需要巧妙地操作指针。下面是一个C语言的例子:
```c
struct ListNode* reverseListInPlace(struct ListNode* head) {
struct ListNode *prev = NULL, *current = head;
while (current != NULL) {
struct ListNode *nextTemp = current->next; // 临时保存当前节点的下一个节点
current->next = prev; // 将当前节点的next指向前一个
prev = current; // 更新前驱指针
current = nextTemp; // 跳过已经反转的部分,继续处理下一位
}
// 如果链表只有一个节点,或者原头节点变成了最后一个节点
if (!prev) return head;
else head = prev; // 新的头节点就是原尾节点
return head;
}
```
这段代码同样实现了单链表的反转,但由于需要原地操作,可能会让代码看起来比非递归版本更复杂。
阅读全文