zoukankan      html  css  js  c++  java
  • 1

    1123. Is It a Complete AVL Tree (30)

    时间限制: 400 ms
    内存限制: 65536 kB
    代码长度限制: 16000 B
    判题程序:Standard

      An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.
    Now given a sequence of insertions, you are supposed to output the level-order traversal sequence of the resulting AVL tree, and to tell if it is a complete binary tree.

    Input   Each input file contains one test case. For each case, the first line contains a positive integer N (<= 20). Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.
    Output   For each test case, insert the keys one by one into an initially empty AVL tree. Then first print in a line the level-order traversal sequence of the resulting AVL tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line. Then in the next line, print "YES" if the tree is complete, or "NO" if not.
    Examples
    >| Input| | ------------- | | 5
    88 70 61 63 65 | | Output | | 70 63 88 61 65
    YES |
    >| ------------- | >| Input| | 8
    88 70 61 96 120 90 65 68| | Output | | 88 65 96 61 70 90 120 68
    NO|   Notes   
    作者   CHEN, Yue

      下面程序的AVL树是用平衡因子实现的,平衡处理是独立的,再插入操作完成后进行,这样的写法可能更清晰,易于理解。
      判断树是否为完全二叉树的做法是,用一个存储节点指针的queue对树进行层次遍历,从根节点开始,先将其指针加入queue,不断将queue的队首元素的左右节点指针(空指针也加入)加入queue后将队首元素移出,直到queue空为止。在遍历的过程中,queue队首元素第一次为空指针时,如果已经将所有节点遍历完(计数即可),就说明该树为完全二叉树。
      

    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <vector>
    #include <functional>
    #include <string>
    #include <cstring>
    #include <queue>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <cstdio>
    #include <sstream>
    #include <iomanip>
    using namespace std;
    #define IOS ios_base::sync_with_stdio(false)
    #define TIE std::cin.tie(0)
    #define MIN2(a,b) (a<b?a:b)
    #define MIN3(a,b) (a<b?(a<c?a:c):(b<c?b:c))
    #define MAX2(a,b) (a>b?a:b)
    #define MAX3(a,b,c)  (a>b?(a>c?a:c):(b>c?b:c))
    typedef long long LL;
    typedef unsigned long long ULL;
    const int INF = 0x3f3f3f3f;
    const double PI = 4.0*atan(1.0);
    const double eps = 1e-6;
    
    int n, x;
    
    struct AVLTree{
    	struct AVLTreeNode{
    		int data;
    		int balanceFactor;//平衡因子
    		AVLTreeNode * left = NULL;
    		AVLTreeNode * right = NULL;
    		AVLTreeNode(){}
    		AVLTreeNode(int item) :data(item){}
    	};
    	typedef AVLTreeNode * AVLTreeNodePointer;
    	void insert(int item);
    	void adj();
    	int adjAux(AVLTreeNodePointer & subtreeRoot, int h);
    	void leftSingleRotation(AVLTreeNodePointer & subtreeRoot);
    	void rightSingleRotation(AVLTreeNodePointer & subtreeRoot);
    	void leftDoubleRotation(AVLTreeNodePointer & subtreeRoot);
    	void rightDoubleRotation(AVLTreeNodePointer & subtreeRoot);
    	void levelorder(AVLTreeNodePointer subtreeRoot) const;
    	AVLTreeNodePointer myRoot = NULL;
    };
    
    void AVLTree::insert(int item)
    {
    	AVLTreeNodePointer locptr = myRoot;				 //查找指针
    	AVLTreeNodePointer parent = 0;
    	bool found = false;						 //表示item是否已存在于树中
    	while (!found && locptr != 0)
    	{
    		parent = locptr;
    		if (item < locptr->data)             //下降到左子树
    			locptr = locptr->left;
    		else if (locptr->data < item)        //下降到右子树
    			locptr = locptr->right;
    		else
    			found = true;                    //item被找到
    	}
    	if (!found)								 //item未被找到
    	{
    		//创建包含item的节点
    		locptr = new AVLTreeNode(item);
    		if (parent == 0)					 //当前树为空
    			myRoot = locptr;
    		else if (item < parent->data)        //作为父亲节点的左孩子插入
    			parent->left = locptr;
    		else
    			parent->right = locptr;          //作为父亲节点的右孩子插入
    	}
    	else
    		;//item已存在 
    }
    
    void AVLTree::adj()
    {
    	adjAux(myRoot, 1);
    }
    
    int AVLTree::adjAux(AVLTreeNodePointer & subtreeRoot, int h)
    {
    	//参数height为节点的高度,设定根节点的高度为1,自顶向下逐层的高度依次加1
    	int leftHeight = 0, rightHeight = 0;
    	if (subtreeRoot != NULL)
    	{
    		h++;                                                 //高度增加1
    		leftHeight = adjAux(subtreeRoot->left, h);    //左子树相对根节点的高度
    		rightHeight = adjAux(subtreeRoot->right, h);  //右子树相对根节点的高度
    		subtreeRoot->balanceFactor = leftHeight - rightHeight;    //计算平衡因子
    
    		if (subtreeRoot->balanceFactor == 2)                      //左子树高
    		{
    			if (subtreeRoot->left->balanceFactor == 1)            //右单旋
    				rightSingleRotation(subtreeRoot);
    			else if (subtreeRoot->left->balanceFactor == -1)      //右双旋
    				rightDoubleRotation(subtreeRoot);
    			return adjAux(subtreeRoot, h - 1);        //旋转调整后重新计算平衡因子
    		}
    		else if (subtreeRoot->balanceFactor == -2)				  //右子树高
    		{
    			if (subtreeRoot->right->balanceFactor == -1)          //左单旋
    				leftSingleRotation(subtreeRoot);
    			else if (subtreeRoot->right->balanceFactor == 1)      //左双旋
    				leftDoubleRotation(subtreeRoot);
    			return adjAux(subtreeRoot, h - 1);		  //旋转调整后重新计算平衡因子
    		}
    		else                                                      //不需调整,返回左子树和右子树树高的最大值
    		{                                                         //即为父亲节点的高度
    			return max(leftHeight, rightHeight);
    		}
    	}
    	else
    		return h;                                             //节点为空
    }
    
    void AVLTree::leftSingleRotation(AVLTreeNodePointer & subtreeRoot)
    {
    	AVLTreeNodePointer rightTree = subtreeRoot->right;
    	subtreeRoot->right = rightTree->left;
    	rightTree->left = subtreeRoot;
    	subtreeRoot = rightTree;
    }
    
    void AVLTree::rightSingleRotation(AVLTreeNodePointer & subtreeRoot)
    {
    	AVLTreeNodePointer leftTree = subtreeRoot->left;
    	subtreeRoot->left = leftTree->right;
    	leftTree->right = subtreeRoot;
    	subtreeRoot = leftTree;
    }
    
    void AVLTree::leftDoubleRotation(AVLTreeNodePointer & subtreeRoot)
    {
    	AVLTreeNodePointer rightTree = subtreeRoot->right,
    		child = rightTree->left;
    
    	//右旋
    	rightTree->left = child->right;
    	child->right = rightTree;
    	subtreeRoot->right = child;
    
    	//左旋
    	subtreeRoot->right = child->left;
    	child->left = subtreeRoot;
    	subtreeRoot = child;
    }
    
    void AVLTree::rightDoubleRotation(AVLTreeNodePointer & subtreeRoot)
    {
    	AVLTreeNodePointer leftTree = subtreeRoot->left,
    		child = leftTree->right;
    
    	//左旋
    	leftTree->right = child->left;
    	child->left = leftTree;
    	subtreeRoot->left = child;
    
    	//右旋
    	subtreeRoot->left = child->right;
    	child->right = subtreeRoot;
    	subtreeRoot = child;
    }
    
    void AVLTree::levelorder(AVLTreeNodePointer subtreeRoot) const
    {
    	queue<AVLTreeNodePointer> que;
    	que.push(myRoot);
    	bool first = true, nullfir=true;
    	bool cmp = false;
    	int cnt = 0;
    	while (!que.empty()){
    		AVLTreeNodePointer ptr = que.front();
    		que.pop();
    		if (ptr == NULL){
    			if (nullfir){
    				nullfir = false;
    				if (cnt == n)
    					cmp = true;
    			}
    			continue;
    		}
    		cnt++;
    		if(first) first = false;
    		else printf(" ");
    		printf("%d", ptr->data);
    		que.push(ptr->left);
    		que.push(ptr->right);
    	}
    	printf("
    %s
    ", cmp ? "YES" : "NO");
    }
    
    int main()
    {
    	AVLTree tree;
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++)
    	{
    		scanf("%d", &x);
    		tree.insert(x);
    		tree.adj();
    	}
    	tree.levelorder(tree.myRoot);
    	//system("pause");
    }
    //system("pause");
    
  • 相关阅读:
    Sum Root to Leaf Numbers 解答
    459. Repeated Substring Pattern
    71. Simplify Path
    89. Gray Code
    73. Set Matrix Zeroes
    297. Serialize and Deserialize Binary Tree
    449. Serialize and Deserialize BST
    451. Sort Characters By Frequency
    165. Compare Version Numbers
    447. Number of Boomerangs
  • 原文地址:https://www.cnblogs.com/cumulonimbus/p/6495620.html
Copyright © 2011-2022 走看看