zoukankan      html  css  js  c++  java
  • [PAT] A1066 Root of AVL Tree

    (要熟练!)

    题目大意

    输入一个结点序列,按照这个序列输入,每插入一次都自动调整为平衡二叉搜索树AVL。求最终形成的AVL树根的值。
    在AVL树中,任何节点的两个子子树的高度最多相差一个;如果在任何时候它们相差多于一个,则重新平衡以恢复此属性。

    思路

    熟练掌握建立AVL的代码即可。

    在判断子结点平衡因子的时候,为1和为-1两个if必须是互斥的。一开始没写else,会出现进入第一个if后平衡因子的值改变了又进入第二个if的情况。
    debug了一早上,一直以为是别的问题,没注意到这个细节...但发现可以不必在结构体中保存每个结点的高度,需要判断的时候每次递归求解即可。
    建立树的过程还不够熟练,一定要多多再写几遍。

    AC代码

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include <cstdio>
    #include <vector>
    #include <map>
    #include<algorithm>
    #include<queue>
    using namespace std;
    struct node {
    	int key;
    	node* lchild, * rchild;
    };
    int getheight(node* root) {
    	if (root == NULL)return 0;
    	return max(getheight(root->lchild), getheight(root->rchild)) + 1;
    }
    int balance(node* root) {
    	return getheight(root->lchild) - getheight(root->rchild);
    }
    void R(node*& root) {
    	node* newroot = root->lchild;
    	root->lchild = newroot->rchild;
    	newroot->rchild = root;
    	root = newroot;
    }
    void L(node*& root) {
    	node* newroot = root->rchild;
    	root->rchild = newroot->lchild;
    	newroot->lchild = root;
    	root = newroot;
    }
    void insert(node*& root, int number) {
    	if (root == NULL) {
    		root = new node;//注意细节
    		root->key = number;
    		root->lchild = root->rchild = NULL;
    		return;
    	}
    	if (number < root->key) {
    		insert(root->lchild, number);
    		if (balance(root) == 2) {
    			if (balance(root->lchild) == 1)R(root);
                            //一开始漏了“else”,可能出现进入上一个1的if后值改变了又进入第二个if的情况
    			else if (balance(root->lchild) == -1) {
    				L(root->lchild);
    				R(root);
    			}
    		}
    	}
    	else {
    		insert(root->rchild, number);
    		if (balance(root) == -2) {
    			if (balance(root->rchild) == -1)L(root);
    			else if (balance(root->rchild) == 1) {
    				R(root->rchild);
    				L(root);
    			}
    		}
    	}
    }
    int main() {
    	int i, n;
    	scanf("%d", &n);
    	int number;
    	node* root = NULL;
    	for (i = 0;i < n;i++) {
    		scanf("%d", &number);
    		insert(root, number);
    	}
    	printf("%d", root->key);
    	return 0;
    }
    
    

    最后附上一个按照算法笔记上写的(在节点中加入了参数height表示该结点的高度)代码

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include <cstdio>
    #include <vector>
    #include <map>
    #include<algorithm>
    #include<queue>
    using namespace std;
    struct node {
    	int key;
    	node* lchild, * rchild;
    	int height;
    };
    int getheight(node* p) {
    	if (p == NULL)return 0;
    	return p->height;
    }
    int balance(node* root) {
    	return getheight(root->lchild) - getheight(root->rchild);
    }
    void updateheight(node* root) {
    	root->height = max(getheight(root->lchild), getheight(root->rchild)) + 1;
    }
    void R(node*& root) {
    	node* newroot = root->lchild;
    	root->lchild = newroot->rchild;
    	newroot->rchild = root;
    	updateheight(root);//记得更新高度!而且这里必须先更新root(因为它现在是newroot孩子)!
    	updateheight(newroot);
    	root = newroot;
    }
    void L(node*& root) {
    	node* newroot = root->rchild;
    	root->rchild = newroot->lchild;
    	newroot->lchild = root;
    	updateheight(root);//记得更新高度!
    	updateheight(newroot);
    	root = newroot;
    }
    void insert(node*& root, int number) {
    	if (root == NULL) {
    		root = new node;//注意细节
    		root->height = 1;
    		root->key = number;
    		root->lchild = root->rchild = NULL;
    		return;
    	}
    	if (number <= root->key) {
    		insert(root->lchild, number);
    		updateheight(root);
    		if (balance(root) == 2) {
    			if (balance(root->lchild) == 1)R(root);
    			else if (balance(root->lchild) == -1) {
    				L(root->lchild);
    				R(root);
    			}
    		}
    	}
    	else {
    		insert(root->rchild, number);
    		updateheight(root);
    		if (balance(root) == -2) {
    			if (balance(root->rchild) == -1)L(root);
    			else if (balance(root->rchild) == 1) {
    				R(root->rchild);
    				L(root);
    			}
    		}
    	}
    }
    int main() {
    	int i, n;
    	scanf("%d", &n);
    	int number;
    	node* root = NULL;
    	for (i = 0;i < n;i++) {
    		scanf("%d", &number);
    		insert(root, number);
    	}
    	printf("%d", root->key);
    	return 0;
    }
    
  • 相关阅读:
    芯片产品介绍
    稀疏矩阵理论与实践
    EUV极紫外光刻技术
    国内AI与芯片企业列表
    中国软件外包现状对比
    GPU指令集技术分析
    寒武纪智能系统参数
    TVM量化路线图roadmap
    EUV光刻机市场与技术
    轻松部署 .NET 5 应用程序,这个指南一定不要错过
  • 原文地址:https://www.cnblogs.com/yue36/p/13306247.html
Copyright © 2011-2022 走看看