18从汇编的角度深入理解c++_深入理解二叉树前置(递归和快速排序算法)

递归的本质就是:

  自己调用自己(关键是如何自己调用自己)。

求:1,2,3,……100的和,我们知道结果是5050.

正常逻辑:1+2+3+4+……+100.

逆向逻辑:s(100) = s(99) + 100;

       s(99) = s(98) + 99;

      ……………………………

       s(1) = 1;

转换为递归:

  s(n) = s(n-1) + n   

       s1 = 1

正常思维就是:横向从左到右加

逆向的递归思维就是:纵向分为s(n-1)和n

递归不好理解主要是: 

  1、逆向思维

  2、解决的问题与问题复杂度无关,只要找到调用关系和出口。

例如:

斐波那契数列1、1、2、3、5、8、13、21、34……

F(n)=F(n - 1)+F(n - 2)   //调用关系

F(0)=1,F(1)=1;    //出口

#include "stdafx.h"
//1 1 2 3 5 8 13 21

int f(int n){
	if(n==1||n==2)
		return 1;
	else
		return f(n-1)+f(n-2);
}
int _tmain(int argc, _TCHAR* argv[])
{	
	int m=7;
	int x = f(m);
	printf("f(%d):%d\n",m,x);
	getchar();
	return 0;
}

调用堆栈:

 递归类似于栈的特性:先进后出。

快速排序算法递归实现:

#include "stdafx.h"
//
int partition(int arr[] ,int startIndex,int endIndex){
		
		int pivot = arr[startIndex];
        int left = startIndex;
        int right = endIndex;

        while (left!=right){
            //控制right 指针比较并左移
            while (left<right&&arr[right]>pivot){
                right--;
            }
            //控制left指针比较并右移
            //有等于是因为:int pivot = arr[startIndex]; int left = startIndex;
            while (left<right&&arr[left]<=pivot){
                left++;
            }
            //left和right都找到后,交换这俩的值
            if (left<right){
                int p =arr[left];
                arr[left]=arr[right];
                arr[right]=p;
            }
        }
        //到这一步的时候left==right了
        //执行pivot 和指针重合点交换
        arr[startIndex] = arr[left];
        arr[left] = pivot;
        //至此,依据第一个元素(基准元素pivot),把数组大于第一个元素的放在他右边,小于的放在左边,并返回基准元素(pivot)最终的下标
        return left;
    }

void quicksort(int aa[],int startIndex,int endIndex)
{
	if(startIndex>=endIndex){
            return;
     }
	int p = partition(aa, startIndex, endIndex);
    /************************/

    quicksort(aa, startIndex, p - 1);
    quicksort(aa, p + 1, endIndex);
}
int _tmain(int argc, _TCHAR* argv[])
{	
	int aa[11]={5,9,3,2,1,7,10,8,6,4,12};
	for(int i=0;i<11;i++){
		printf("%d ",aa[i]);
	}
	printf("\n*************\n");

	quicksort(aa,0,10);

	for(int i=0;i<11;i++){
		printf("%d ",aa[i]);
	}
	getchar();
	return 0;
}

  快速排序的逻辑是,若要对 nums[startIndex..endIndex] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[startIndex..p-1] 都小于等于 nums[p],且 nums[p+1..endIndex] 都大于 nums[p],然后递归地去 nums[startIndex..p-1] 和 nums[p+1..endIndex] 中寻找新的分界点,最后整个数组就被排序了。

算法理解示意图如下:

 

快速排序其实就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历。

 

posted @ 2023-10-18 15:07  一日学一日功  阅读(27)  评论(0)    收藏  举报