C++实例(2)

                          C++实例(2)

1.下面是一个简单的程序,向你展示一个很小的函数要递归调用多少次才会耗光栈空间。(函数的栈帧越大,能进行的递归调用次数就越少)

#include<iostream>
using namespace std;
void recures(int count)  //每次调用的count都不一样
{
    cout<<count<<endl;
    //这里没有必要写一条语句来专门递增count
    //因为每个函数的变量是独立的
    //(因此每个栈帧中的count将被初始化为上一个函数的count加1)
    recures(count+1);
}
int main()
{
    recures(1);//第一次函数调用,因此置为1
}

2.我们使用两个函数来计算阶乘:一个用于计算偶数的,一个计算奇数的。

int factorial_odd(int x)
{
    if(x==0)
    {
        return 1;
    }
    return factorial_even(x-1);
}
int factorial_even(int n)
{
    if(x==0)
    {
        return 1;
    }
    return factorial_odd(x-1);
}
int factorial(int x)
{
    if(x%2==0)
    {
        return factorial_even(x);
    }
    else
    {
        return factorial_odd(x);
    }
}

3.下面是一些何时使用递归或循环的经验法则:

1).适合用递归的情况:
(1)问题的解决需要将问题分解成相同问题的较小版本,且存在一个明显能用循环来实现的方案;
(2)你正在处理的数据结构递归的。(如链表)
2)。适合用循环的情况:
(1)很明显能用一个简单的循环来解决问题(例如,要将一串数字相加,你当然可以写一个递归函数,但这不值得);
(2)正在处理的数据结构使用数字进行索引时,如数组

4.在树中插入新节点

(1) 函数接收一个key值和一棵已存在的树(可能为空),返回包含此插入值的新树。

node* insert(node *p_tree,int key)
{
   //基线条件:我们到达了一棵空树,需要将新节点插入到这里
   if(p_tree==NULL)
   {
      node* p_new_tree=new node;
      p_new_tree->p_left=NULL;
      p_new_tree->p_right=NULL;
      p_new_tree->key_value=key;
      return p_new_tree;
   }
   //决定将新节点插入到左子树或右子树中
   //取决于新节点的值
   if(key<p_tree->key_value)
   {
    //根据p_tree->left和新增的key值,构建一棵新树,
    //然后用一个指向新树的指针来替换现有的p_tree->left
    //之所以需要替换现有的p_tree->left,是为了防止
    //原有的p_tree->left为NULL的情况(如果不为NULL,
    //p_tree->p_left实际上不会改变,但替换下也无妨)
    p_tree->p_left=insert(p_tree->p_left,key);
   }
   else
   {
   //插入到右子树的情况与插入到左子树是对称的
   p_tree->p_right=insert(p_tree->p_right,key);
  }
  return p_tree;
}

此算法的基本逻辑是:如果当前拥有的是一棵空树,那就创建一棵新的树。若非空树,那么如果要插入的值大于当前节点,就将其插入左子树中,并用新创建的子树替换原来的左子树;否则就将新节点插入右子树中,并做同样的替换。

5.在树中搜索

node *search(node *p_tree,int key)
{
   //如果到达了空树,很明显,值key不在这棵树中!
   if(p_tree==NULL)
   {
     return NULL;
   }
   //如果找到了值key,搜索完成!
   else if(key==p_tree->key_value)
   {
    return p_tree;
   }
   //否则,尝试在左子树或右子树中寻找
   else if(key<p_tree->key_value)
   {
    return search(p_tree->p_left,key);
   }
   else
   {
    return search(p_tree->p_right,key);
   }
}

上面的search函数首先检查两个基线条件:是否到达树的分支末端或是否找到了值key。无论哪种情况,我们都知道应该返回什么:如果到达树的分支末端,就返回NULL;如果找到了key值,就返回这棵树本身

6.删除树

destroy_tree函数也应该是递归的。该算法将删除当前节点的两个子树,然后再删除当前节点。

 void destroy_tree(node *p_tree)
 {
 if(p_tree!=NULL)
  {
    destroy_tree(p_tree->p_left);
    destroy_tree(p_tree->p_right);
    cout<<"Deleting node: "<<p_tree->key_value;
    delete p_tree;
  }
 }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值