• 【2020-MOOC-浙江大学-陈越、何钦铭-数据结构】树(第四周的笔记和编程作业)


    〇、前言

    这两周开始跟着【MOOC-浙江大学-陈越、何钦铭-数据结构】进行数据结构与算法的学习,特此记录复习一下,虽然记不住,但是一直记一直记一直记,成为复读机就好了。
    在这里插入图片描述

    一、二叉搜索树

    在这里插入图片描述
    在这里插入图片描述

    二、平衡二叉树

    在这里插入图片描述

    三、平衡二叉树的调整

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    四、是否同一棵二叉搜索树

    在这里插入图片描述
    在这里插入图片描述
    实现在后面的第一题!

    五、课后题

    在这里插入图片描述


    1、04-树4 是否同一棵二叉搜索树 (25分)

    在这里插入图片描述
    输入样例:

    4 2
    3 1 4 2
    3 4 1 2
    3 2 4 1
    2 1
    2 1
    1 2
    0

    输出样例:

    Yes
    No
    No


    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct TreeNode *Tree;
    struct TreeNode {
    	int v;
    	Tree Left, Right;
    	int flag;
    };
    
    Tree NewNode( int V )
    { 
    	Tree T = (Tree)malloc(sizeof(struct TreeNode));
    	T->v = V;
    	T->Left = T->Right = NULL;
    	T->flag = 0;
    	return T;
    }
    
    Tree Insert( Tree T, int V )
    {
    	if ( !T ) 
    		T = NewNode(V);
    	else {
    		if ( V>T->v )
    			T->Right = Insert( T->Right, V );
    		else
    			T->Left = Insert( T->Left, V );
    	}
    	return T;
    }
    
    Tree MakeTree( int N )
    { 
    	Tree T;
    	int i, V;
    	scanf("%d", &V);
    	T = NewNode(V);
    	for (i=1; i<N; i++) {
    		scanf("%d", &V);
    		T = Insert(T, V);
    	}
    	return T;
    }
    
    int check ( Tree T, int V )
    {
    	if ( T->flag ) {
    		if ( V<T->v ) 
    			return check(T->Left, V);
    		else if ( V>T->v ) 
    			return check(T->Right, V);
    		else 
    			return 0;
    	}
    	else {
    		if ( V==T->v ) {
    			T->flag = 1;
    			return 1;
    		}
    		else 
    			return 0;
    	}
    }
    
    int Judge( Tree T, int N )
    {
    	int i, V, flag = 0;
    	/* flag: 0代表目前还一致,1代表已经不一致*/
    	scanf("%d", &V);
    	if ( V!=T->v ) 
    		flag = 1;
    	else 
    		T->flag = 1;
    	for (i=1; i<N; i++) {
    		scanf("%d", &V);
    		if ( (!flag) && (!check(T, V)) ) 
    			flag = 1;
    	}
    	if (flag) 
    		return 0;
    	else 
    		return 1;
    }
    
    void ResetT ( Tree T ) /* 清除T中各结点的flag标记 */
    {
    	if (T->Left) ResetT(T->Left);
    	if (T->Right) ResetT(T->Right);
    	T->flag = 0;
    }
    
    void FreeTree ( Tree T ) /* 释放T的空间 */
    {
    	if (T->Left) FreeTree(T->Left);
    	if (T->Right) FreeTree(T->Right);
    	free(T);
    }
    
    int main()
    {
    	int N, L, i;
    	Tree T;
    	scanf("%d", &N);
    	while (N) {
    		scanf("%d", &L);
    		T = MakeTree(N);
    		for (i=0; i<L; i++) {
    			if (Judge(T, N)) 
    				printf("Yes
    ");
    			else 
    				printf("No
    ");
    			ResetT(T); /*清除T中的标记flag*/
    		}
    		FreeTree(T);
    		scanf("%d", &N);
    	}
    	return 0;
    }
    

    在这里插入图片描述


    2、04-树5 Root of AVL Tree (25分)

    在这里插入图片描述
    在这里插入图片描述
    Sample Input 1:

    5
    88 70 61 96 120

    Sample Output 1:

    70

    Sample Input 2:

    7
    88 70 61 96 120 90 65

    Sample Output 2:

    88


    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    typedef int ElementType;
    typedef struct AVLNode *Position;
    typedef Position AVLTree; /* AVL树类型 */
    struct AVLNode{
        ElementType Data; /* 结点数据 */
        AVLTree Left;     /* 指向左子树 */
        AVLTree Right;    /* 指向右子树 */
        int Height;       /* 树高 */
    };
    
    int Max ( int a, int b )
    {
        return a > b ? a : b;
    }
    
    int GetHeight(AVLTree A)
    {
    	int MaxH, HR, HL;
    	if(A) {
    		HL = GetHeight(A->Left);
    		HR = GetHeight(A->Right);
    		MaxH = (HL>HR)?HL:HR;
    		return MaxH+1;
    	}
    	return -1;
    }
    
    AVLTree SingleLeftRotation(AVLTree A)
    {
        AVLTree B = A->Left;
        A->Left = B->Right;
        B->Right = A;
        A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
        B->Height = Max(GetHeight(B->Left), A->Height) + 1;
    
        return B;
    }
    
    AVLTree SingleRightRotation(AVLTree A)
    {
        AVLTree B = A->Right;
        A->Right = B->Left;
        B->Left = A;
        A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
        A->Height = Max(GetHeight(B->Right), A->Height) + 1;
    
        return B;
    }
    
    AVLTree DoubleLeftRightRotation(AVLTree A)
    {
        A->Left = SingleRightRotation(A->Left);
    
        return SingleLeftRotation(A);
    }
    
    AVLTree DoubleRightLeftRotation(AVLTree A)
    {
        A->Right = SingleLeftRotation(A->Right);
    
        return SingleRightRotation(A);
    }
     
    AVLTree Insert( AVLTree T, ElementType X )
    { /* 将X插入AVL树T中,并且返回调整后的AVL树 */
        if ( !T ) { /* 若插入空树,则新建包含一个结点的树 */
            T = (AVLTree)malloc(sizeof(struct AVLNode));
            T->Data = X;
            T->Height = 0;
            T->Left = T->Right = NULL;
        } /* if (插入空树) 结束 */
     
        else if ( X < T->Data ) {
            /* 插入T的左子树 */
            T->Left = Insert( T->Left, X);
            /* 如果需要左旋 */
            if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 )
                if ( X < T->Left->Data ) 
                   T = SingleLeftRotation(T);      /* 左单旋 */
                else 
                   T = DoubleLeftRightRotation(T); /* 左-右双旋 */
        } /* else if (插入左子树) 结束 */
         
        else if ( X > T->Data ) {
            /* 插入T的右子树 */
            T->Right = Insert( T->Right, X );
            /* 如果需要右旋 */
            if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 )
                if ( X > T->Right->Data ) 
                   T = SingleRightRotation(T);     /* 右单旋 */
                else 
                   T = DoubleRightLeftRotation(T); /* 右-左双旋 */
        } /* else if (插入右子树) 结束 */
     
        /* else X == T->Data,无须插入 */
     
        /* 别忘了更新树高 */
        T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1;
         
        return T;
    }
    
    int main()
    {
    	int N, i;
    	ElementType t;
    	AVLTree T=NULL;
    	scanf("%d", &N);
    	for (i=0; i<N; i++) {
    	 	scanf("%d",&t);
    		T= Insert(T,t);
    	}
    	if(T)
    		printf("%d", T->Data);
    	return 0;
    }
    

    在这里插入图片描述


    3、04-树6 Complete Binary Search Tree (30分)

    在这里插入图片描述
    Sample Input:

    10
    1 2 3 4 5 6 7 8 9 0

    Sample Output:

    6 3 8 1 5 7 9 0 2 4


    在这里插入图片描述

    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    int arr[1000], rearr[1000];
    int compare( const void* a, const void* b ){
    	return *(int*)a - *(int*)b;
    }
    //利用二叉树的性质:
    //满二叉树第i层有 2^(i-1) 个结点, 
    //高为h的满二叉树有 2^h - 1 个结点(从1开始)
    int getLeftLength(int n){
    	double h, x, L, t;
    	h = (double)(int)( log((double)n+1) / log(2.0) );
    	//h = floor( log((double)n+1) / log(2.0) );	
    	x = n - pow(2.0, h) + 1 ;
    	t = pow(2.0, h - 1.0);
    	x = x < t ? x : t;
    	L = t - 1 + x;
    	return (int)L;
    }
    void solve( int left, int right, int root ){
    	//初始调用: solve(0, n-1, 0);
    	int n, L, leftRoot, rightRoot;
    	n = right - left + 1;			//数组中的总个数
    	if(n == 0) return ;				//递归退出的条件
    	L = getLeftLength(n);			//计算出左子树的结点
    	rearr[root] = arr[left + L];	//将新的根结点放入新的数组
    	leftRoot = root * 2 + 1;		//左孩子
    	rightRoot = leftRoot + 1;		//右孩子
    	solve(left, left + L - 1, leftRoot);
    	solve(left + L + 1, right, rightRoot);
    }
    int main(){
    	int n;
    	scanf("%d", &n);
    	for(int i = 0; i < n; i++){
    		scanf("%d", &arr[i]);
    	}
    	qsort(arr, n, sizeof(int), compare);
    	solve(0, n-1, 0);
    	for(int i = 0; i < n; i++){
    		if( i != 0 ) printf(" ");
    		printf("%d", rearr[i]);
    	}
    	system("pause");
    	return 0;
    }
    

    在这里插入图片描述


    4、04-树7 二叉搜索树的操作集 (30分)

    在这里插入图片描述
    在这里插入图片描述

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef int ElementType;
    typedef struct TNode *Position;
    typedef Position BinTree;
    struct TNode{
        ElementType Data;
        BinTree Left;
        BinTree Right;
    };
    
    void PreorderTraversal( BinTree BT ); /* 先序遍历,由裁判实现,细节不表 */
    void InorderTraversal( BinTree BT );  /* 中序遍历,由裁判实现,细节不表 */
    
    BinTree Insert( BinTree BST, ElementType X );
    BinTree Delete( BinTree BST, ElementType X );
    Position Find( BinTree BST, ElementType X );
    Position FindMin( BinTree BST );
    Position FindMax( BinTree BST );
    
    int main()
    {
        BinTree BST, MinP, MaxP, Tmp;
        ElementType X;
        int N, i;
    
        BST = NULL;
        scanf("%d", &N);
        for ( i=0; i<N; i++ ) {
            scanf("%d", &X);
            BST = Insert(BST, X);
        }
        printf("Preorder:"); PreorderTraversal(BST); printf("
    ");
        MinP = FindMin(BST);
        MaxP = FindMax(BST);
        scanf("%d", &N);
        for( i=0; i<N; i++ ) {
            scanf("%d", &X);
            Tmp = Find(BST, X);
            if (Tmp == NULL) printf("%d is not found
    ", X);
            else {
                printf("%d is found
    ", Tmp->Data);
                if (Tmp==MinP) printf("%d is the smallest key
    ", Tmp->Data);
                if (Tmp==MaxP) printf("%d is the largest key
    ", Tmp->Data);
            }
        }
        scanf("%d", &N);
        for( i=0; i<N; i++ ) {
            scanf("%d", &X);
            BST = Delete(BST, X);
        }
        printf("Inorder:"); InorderTraversal(BST); printf("
    ");
    
        return 0;
    }
    /* 你的代码将被嵌在这里 */
    

    输入样例:

    10
    5 8 6 2 4 1 0 10 9 7
    5
    6 3 10 0 5
    5
    5 7 0 10 3

    输出样例:

    Preorder: 5 2 1 0 4 8 6 7 10 9
    6 is found
    3 is not found
    10 is found
    10 is the largest key
    0 is found
    0 is the smallest key
    5 is found
    Not Found
    Inorder: 1 2 4 6 8 9


    
    BinTree Insert( BinTree BST, ElementType X ){
    	if( !BST ){
    		BST = (BinTree)malloc(sizeof(struct TNode));
    		BST->Data = X;
    		BST->Left = BST->Right = NULL;
    	}
    	else {
    		if( X < BST->Data ) BST->Left = Insert( BST->Left, X );
    		else if( X > BST->Data ) BST->Right = Insert( BST->Right, X );
    		//else if(X = BST->Data)  do nothing
    	}
    	return BST;
    }
    BinTree Delete( BinTree BST, ElementType X ){
    	Position TMP;
    	if( !BST ) printf("Not Found
    ");
    	else {
    		if( X < BST->Data ) BST->Left = Delete( BST->Left, X );  //从左子树递归删除
    		else if( X > BST->Data ) BST->Right = Delete( BST->Right, X );  //从右子树递归删除
    		else { //BST就是要删除的结点
    			if( BST->Left && BST->Right ){  //如果BST左右孩子都有
    				TMP = FindMin( BST->Right ); //从右子树中找到最小的结点来代替该结点
    				BST->Data = TMP->Data;
    				BST->Right = Delete( BST->Right, BST->Data );  //从右子树中把最小的结点删除
    			}
    			else { 
    				TMP = BST;
    				if( !BST->Left )	//如果只有右结点,或者没有结点
    					BST = BST->Right;
    				else				//只有左结点
    					BST = BST->Left;
    				free( TMP );
    			}
    		}
    	}
    	return BST;
    }
    Position Find( BinTree BST, ElementType X ){
    	if( !BST )	return NULL;
    	else if( X == BST->Data ) return BST;
    	else if( X > BST->Data ) return Find( BST->Right, X );
    	else if( X < BST->Data ) return Find( BST->Left, X );
    	return NULL;
    }
    //递归查找最小元素
    Position FindMin( BinTree BST ){
    	if( !BST ) return NULL;
    	else if( !BST->Left ) return BST;
    	else if( BST->Left ) FindMin( BST->Left );
    }
    //非递归查找最大元素
    Position FindMax( BinTree BST ){
    	if( BST )
    		while( BST->Right ) BST = BST->Right;
    	return BST;
    }
    

    在这里插入图片描述

    总结

    简单总结下这周的学习内容,继续二叉树,我觉得自己非常有做调包侠的前途!!!

    如果想要更多的资源,欢迎关注 @我是管小亮,文字强迫症MAX~

    回复【数据结构】即可获取我为你准备的大礼

    想看更多文(段)章(子),欢迎关注微信公众号「程序员管小亮」~

    在这里插入图片描述

  • 相关阅读:
    C++中析构函数为什么要是虚函数
    依赖注入(IOC)
    ParseInt()与NaN()
    仿windows关机效果
    类似Tab的效果
    飞来飞去的广告
    Sql Server 三种连接
    JS日期处理
    绚丽的注册效果
    JS图片自动切换
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13302612.html
Copyright © 2020-2023  润新知