编程题:
设有一带头结点的单链表,编程将链表颠倒过来。要求不用另外的数 组或结点完成。
分析:
该算法通过维护三个指针(prev、curr 和 next)逐步遍历单链表,实现链表的逆转。在遍历过程中,curr 的 next 指针被更新为指向 prev,逐步反转指向。最终,头结点的 next 指针指向新的头节点(即原链表的尾节点),从而完成链表的逆转。这一过程只需 (O(n)) 的时间复杂度和 (O(1)) 的空间复杂度。
#include <stdio.h>
#if 0
typedef int ElemType;
typedef struct Lnode {
ElemType data; // 数据域
struct Lnode* next; // 指针域
} Lnode, * LinkList;
// 创建带头结点的单链表
LinkList createList() {
LinkList head = (LinkList)malloc(sizeof(Lnode));
head->next = NULL;
// 这里可以添加其他节点以构造链表
return head;
}
// 逆转带头结点的单链表
void reverseList(LinkList head) {
Lnode* prev = NULL;
Lnode* curr = head->next; // 从头结点的下一个开始
Lnode* next;
while (curr) {
next = curr->next; // 保存下一个节点
curr->next = prev; // 反转当前节点的指针
prev = curr; // 移动 prev 指针
curr = next; // 移动 curr 指针
}
head->next = prev; // 头结点的 next 指向新的头结点
}
// 打印链表
void printList(LinkList head) {
Lnode* temp = head->next; // 从头结点的下一个开始
while (temp) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
int main() {
LinkList list = createList();
// 添加十个节点到链表
for (int i = 1; i <= 10; i++) {
Lnode* newNode = (Lnode*)malloc(sizeof(Lnode));
newNode->data = i;
newNode->next = NULL;
Lnode* temp = list; // 找到链表的最后一个节点
while (temp->next) {
temp = temp->next;
}
temp->next = newNode; // 将新节点添加到链表末尾
}
printf("Original List:\n");
printList(list);
reverseList(list);
printf("Reversed List:\n");
printList(list);
// 释放链表的内存
Lnode* temp;
while (list->next) {
temp = list->next;
list->next = temp->next;
free(temp);
}
free(list);
return 0;
}
#endif
考试写:
// 逆转带头结点的单链表
void reverseList(LinkList head) {
Lnode* prev = NULL;
Lnode* curr = head->next; // 从头结点的下一个开始
Lnode* next;
while (curr) {
next = curr->next; // 保存下一个节点
curr->next = prev; // 反转当前节点的指针
prev = curr; // 移动 prev 指针
curr = next; // 移动 curr 指针
}
head->next = prev; // 头结点的 next 指向新的头结点
}
解法不唯一,欢迎评论区交流。