剑指Offer系列---(7)从尾到头打印链表

来源:互联网 发布:富士国际语学院 知乎 编辑:程序博客网 时间:2024/05/27 20:52

1.题目描述:

输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表结点的定义如下:

struct ListNode{

    int m_nKey;

    ListNode *m_pNext;

};

2.源代码:

A1.用栈实现的“从尾到头打印链表”程序代码如下:

#include <stdio.h>#include <stdlib.h>#include <memory.h>#ifndef ERROR#define ERROR (0)#endif#ifndef OK#define OK   (!ERROR)#endif#define STACK_INIT_SIZE 1#define STACKINCREMENT 10typedef int ElemType;typedef struct Node{    ElemType data;    struct Node *next;}Node,*pNode;typedef int SElemType;typedef struct SqStack{    SElemType  *base;    SElemType  *top;    int  stacksize;}SqStack,*pStack;pStack S;pStack InitStack(pStack S){    S = (pStack)malloc(STACK_INIT_SIZE * sizeof(SElemType));    if (S == NULL) {        return ERROR;    }    S->base = (SElemType *)S;    S->top = S->base;    S->stacksize = STACK_INIT_SIZE;        return S;}pStack Push(pStack S,SElemType e){    if((S->top - S->base) >= S->stacksize){        S->base = (SElemType*)realloc(S, (S->stacksize +STACKINCREMENT)*sizeof(SElemType));        if (S->base == NULL) {            return ERROR;        }        S->top = S->base + S->stacksize;        S->stacksize += STACKINCREMENT;    }    *S->top++ = e;    return S;}SElemType Pop(pStack S){    return *(--S->top);}pNode CreateList(){    ElemType val;    pNode pHead = NULL;    pNode pCur = NULL;        do{        scanf("%d",&val);        if(val != -1){            pNode pNew = (pNode)malloc(sizeof(Node));            if (pNew == NULL)                    exit(EXIT_FAILURE);                pNew->data = val;                pNew->next = NULL;                                if (pHead == NULL) {                    pHead = pNew;                    pCur = pHead;                }else{                    pCur->next = pNew;                    pCur = pCur->next;                }        }    }while (val != -1);    return pHead;}void DestroyList(pNode pHead){    if(pHead == NULL)        return;    pNode p = NULL;    while (pHead != NULL) {        p = pHead->next;        free(pHead);        pHead = p;    }}void PrintListReverse(pNode pHead){    if(pHead == NULL)        return;    while (pHead != NULL) {        Push(S, pHead->data);        pHead = pHead->next;    }    while (S->top != S->base) {        printf("%d\n",Pop(S));    }}int main(int argc, char ** argv){    S = InitStack(S);        pNode pHead = CreateList();    PrintListReverse(pHead);    DestroyList(pHead);    return 0;}

A2.用递归实现的“从尾到头打印链表”程序代码如下:

#include <stdio.h>#include <stdlib.h>typedef int ElemType;typedef struct Node{    ElemType  data;    struct Node *next;}Node,*pNode;void PrintListReverse(pNode pHead){    if(pHead == NULL)        return;    if(pHead->next != NULL)        PrintListReverse(pHead->next);    printf("%d\n",pHead->data);}pNode CreateList(){    ElemType val;    pNode pHead = NULL;    pNode pCur = NULL;        do{        scanf("%d",&val);        if(val != -1){            pNode pNew = (pNode)malloc(sizeof(Node));            if(pNew == NULL)                exit(EXIT_FAILURE);            pNew->data = val;            pNew->next = NULL;                        if(pHead == NULL){                pHead = pNew;                pCur = pHead;            }else{                pCur->next = pNew;                pCur = pCur->next;            }        }    }while (val != -1);    return pHead;}void DestroyList(pNode pHead){    if (pHead == NULL) {        return;    }    pNode p = NULL;    while (pHead != NULL) {        p = pHead->next;        free(pHead);        pHead = p;    }}int main(int argc,char **argv){    pNode pHead = CreateList();    PrintListReverse(pHead);    DestroyList(pHead);    return 0;}

3.小结:

1)对于反向输出时,应该考虑它的特性,选择数据结构类型来实现。一定要搞清楚各种数据结构类型的特点;

2)对于栈能实现的例子,一般要想到也可以用递归来完成。递归的缺点就是递归层级很深时,可能导致函数调用栈溢出;

3)在面试过程中,可以试着问面试官一些关于题目的信息,比如上面的从尾到头打印链表,是否允许对输入的数据做修改。

0 0
原创粉丝点击