数据结构(一)---对递归的思考

一、递归

      递归自己调用自己,调用过程是一个碗状结构。但是需要确保在碗底能得到基准情形(数据)。有点类似多线程中嵌入多线程在解决斐波那契时的sync。其本质特征是一个大问题可以分解成更小的问题,小问题解法和大问题一样。

      每次调用函数都要有三个操作前先保存寄存器,并在返回时恢复;复制实参;旧值不能释放,程序必须转向一个新位置执行。这种每次去代码区调用函数,然后栈区计算且不能释放,会带来大量计算,而且栈区比较小,不能嵌套太多层。内联函数不能递归,编译器会忽略甚至报错。

二、递归的非递归解法

  (1)“尾递归” 

    从碗底开始,往上迭代。

   (2)非递归

    编译器无法自动优化一般的递归函数,不过通过模拟递归函数的过程,我们可以借助于栈将任何递归函数转换为迭代函数。直观点,递归的过程其实是编译器帮我们处理了压栈和出栈的操作,转换为迭代函数就需要手动地处理压栈和出栈。

   下面我们以经典的快速排序为例子。  

int partition(int *array, int low, int high) {
    int val = array[low];
    while(low < high) {
      while(low<high && array[high]>=val)

      --high;

     swap(&array[low], &array[high]);
     while(low<high && array[low]<=val)

      ++low;

     swap(&array[low], &array[high]);
   }
   return low;
 }
  void Quicksort(int *array, int b, int e) {
    if (b >= e) return;
   int p = partition(array, b, e);
    Quicksort(array, b, p-1);
    Quicksort(array, p+1, e);
 }

 其实不难看出快速排序的递归算法就是一个二叉树的先序遍历过程,先处理当前根节点,然后依次处理左子树和右子树。将快速排序递归算法转换为非递归相当于将二叉树先序遍历递归算法转为非递归算法。

因为无需保留上一节信息,只需返回边界。所以递归调用是可以接受的。但是,也可以利用堆栈,进行非递归实现 。代码不好懂,递归实现就可以! 

http://blog.jobbole.com/109124/ 

 

posted @ 2018-06-02 10:25  秋雨声  阅读(188)  评论(0编辑  收藏  举报