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

这篇博客介绍了如何使用栈从尾到头打印链表,提供了三种方法,重点讲解了利用栈的后进先出特性来实现这一功能的代码实现。通过创建栈结构体并实现初始化、入栈、出栈等操作,最终成功地从尾到头遍历并打印链表节点。

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);
        }
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值