阿里14笔试题-求一个二叉树最大值和最小值的差值绝对值

阿里巴巴面试题:

输入:一个二叉树

输出:二叉树的最大值和最小值的差值绝对值


单纯从算法功能上来看

1-可以先建立一个大根堆,把最大的元素挑出来;

2-然后在建立小根堆,把最小的元素挑出来;

3-在求最大和最小差值的绝对值;

代码:

#if 0
/*
最大堆排序
*/
#include<stdio.h>
#include<stdlib.h>
#define LeftChild(i) ( 2*i + 1 )
// 下标 i = 0 存储是最大的值 , 所以leftchild 是 2×i + 1 ;
void PercDown(int a[] , int i , int n) //最大的下滤
{
    int child , temp ;
    for( temp = a[i] ; LeftChild(i) < n ; i = child )
    {
        child = LeftChild(i);
        if ( (child != n -1) && (a[child+1] > a[child]) ) //选择最大的孩子节点,
            child++;
        if( temp < a[child] )
            a[i] = a[child] ; //把孩子节点赋值给  父节点
        else
            break;
    }
    a[i] = temp ;
}

void PercUp(int a[] , int i , int n) //最小的上滤
{
    int child , temp ;
    for( temp = a[i] ; LeftChild(i) < n ; i = child )
    {
        child = LeftChild(i);
        if ( (child != n -1) && (a[child+1] < a[child]) ) // 选择最小的节点 若右孩子小于左孩子,所以要用右孩子去和根节点比较
            child++;
        if( temp > a[child] )
            a[i] = a[child] ;//把最小的孩子  赋值给父节点
        else
            break;
    }
    a[i] = temp ; //把之前节点 赋值给当前需要交换的节点
}

void Swap(int *a , int *b)
{
    int *Tmp ;
    *Tmp = *a ;
    *a = *b ;
    *b = *Tmp ;
}
int HeapSort(int a[] ,int n )
{
    int i , Tmp_Larger ,Tmp_Smaller ;
    for(i = n/2 ; i >= 0 ; i-- ) // n/2 标号最大分支节点,即最大的非叶子节点标号 ;
        PercDown(  a , i , n ); //求最大堆,采用下滤,使最大的浮上来
    #if 0
   printf("The first build large heap:\n");
    for(i = 0 ; i < n ; i++ )
        printf("%d \t" , a[i]);
        printf("\n");
    #endif
    Tmp_Larger = a[0];
    printf("larger : %d \n" ,a[0]);

    #if 0 //this code for heap sort
    for(i = n -1 ; i > 0 ; i-- )
    {
        Swap( &a[0] , &a[i] ) ;  //本代码 堆排序是数组从下标0开始的 ,堆的最后元素和堆的首元素交换 ,仅仅用一个数组就可以排序
        PercDown(a , 0 , i ) ;
    }
    #endif


     for(i = n/2 ; i >= 0 ; i-- ) // n/2 标号最大分支节点,即最大的非叶子节点标号 ;
        PercUp(  a , i , n ); //求最小堆,采用上滤,使最小的浮上来
    #if 0
    printf("The first build smaller heap:\n");
    for(i = 0 ; i < n ; i++ )
        printf("%d \t" , a[i]);
        printf("\n");
    #endif
    Tmp_Smaller = a[0];
    printf("smaller : %d \n" ,a[0]);

    return abs(Tmp_Larger - Tmp_Smaller);
}

int main()
{   int a[] = {31,41,59,26,53,58,97,-1,100}; //测试数组
    int len , i ;
    len = sizeof(a)/sizeof(int);
    i = HeapSort( a , len );  //建立堆
    printf("This is a HeapSort Data: %d\n",i);


  #if 0
    for(i = 0 ; i < len ; i++ ) //遍历已经拍好序的数组
        printf("%d \t" , a[i]);
  #endif
    return 1;
}
#endif
结果:
larger : 100
smaller : -1
This is a HeapSort Data: 101


Process returned 1 (0x1)   execution time : 0.028 s
Press any key to continue.


不过从工程上来说,这样的代码肯定是不行的,需求一改那这个代码又需要修改,比如:求最大和中间差值的绝对值。那这个代码就不行了,所以先排序然后在按需求输出,就爽爆天了!

排序:先看排序的数量,数量大优先选用快排,数量小用插入;

代码:

#include<stdio.h>
#define cutoff 3
void Swap(int *a ,int *b)
{
    int *temp ;
    *temp = *a;
    *a = *b;
    *b = *temp;
}
int Median3(int a[] ,int Left , int Right)
{
    int Center ;
    Center = (Left + Right )/2 ;

    if (a[Left] > a[Center])
        Swap(&a[Left] , &a[Center]);
    if (a[Left] > a[Right])
        Swap(&a[Left] , &a[Right]);
    if (a[Center] > a[Right])
        Swap(&a[Center] , &a[Right]);
    Swap(&a[Center] , &a[Right-1]);//把枢纽元素和放在倒数第二个位置  ,Left < Center , Right > Center ; 所以开始比较就不用从Left && Righr开始
    return a[ Right-1 ] ;
}

void InsertionSort( int A[ ], int N )
{
    int j, P;
    int  Tmp;

    for( P = 1; P < N; P++ )
    {
        Tmp = A[ P ];
        for( j = P; j > 0 && A[ j - 1 ] > Tmp; j-- )
            A[ j ] = A[ j - 1 ];
        A[ j ] = Tmp;
    }
}
void Qsort(int a[] , int Left , int Right )
{
    int i , j ;
    int Pivot ;
    if ( Left + cutoff <= Right ) //
    {
        Pivot = Median3(a,Left,Right);
        i = Left ; j = Right -1 ;
        for( ; ; )
        {
            while( a[++i] < Pivot ){}
            while( a[--j] > Pivot ){}
            if ( i < j )
                Swap(&a[i] , &a[j]);
            else
                break;
        }
        Swap(&a[i] , &a[Right-1]) ;
        Qsort(a,Left,i-1) ;
        Qsort(a,i+1,Right) ;
    }
    else
    {
             InsertionSort(a+Left , Right - Left + 1) ;
         //    printf("using InsertionSort ! \n");
    }

}
int main()
{
   int i,a[] = {31,41,59,26,53,58,97,-1,100}; //测试数组
   int len = sizeof(a)/sizeof(int);
   Qsort( a , 0 , len );
   printf("The sort after : \n");
   for( i = 0 ; i < len ; i++ )
        printf("%d \t " ,a[i] );
    printf("\n");
    printf("The vuale of largest and smaller is : %d ", a[len-1] - a[0] );
    return 0;
}
结果:

The sort after :
-1       26      31      41      53      58      59      97      100
The vuale of largest and smaller is : 101
Process returned 0 (0x0)   execution time : 0.023 s
Press any key to continue.



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值