【剑指offer】面试题5:从尾到头打印链表

来源:互联网 发布:数据集中存储的好处 编辑:程序博客网 时间:2024/05/16 09:07


题目:

输入一个链表的头结点,从尾到头反过来打印出每个结点的值

链表结点定义如下:

typedef struct LNode{    int data;    struct LNode *next;}LNode,*LinkList;

题目很简单,可以用从递归遍历二叉树启发,我们可以写一个递归来实现。但这样耗时就太长了。这时应该考虑用数据结构来实现,特别是反向输出,就应该立即想起来用栈来实现该功能。

那么这里就要好好学习《链表》和《栈》两部分的知识。


1:定义结点信息

(1)定义链表结点

//定义链表结点typedef struct LNode{    int data;    struct LNode *next;}LNode,*LinkList;

(2)定义栈的结点

#define STACKINITSIZE 100#define STACKINCREMENT 10//定义栈typedef struct{    int *base;    int *top;    int stacksize;}SqStack;

2:实现链表的基本操作函数

(1)链表的初始化

int list_init(LinkList *L){    (*L) = (LinkList)malloc(sizeof(LNode));    if(!(*L))        exit(-1);    (*L)->next = NULL;    return 1;}

注意:这里的L必须为指针的指针!因为是初始化传递尽量的指针(比如head),这时head是未定义的,如果传入int list_init(LinkLIst L)函数,定义的L只是head的副本,在该函数中对L重新赋值,将不会反馈给head。因此:可用L修改所指向的数据。不能重新赋值(不能传递)!

(2)在链头插入结点

int list_insert_head(LinkList L,int e){    LinkList p = (LinkList)malloc(sizeof(LNode));    if(!p)        exit(-1);    p->data = e;    p->next = L->next;    L->next = p;    return 1;}

3:栈的相关操作

(1)初始化

int stack_init(SqStack *S){    S->base = S->top = (int *)malloc(STACKINITSIZE * sizeof(int));    if(!S->base)        exit(-1);    S->stacksize = STACKINITSIZE;    return 1;}

(2)插入元素

int push(SqStack *S,int e){    if(S->top - S->base >= S->stacksize){        S->base = (int *)realloc(S->base,(STACKINITSIZE+STACKINCREMENT)*sizeof(int));        if(!S->base)            exit(-1);        S->top = S->base + S->stacksize;        S->stacksize += STACKINCREMENT;    }    *(S->top) = e;    S->top++;    return 1;}

(3)删除元素

int pop(SqStack *S,int *e){    if(S->top == S->base)        return 0;    *e = *(--S->top);    return 1;}


4:代码的实现

#include <stdio.h>#include <stdlib.h>//定义链表结点typedef struct LNode{    int data;    struct LNode *next;}LNode,*LinkList;#define STACKINITSIZE 100#define STACKINCREMENT 10//定义栈typedef struct{    int *base;    int *top;    int stacksize;}SqStack;int list_init(LinkList *L);int list_insert_head(LinkList L,int e);int stack_init(SqStack *S);int push(SqStack *S,int e);int pop(SqStack *S,int *e);void print_list(LinkList L);int main(void){    LinkList L,p;    SqStack stack;    int n,e;    list_init(&L);    stack_init(&stack);    printf("please input the numbers of data:");    while(scanf("%d",&n)){        if(n<1){            printf("please input the number more than 0!\n");            continue;        }        printf("please input the data:");        for(int i=0;i<n;i++){            scanf("%d",&e);            list_insert_head(L,e);        }        print_list(L);        p = L->next;        while(p){            push(&stack,p->data);            p = p->next;        }        printf("\nthe reverse are:");        while(pop(&stack,&e)){            printf("%d ",e);        }        printf("\nplease input the data:");    }    return 0;}//链表的相关操作//初始化是传入的一定要是指针的指针形式,因为如果只是传入一个指针,则L为传入的副本,L指向的地方未定义,不能传给实参。只能用于修改数据int list_init(LinkList *L){    (*L) = (LinkList)malloc(sizeof(LNode));    if(!(*L))        exit(-1);    (*L)->next = NULL;    return 1;}int list_insert_head(LinkList L,int e){    LinkList p = (LinkList)malloc(sizeof(LNode));    if(!p)        exit(-1);    p->data = e;    p->next = L->next;    L->next = p;    return 1;}//栈的相关操作int stack_init(SqStack *S){    S->base = S->top = (int *)malloc(STACKINITSIZE * sizeof(int));    if(!S->base)        exit(-1);    S->stacksize = STACKINITSIZE;    return 1;}int push(SqStack *S,int e){    if(S->top - S->base >= S->stacksize){        S->base = (int *)realloc(S->base,(STACKINITSIZE+STACKINCREMENT)*sizeof(int));        if(!S->base)            exit(-1);        S->top = S->base + S->stacksize;        S->stacksize += STACKINCREMENT;    }    *(S->top) = e;    S->top++;    return 1;}int pop(SqStack *S,int *e){    if(S->top == S->base)        return 0;    *e = *(--S->top);    return 1;}void print_list(LinkList L){    LinkList p = L->next;    while(p){        printf("%d ",p->data);        p = p->next;    }}


0 0
原创粉丝点击