关于递归的性能问题

来源:6-5 二分搜索树的查询操作

慕斯卡1555144

2019-02-25

听了波波老师的课爱上递归了!使用起来有种四两拨千斤的快感。但是个问题请教,与普通的循环遍历比,它的性能是否更好呢?
贴一下自己用PHP写的二叉树,学习这门课的PHPer一起加油吧!

<?php
class Node{
	public $value,$left,$right;
	public function __construct($value,Node $left = null,Node $right = null){
		$this->value = $value;
		$this->left = $left;
		$this->right = $right;
	}
}
class BST{
	private $root,$size;
    public function	__construct(){
    	$this->root = null;
    	$this->size = 0;
	}
	public function add($e){
		$this->root = $this->_add($this->root,$e);
	}
	private function _add($root,$e){
		if($root == null){
			$this->size++;
			return new Node($e);
		}
		if($e > $root->value )
			$root->right = $this->_add($root->right,$e);
		else if($e < $root->value)
			$root->left = $this->_add($root->left,$e);
		return $root;
	}
	public function contains($value){
		if($this->root->value == $value)
			return $this->root;
		else if ($this->root->value > $value)
			return $this->_contains($value,$this->root->right);
		else if ($this->root->value < $value)
			return $this->_contains($value,$this->root->left);
	}
	private function _contains($value,$root){
		if($root == null)
			return false;
		if($root->value == $value)
			return true;
		else if ($root->value > $value)
			return $this->_contains($value,$root->right);
		else if($root->value < $value)
			return $this->_contains($value,$root->left);
	}
}
$bst = new BST();
$bst->add(21);
$bst->add(23);
$bst->add(56);
$bst->add(24);
$bst->add(45);
var_dump($bst->contains(23));
var_dump($bst->contains(34));
写回答

1回答

liuyubobobo

2019-02-26

赞!感谢分享:)


如果你的递归实现是正确的话,并且保证递归算法确实是等价的非递归算法的话,那么:

1)从时间复杂度分析的角度,递归算法和非递归算法是一样的。也就是拥有同样的复杂度级别;

2)从空间复杂度分下的角度,对于有些算法,递归算法的空间占用会比非递归高。只是有些,比如对于大多数链表相关的递归算法,空间复杂度会是O(n)的,但非递归复杂度会是O(1)的。这是由于递归过程占用了系统栈;

3)从实际性能的角度,递归算法会比非递归算法慢一点点,只是一点点,在大多数业务环境根本不会影响(可能在一些嵌入式环境中会有所影响,但随着现在嵌入式的发展,这种影响也在降低)。这是因为他们是具备相同的渐进时间复杂度的。慢的这一点点,是因为递归过程中需要不断地进行函数调用(包括传参),所进行的时间开销:)


不过,递归真正的意义在于:从一个更高层面,清晰的展示逻辑。对于很多算法,使用递归的方法书写逻辑,是极其极其简单的,相应的非递归算法,会是极其极其复杂的。在这里,我举几个例子:

1)快速排序;

2)二分搜索树的前中后续遍历;

3)汉诺塔问题


不列举更多了,更多的问题会越来越不够“大众”,上面几个例子已经足够了。仔细思考一下,这些例子都是可以非常简单的写出相应的递归算法,但是要想写出非递归算法,是极其困难,或者复杂繁琐的:)


加油!:)

2
1
慕斯卡1555144
明白了,老师回答得很详细,感谢!
2019-02-26
共1条回复

玩转数据结构

动态数组/栈/队列/链表/BST/堆/线段树/Trie/并查集/AVL/红黑树…

6221 学习 · 1704 问题

查看课程