学习数据结构(三)——栈

1.栈

栈是一个线性表,如下图,其特点是后进先出。对栈来说,表尾部是栈顶,表头是栈底,不含元素的栈叫空栈。栈的基本操作除了出栈、入栈,还有初始化栈,空栈判断、取栈顶元素等。

 

(1)顺序栈

利用顺序方式存储的栈为顺序栈,栈许多操作在栈顶实现,因此需要设置一个栈顶指示器标注栈顶位置。栈的应该包括连续空间首地址、顺序栈的最大空间和栈中元素的个数。

(1)进栈操作:在栈未满的情况下,允许元素进栈,栈顶指示器往上移一个空间,然后将一个新元素放进栈中。(2)出栈操作:将栈顶指示器所指的值保存在一个变量中,再将栈顶指示器向下移动。(3)取栈:将栈顶指示器所指值保存至一个变量中

(2)共享栈

为了防止顺序栈溢出,通常需要给栈分配较大空间,但如果栈中没有几个元素,又会造成空间浪费。当需要使用同类型栈时,为了充分利用各个栈的空间,采用多个栈共享存储。

假设共享栈中的两个栈共享一个连续的存储空间,栈底设在大栈的两端,往中间入栈。

(1)入栈操作:两个栈均从两顿往中间入栈,直到栈满。

(3)链栈

是指用链式存储结构实现的栈。与单向链表相似,但没有头结点。

2.递归

递归在程序中执行效率极低。

对于递归问题,可以转换为非递归解决。

(1)直接转换法

该方法常用来消除尾递归和单向递归,用循环或迭代代替递归!

例如下面的求阶乘的代码:

#include <iostream>
#include <Windows.h>

long factorial1(int n)
{
	int temp = n;
	if (n == 0)
	{
		temp = 1;
		return temp;
	}

	else
	{
		temp = temp * factorial1(temp-1);
		return temp;
	}
}

long factorial2(int n)
{
	int temp = n;
	int ans = n;
	for (int i = 1; i <n; i++)
	{
		temp--;
		ans = ans * temp;
	}

	return ans;
}

void main()
{
	int n;
	long ans1,ans2;
	std::cin >> n;
	std::cout << std::endl;

	DWORD start_time1 = GetTickCount();
	for (int i = 0; i < 80000; i++)
	{
		ans1 = factorial1(n);
	}
	DWORD end_time1 = GetTickCount();
	DWORD start_time2 = GetTickCount();
	for (int i = 0; i < 80000; i++)
	{
		ans2 = factorial2(n);
	}
	DWORD end_time2 = GetTickCount();
	std::cout << ans1 <<" "<< (end_time1 - start_time1) <<"ms"<< std::endl;
	std::cout << ans2 << " " << (end_time2 - start_time2)  << "ms" << std::endl;
}

其输出如下图:

 

明显可以看出尾递归的速度明显慢于循环……

(2)间接转化法

利用栈保存中间结果,根据递归函数在栈中的变化结果得到答案。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值