【数据结构】设有一带头结点的单链表,编程将链表颠倒过来。要求不用另外的数 组或结点完成。

编程题:

设有一带头结点的单链表,编程将链表颠倒过来。要求不用另外的数 组或结点完成。

分析:

该算法通过维护三个指针(prev、curr 和 next)逐步遍历单链表,实现链表的逆转。在遍历过程中,curr 的 next 指针被更新为指向 prev,逐步反转指向。最终,头结点的 next 指针指向新的头节点(即原链表的尾节点),从而完成链表的逆转。这一过程只需 (O(n)) 的时间复杂度和 (O(1)) 的空间复杂度。

cpp 复制代码
#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

考试写:

cpp 复制代码
// 逆转带头结点的单链表
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 指向新的头结点
}

解法不唯一,欢迎评论区交流。

相关推荐
云淡风轻~窗明几净7 小时前
角谷猜想的任意算法测试
数据结构·人工智能·算法
代码中介商7 小时前
关键路径解析:项目管理的工期奥秘
数据结构
love_muming7 小时前
链表每日一练
java·开发语言·数据结构·链表·idea·每日一练
玖玥拾8 小时前
C/C++ 数据结构(二)双向链表
c语言·数据结构·c++
乐观勇敢坚强的老彭8 小时前
GESP一级核心算法:循环与条件判断的结合
java·数据结构·算法
noipp8 小时前
推荐题目:洛谷 P1737 [NOI2016] 旷野大计算
linux·数据结构·算法
lzjava20248 小时前
Python的数据结构,推导式、迭代器和生成器
数据结构·windows·python
怪兽学LLM9 小时前
LeetCode 21 合并两个有序链表:彻底理解虚拟头节点(Dummy)套路
python·leetcode·链表
rit843249910 小时前
MATLAB近红外光谱预处理:平滑与求导(MSV方法)
数据结构·算法·matlab
触底反弹10 小时前
从 JS 引擎执行原理理解数据类型:栈内存、堆内存与作用域
javascript·数据结构·面试