剑指Offer--链表-从尾到头打印链表C

数据结构4.4从尾到头打印单链表 分析: **方式1:**单链表反转后再遍历(破坏了单链表的结构) **方式2:**利用栈的数据结构,将各个节点压入栈中,然后利用栈的先进后出的结构实现逆序打印。 使用方式2的方法: 测试: 阅读详情

1.链表

链表是一种动态数据结构。
常见的面试题:单向链表、从尾到头打印链表、删除链表的节点、链表中倒数第K个节点、反转链表、合并两个排序的链表、两个链表的第一个公共节点等

2.从尾到头打印链表

方法1:可以改变链表方向实现
方法2:采用栈的“后进先出”方案
方法3:递归函数(当链表非常长时,就会导致函数调用的层级很深,从而导致函数调用栈溢出
本文采用“方法2”

/* 链表结构体 */
typedef struct _ST_NODE_
{
    void *pDataAddr;      /* 存放的数据 */
    unsigned dataLen;   /* 数据长度 */
    struct _ST_NODE_ *pNextNode;     /* 下一个节点的指针 */
} ST_NODE, *PST_NODE;

/* 栈结构体 */
typedef struct _ST_STACK_
{
    ST_NODE *pHeadNode; /* 头结点 */
    ST_NODE *pTailNode; /* 尾节点 */
    int len; /* 栈的长度 */
    int offset; /* 地址偏移量 */
    int top; /* 栈顶的下标 */
    void *pAddr; /* 存放栈的首地址 */
} ST_STACK, *PST_STACK;

/*************************************************
   Function:		st_initStack
   Description: 初始化栈内容
   Parameter:	pStStack 栈
            size 单个变量需要的内存大小
            len 栈的长度
   Output:		None
   Return:		-1失败 0是成功
*************************************************/
int st_initStack(ST_STACK *pStStack, int size, int len)
{
    if (!pStStack || size <= 0)
    {
        printf("param err size:%d\n", size);
        return -1;
    }

    pStStack->len = len;
    pStStack->offset = size;

    if (pStStack->len <= 0)
    {
        printf("param err pStStack->len:%d\n", pStStack->len);
        return -1;
    }

    pStStack->pAddr = malloc(size * pStStack->len);
    if (!pStStack->pAddr)
    {
        printf("not enough Malloc\n");
        return -1;
    }

    pStStack->top = -1;
    return 0;
}

/*************************************************
   Function:		st_fullStack
   Description: 判断栈是否已满
   Parameter:	pStStack 栈
   Output:		None
   Return:		-1失败 0是成功
*************************************************/
bool st_fullStack(ST_STACK *pStStack)
{
    if (!pStStack)
    {
        printf("param err size\n");
        return -1;
    }

    return pStStack->top + 1 >= pStStack->len;
}

/*************************************************
   Function:		st_emptyStack
   Description: 判断栈是否空闲
   Parameter:	pStStack 栈
   Output:		None
   Return:		-1失败 0是成功
*************************************************/
bool st_emptyStack(ST_STACK *pStStack)
{
    if (!pStStack)
    {
        printf("param err size\n");
        return -1;
    }

    return pStStack->top == -1;
}

/*************************************************
   Function:		st_topStack
   Description: 查找栈顶
   Parameter:	pStStack 栈
   Output:		None
   Return:		-1失败 0是成功
*************************************************/
int st_topStack(ST_STACK *pStStack, void **pDst)
{
    if (!pStStack)
    {
        printf("param err size\n");
        return -1;
    }

    if (st_emptyStack(pStStack))
    {
        printf("1stack empty!!!\n");
        return -1;
    }

    *pDst = pStStack->pAddr + pStStack->top * pStStack->offset;
    printf("param %p, %d,%d, %p\n", pStStack->pAddr, pStStack->top, pStStack->offset, *pDst);
    return 0;
}

/*************************************************
   Function:		st_pushStack
   Description: 变量入栈
   Parameter:	pStStack 栈
        pStValue 单个栈的内容
            size 单个变量需要的内存大小
   Output:		None
   Return:		-1失败 0是成功
*************************************************/
int st_pushStack(ST_STACK *pStStack, void *pStValue, int size)
{
    if (!pStStack || !pStValue || size <= 0)
    {
        printf("param err size:%d\n", size);
        return -1;
    }

    if (pStStack->len <= 0)
    {
        printf("param err pStStack->len:%d\n", pStStack->len);
        return -1;
    }

    if (st_fullStack(pStStack))
    {
        printf("stack full!!!\n");
        return -1;
    }

    pStStack->top++;

    memcpy(pStStack->pAddr + pStStack->top * pStStack->offset, pStValue, size);

    return 0;
}

/*************************************************
   Function:		st_popStack
   Description: 变量出栈
   Parameter:	pStStack 栈
   Output:		None
   Return:		-1失败 0是成功
*************************************************/
int st_popStack(ST_STACK *pStStack)
{
    if (!pStStack)
    {
        printf("param err\n");
        return -1;
    }

    if (st_emptyStack(pStStack))
    {
        printf("stack empty!!!\n");
        return -1;
    }

    pStStack->top--;

    return 0;
}

/*************************************************
   Function:		st_putNodeToStack
   Description: 节点放到栈里
   Parameter:	pNode 节点
            pStStack 堆栈
   Output:		None
   Return:		-1失败 0是成功
*************************************************/
void st_putNodeToStack(ST_NODE *pNode, ST_STACK *pStStack)
{
    int ret = 0;

    if (!pStStack || !pNode)
    {
        return;
    }

    while (pNode != NULL)
    {
        ret = st_pushStack(pStStack, pNode->pDataAddr, pNode->dataLen);
        if (ret != 0)
        {
            printf("st_pushStack err \n");
            return;
        }

        pNode = pNode->pNextNode;
    }

    return;
}

/*************************************************
   Function:		st_pthread_getPriorityScope
   Description: 获取线程最大和最小优先级
   Parameter:	pMaxPriority 最大优先级
            pMinPriority 最小优先级
   Output:		None
   Return:		-1失败 0是成功
*************************************************/
void st_getPrintStack(ST_STACK *pStStack, void **pDst)
{
    if (!pStStack)
    {
        return;
    }

    printf("pStStack->top:%d\n", pStStack->top);
    if (!st_emptyStack(pStStack))
    {
        st_topStack(pStStack, pDst);
        printf("pStStack->pst:%p\n", *pDst);
        st_popStack(pStStack);
    }

    return;
}

int main(int argc, char *argv[])
{
	  ST_NODE *pHead = (ST_NODE *)malloc(sizeof(ST_NODE));
/* pEnd 目的是采用尾插法而不是头插法 */
    ST_NODE *pEnd = NULL;
    pHead->pNextNode = NULL;
    int i = 0;
    int lenNode = 7;
    ST_STACK stStack;
    void *pDst = NULL;
    ST_TEST_NODE_INFO *pTestNodeDst = NULL;
    pEnd = pHead;


    memset(&stStack, 0, sizeof(stStack));

    for (i = 0; i < lenNode; i++)
    {
        ST_TEST_NODE_INFO *pTestNodeInfo = NULL;
        pTestNodeInfo = (ST_TEST_NODE_INFO *)malloc(sizeof(ST_TEST_NODE_INFO));
        pTestNodeInfo->val = i + 1;
        ST_NODE *pS = (ST_NODE *)malloc(sizeof(ST_NODE));
        pS->dataLen = sizeof(ST_TEST_NODE_INFO);
        pS->pDataAddr = pTestNodeInfo;
        pEnd->pNextNode = pS;
        pEnd = pS;
    }

    pEnd->pNextNode = NULL;
    /* 初始化栈 */
    st_initStack(&stStack, sizeof(ST_NODE), 20);
    printf("len:%d, offset:%d\n", stStack.len, stStack.offset);
    /* 将节点放到栈空间 */
    st_putNodeToStack(pHead->pNextNode, &stStack);
    printf("len:%d, offset:%d, top:%d\n", stStack.len, stStack.offset, stStack.top);
    while (!st_emptyStack(&stStack))
    {
        st_getPrintStack(&stStack, &pDst);
        printf("pDst:%p\n", pDst);
        if (pDst)
        {
            pTestNodeDst = (ST_TEST_NODE_INFO *)pDst;
            printf("val:%d\n", pTestNodeDst->val);
        }
    }
}

大模型训练显存瘦身全记录:从ZeRO-3参数分区到CPU Offload的硬件协奏曲 本文详细解析了如何通过ZeRO-3参数分区与CPU/NVMe卸载技术优化大模型训练的显存使用。结合bf16混合精度与梯度累积等策略,实现在消费级GPU上高效训练百亿参数模型,显著提升硬件利用率与训练效率。 阅读详情

相关推荐

莆田市C++专项选拔第一轮题4

现在小明同学想要从两堆硬币中各选择一枚硬币,使得两枚硬币的面值之和 不超过 k。不同的硬币组合,就算面值相同,也视为不同的方案。现在他把这些硬币分成了两堆,已知两堆硬币分别有 n 和 m 枚硬币。可选方案有: (1,2), (1,1), (1,1), (5,2), (5,1), (5,1),共 6 种。第一行三个整数 n, m, k,分别表示第一堆硬币的数量,第二堆硬币的数量,以及面值之和的上限。对于30%的数据,1 ≤ n , m ≤ 1000 , 1 ≤ b , c ≤ 1000。

lpstudio的博客 925

C语言:从尾到头打印链表

双12买了本《剑指offer》,里面好多题目之前都做过,但仅限于做出来,当时没有思考太多,很多都是直接调类(用的java)。今天开始重新学习,想着用C再实现一遍,这次要考虑更深层的东西,比如时间复杂度这些。 言归正传,再次学习还是从链表开始,第一道关于链表的题目是从尾到头打印链表。看到这道题,我第一反应想的是:把链表反转,然后再依次输出每个结点的值就好了,正好还有一道链表反转的题,一次能完成两个呢...

weixin_43936250的博客 1631

Sonatype nexus3 数据迁移及升级3.71+(迁移到H2数据库)

nexus3旧版本OrientDB升级H2,及整体迁移nexus3数据到其它服务器。

葫芦娃 5550

02.从尾到头打印链表

从头到尾打印链表 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回) //输入 head = [1,3,2] //输出 [2,3,1] //限制: 0 <= 链表长度 <= 10000 递归法 代码的关键部分是recur递归函数 假设输入的链表存储着【1,3,2】这样的一组数据 第一次调用recur函数时(head值为1):head!=null继续走, 第二调用recur函数(head值为3),不过传入的参数是head.next, 接着第三次调用recur函数(head值为2)

m0_51258512的博客 1267

Win10/Win11系统下冒险岛V128单机版一键搭建教程(含MySQL配置避坑指南)

本文提供Win10/Win11系统下冒险岛V128单机版一键搭建的详细教程,涵盖服务端部署、MySQL配置优化及常见问题解决方案。通过本指南,玩家可轻松实现单机版冒险岛的一键启动,重温经典游戏体验,同时避免常见的技术陷阱。

weixin_29261711的博客 649

从 SEGW 到 SADL 的那根线,彻底理解 OData Data Source Mapping

本文摘要(150字): 在SAP Gateway的SADL型OData服务开发中,"Map to Data Source"是关键配置环节。与传统RFC映射不同,SADL映射不是针对单个CRUDQ操作,而是建立OData模型与SADL业务实体间的完整语义对应关系。通过属性映射和关联映射,系统能自动处理数据获取和导航请求。映射编辑器支持三种模式:属性映射处理字段对应,关联映射处理模型间关系,动作映射处理业务操作。映射的本质是建立语义翻译表,决定了后续OData请求如何转化为后端业务实体访问,而非简单的字段重命名

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 61

17. 从尾到头打印链表(遍历链表)(DAY 30)

文章目录原题题目代码实现 原题题目 遍历链表和遍历一个数组差不多,只不过语法上有些差距 遍历链表: for(auto p=head;p;p=p->next) p.push_back(p->val); p=链表的头,p不为0时,压栈,也就是push_back(p->val) 把p的值压入,存入链表中。 p=p->next p等于p的next。 代码实现 /** * Definition for singly-linked list. * struct ListNode { *

学恒的博客 1299

MATLAB - 使用 RRT 进行挖掘机运动规划

本例演示了如何使用运动规划器在包含障碍物的环境中为挖掘机规划路径。在此示例中,您将以运动树的简化形式为挖掘机建模,然后使用基于采样的运动规划器确定挖掘机在存在障碍物的两个姿势之间的可行路径。在 Simscape™ 多体™ 模型中模拟结果。

机器人控制与仿真应用 1850

LeetCode:剑指 Offer 06. 从尾到头打印链表(C语言)

题目描述: 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10000 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 解答: /** * Definition for

C/C++攻城狮 427

相似贴子推荐:基于 LangChain4j + Milvus 的混合检索实战

本文提出了一种基于LangChain4j和Milvus的混合检索方案,用于解决论坛社区中的相似帖子推荐问题。该方案结合稠密向量语义检索和BM25关键词检索的优势,通过RRF算法实现结果融合。系统采用bge-small-zh模型生成语义向量,利用Milvus 2.5+原生支持的BM25功能和混合搜索API,在百万级数据规模下实现50ms内的检索延迟,召回率和精确率分别提升15%和22%。文章详细介绍了从数据预处理、向量化到混合检索的完整实现流程,并探讨了进阶优化方向,为推荐系统和RAG应用提供了高效解决方案。

分享AI、区块链技术及应用,未来已来 88

由于找不到mfc110u.dll,无法继续执行代码,重新安装程序可能会解决此问题的 解决方案

本文主要介绍了由于找不到mfc110.dll,无法继续执行代码的解决方案,希望能对使用Windows的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 5万+

剑指offer系列——剑指 Offer 06. 从尾到头打印链表(C语言)

⭐️前面的话⭐️ 大家好!博主开辟了一个新的专栏——剑指offer,我要开始刷题了!这个专栏会介绍《剑指offer》书上所有的面试编程题。并且会分享一些我的刷题心得。由于博主水平有限,如有错误,欢迎指正,如果有更好的解题思路和算法可以分享给博主哦!一起加油!一起努力! 剑指 Offer 06. 从尾到头打印链表(C语言)

未见花闻的博客 1094

WRFDA如何读取风云四号A 星的GIIRS数据?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值。

**My Coding Family** 1027

C语言实现《剑指offer》——05从尾到头打印链表

本篇是第5题_从尾到头打印链表的C语言实现: 题目描述:输入一个链表,从尾到头打印链表每个节点的值。 解法1:链表倒序的数组实现 #include<stdio.h> #include<stdlib.h> #define N 1000 typedef struct node // 复习typedef的基础知识!!!!!!! { int data; struct ...

小灏灏同学的博客 608

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C练题笔记之:Leetcoded-剑指 Offer 06. 从尾到头打印链表

题目: 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10000 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 结果: 思路: 1,因..

lingjinyue的博客 169

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【leetcode C语言实现】剑指 Offer 06. 从尾到头打印链表

题目描述 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10000 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof 解题思路 由于遍历链表只能从头到尾,先遍历的后打印,这是典型的“先进后出”,即栈结构。 此处采用数组存储依次遍历到的数据,

sunshine_hanxx的博客 683

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

剑指 Offer 06. 从尾到头打印链表 C语言

文章目录题目一、思路二、代码1.引入库2.具体代码总结 题目 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 输入:head = [1,3,2] 输出:[2,3,1] 一、思路 本题若不加其他限制条件,可以说非常简单,遍历链表并存到数组,最后逆序数组,然后输出。 二、代码 1.引入库 #include <stdio.h> #include <malloc.h> #include <cstring> 处理数组很标准的三个库 stdio.h是标准库

weixin_43391489的博客 830

剑指offer(C++)--从尾到头打印链表

题目 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。 /** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : * val(x), next(NULL) { * } * }; */ class...

Courage-Hu的专栏 291

剑指 Offer 06. 从尾到头打印链表 C解

剑指 Offer 06. 从尾到头打印链表 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 思路 首先逆序给定链表。并记录链表节点个数。‘ 通过节点个数确定数组大小。 遍历逆序后链表,同时将值copy到数组。 代码示例: typedef struct ListNode Node; int* reversePrint(struct ListNode* head, int* returnSize){

juggte的博客 126

C/C++ 《剑指offer》——(3)从尾到头打印链表

问题描述: 输入一个链表,按链表值从尾到头的顺序打印结点值。 解题思路及知识点 由题意选择三种思路: 采用循环方法从尾到头打印单链表 采用递归方法从尾到头打印单链表 借助栈的特性从尾到头打印单链表 链接方式存储的线性表简称为链表(Linked List),data域--存放结点值的数据域,next域--存放结点的直接后继的地址(位置)的指针域(链域),链表通过每个结点的链域将线性表的n...

yuanzhaoup 321

LeetCode剑指offer 06 从尾到头打印链表(c++)

针对剑指offer06从尾到头打印链表题目给出了三种解法,包括一种借助额外空间(数组)的解法,和一种原地的解法(原地扩充字符串空间)。

xcinkey的博客 204

(C++)剑指offer-3:从尾到头打印链表

剑指offer-3:从尾到头打印链表 目录 剑指offer-3:从尾到头打印链表 目录 1问题描述 2问题解析 3链表学习 3.1数组和链表 3.2链表的简单使用 3.3链表的进阶使用 3.4链表的高阶使用 3.5链表其他操作 4题目答案 4.1利用递归实现 4.2用库函数实现 1问题描述 输入一个链表,从尾到头打印链表每个节点的值。 2问题解析 ...

malele4th 2933

【剑指Offer】从尾到头打印链表(C/C++描述)

题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。 /** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : * val(x), next(NULL) { * } * }; */ clas...

誓约胜利之舰 300

剑指offer(c++)-04.从尾到头打印链表

链表 1. 前景知识: 链表应该是面试时被提及最频繁的数据结构。链表的结构很简单,它由指针把若干个结点连接成链状结构。链表的创建、插入结点、删除结点等操作都只需要20行左右的代码就能实现,其代码量比较适合面试。 链表是一种动态数据结构,是因为在创建链表时,无须知道链表的长度。当插入一个结点时,只需要为新结点分配内存,然后调整指针的指向来确保新结点被链接到链表当中。内存分配不是在创建链表时一次性完成,而是每添加一个结点分配一次内存。由于没有闲置的内存,链表的空间效率比数组高。 由于链表中的内存不是一

Liongz的博客 159

从尾到头打印链表(剑指offer)---C语言

剑指 Offer 06. 从尾到头打印链表 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ /** * Note: The returned array must be mal

gdarg的博客 234

[C语言][剑指offer篇]--从尾到头打印链表

题目描述 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/ 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 理清思路 方法一 尾填数组法  尾填数组法是指正向遍历链表,将节点数据从数组的尾部开始填入。 第一次遍历链表,计算出链表的长度size malloc分配size大小的内存

静待另一片蓝天 718
上一篇: 剑指offer---基础知识:数组
下一篇: C语言之volatile、static、const、extern
ldxFashion
博客等级 码龄6年 0粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值