zoukankan      html  css  js  c++  java
  • PAT1123 AVL树的调整与判断完全二叉树

    解析:这题我学了一天AVL树的调整,建好了树,又用了一个多小时尝试各种方法判断是否为完全二叉树,最后败在了输出层次遍历上。。

    解题步骤:

    • 建立AVL树,其中涉及AVL树的四种调整
    • 输出层次遍历,用队列输出,不能用stack!
    • 判断一棵树是否为完全二叉树,可以给每个节点编号,比如某个节点编号为id,它左儿子为2*id,右儿子为2*id+1,如果最大的编号为n,即为完全二叉树。(这也是完全二叉树的一个性质)

    代码示例:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    typedef struct AVLNode *position;
    typedef position AVLTree;
    int maxid = -1;
    struct AVLNode{
    	int data;
    	AVLTree left;
    	AVLTree right;
    	int h;
    };
    int GetHight(AVLTree A){
    	if(A == NULL)	return -1;
    	return A->h;
    }
    //左单旋
    AVLTree SLR(AVLTree A){
    	AVLTree B = A->left;
    	A->left = B->right;
    	B->right = A;
    	A->h = max(GetHight(A->left),GetHight(A->right))+1;
    	B->h = max(GetHight(B->left),GetHight(B->right))+1;
    	return B;
    } 
    //右单旋
    AVLTree SRR(AVLTree A){
    	AVLTree B = A->right;
    	A-> right = B->left;
    	B->left = A;
    	A->h = max(GetHight(A->left),GetHight(A->right))+1;
    	B->h = max(GetHight(B->left),GetHight(B->right))+1;
    	return B;
    }
    //左右双旋
    AVLTree DLRR(AVLTree A){
    	AVLTree B = A->left;
    	A->left = SRR(B);
    	return SLR(A);
    }
    //右左双旋 
    AVLTree DRLR(AVLTree A){
    	AVLTree B = A->right;
    	A->right = SLR(B);
    	return SRR(A);
    }
    AVLTree Insert(AVLTree T,int x){
    	if(T == NULL){
    		T = new AVLNode();
    		T->data = x;
    		T->left = NULL;
    		T->right = NULL;
    		T->h = 0;
    	}else if(x < T->data){
    		T->left = Insert(T->left,x);
    		if(GetHight(T->left) - GetHight(T->right) == 2)
    			if(x < T->left->data)	T = SLR(T);
    			else T = DLRR(T);
    	}else if(x > T->data){
    		T->right = Insert(T->right,x);
    		if(GetHight(T->left)-GetHight(T->right) == -2)
    			if(x > T->right->data)	T = SRR(T);
    			else	T = DRLR(T);
    	}
    	T->h = max(GetHight(T->left),GetHight(T->right))+1;
    	return T;
    }
    void printTree(AVLTree T){
    	if(!T)	return;
    	queue<AVLTree> q;
    	q.push(T);
    	int cnt = 0;
    	while(q.size()){
    		AVLTree a = q.front();
    		q.pop();
    		if(cnt == 0)	printf("%d",a->data);
    		else	printf(" %d",a->data);
    		cnt++;
    		if(a->left)	q.push(a->left);
    		if(a->right)	q.push(a->right);
    	} 
    	printf("
    ");
    }
    void solve(AVLTree T,int id){
    	maxid = max(id,maxid);
    	if(T->left)	solve(T->left,id<<1);
    	if(T->right)	solve(T->right,id<<1|1);
    	return;
    }
    bool judge(AVLTree T,int n){
    	solve(T,1);
    	if(maxid != n)	return false;
    	return true;
    }
    int main()
    {
    	int n,x;
    	scanf("%d",&n);
    	AVLTree T = NULL;
    	for(int i = 0;i < n;i++){
    		scanf("%d",&x);
    		T = Insert(T,x);
    	}
    	if(n == 0)	puts("NO");
    	else{
    		printTree(T);
    		if(judge(T,n))	puts("YES");
    		else puts("NO");
    	}
    	
    	return 0;
    } 
  • 相关阅读:
    Android设计模式(三)--装饰模式
    kmp算法总结
    SDWebImage源代码解析(二)
    关于C++构造函数一二
    逆向随笔
    iOS中的crash防护(二)KVC造成的crash
    git-osc自己定义控件之:CircleImageView
    java中继承关系学习小结
    openwrt针对RT5350代码下载,配置和编译
    MySQL监控
  • 原文地址:https://www.cnblogs.com/long98/p/10352180.html
Copyright © 2011-2022 走看看