剑指offer-6:逆序打印链表

这道题的题目可以描述为:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。

本文中,对于链表结点的定义及接口定义如下:

typedef   int DataType;

typedef struct ListNode{
	DataType data;
	struct  ListNode *next;
} ListNode

//初始化
void  ListInit(ListNode **ppfirst)
{
	assert(ppfirst != NULL);
	*ppfirst = NULL;
}

本文中将采用非递归,递归和用栈实现三种方式实现:

1.普通非递归

思路可以理解为:从头到尾遍历整个链表,找到最后一个结点,做打印,然后接着从头遍历,找到倒数第二个结点再做打印,直到打印完头结点为止。

代码如下:

void PrintReverse(ListNode *first)
{
	ListNode *end = NULL;//要打印的后一个结点
	while (end != first)
	{
		//每次从第一个结点往前找
		ListNode *cur = first;
		//找到要打印的结点
		while (cur->next != end)
		{
			cur = cur->next;
		}
		//要打印的节点
		printf("%d", cur->data);
		end = cur;
	}
}

2.递归算法

思路可以理解为:要实现反过来输出链表,我们访问到一个结点的时候,先递归输出它后面的结点,再输出自身,最后的输出结果就反过来了。

代码如下:

void PrintReserveRecursion(ListNode *first)
{
	if (first->next == NULL)
	{
		printf("%d", first->data);
	}
	else
	{
		PrintReserveRecursion(first->next);
		//链表中,除了first外的所有结点都已经逆序打印
		printf("%d", first->data);
	}
}

3.用栈实现

思路可以理解为:将链表从头到尾依次压入栈中,然后依次从栈中弹出栈首元素做打印,直到栈空,最后打印的结果就是链表的逆序打印结果。

有关栈结构体的定义以及相关接口定义如下:

typedef   int  DataType;

#define MAXSIZE (100)

typedef   struct{
	DataType  array[MAXSIZE];
	int top;//起了个别名,含义还是size
}Stack;

void   StackInit(Stack *ps)
{
	ps->top = 0;
}

void   StackDestory(Stack *ps)
{
	ps->top = 0;
}

//栈中入放一个元素
void   StackPush(Stack *ps,DataType data)
{
	assert(ps->top < MAXSIZE);
	ps->array[ps->top++] = data;

}
//栈中弹出一个元素
void   StackPop(Stack *ps)
{
	assert(ps->top>0);
	ps->top--;

}

//弹出栈顶元素
DataType   StackTop(const  Stack *ps)
{
	assert(ps->top > 0);
	return ps->array[ps->top - 1];
}

//返回栈的大小
int  StackSize(const Stack *ps)
{
	return  ps->top;
}
//返回栈是否为空
int StackEmpty(const Stack *ps)
{
	return ps->top == 0 ? 1 : 0;
}

栈的算法实现代码如下:

void PrintReverseStack(ListNode *first)
{
	Stack stack;
	StackInit(&stack);
	ListNode *phead = first;
	while (phead != NULL)
	{
		StackPush(&stack, phead->data);
		phead = phead->next;
	}
	while (!StackEmpty(&stack))
	{
		DataType t = 0;
		t= StackTop(&stack);
		printf("%d",t);
		StackPop(&stack);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值