AVL树问题

 在学习AVL二叉树的时候,碰到了这个题目:给出一段序列,让后让你找出这个序列生成的AVL树的根节点

我的本人的代码如下。

主要思路:

   每个节点记录值:当前节点的值,其父节点,左右子树,左右子树的高度

      每次添加一个节点后,根据查找树的方法,进行生成。

      然后根据最后添加的节点,反向向上依次更新父节点的左右子树高度,如果父节点没有或者是其父节点的作用子树的高度没有变化,那么就停止向上更新。在此过程中同时,检查左右子树的高度差,如果超过1说明就是不平衡,需要进行校正

    然后根据情况进行校正。一共四种情况。具体可以见 https://www.sohu.com/a/270452030_478315

/*******************************************************
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 tell the root of the resulting AVL tree.
5
88 70 61 96 120

70
*****************************************************/
#include "stdafx.h"
#include "iostream"
#include <string>
#include <math.h>
#include <vector>
#include <algorithm>

using namespace std;

struct note
{
	int element;
	int left_height,right_height;
	int parent;
	int add;
	int LeftChild;
	int RightChild;
};
//树的高度矫正
int TreeHightRecorrect(int NoteIndex, vector<note> &Tree)    
{
	int	wrongNote = -1;
	if (NoteIndex==-1)
	{
		return wrongNote;
	}
	int currentIndexNote = Tree.at(NoteIndex).parent;
	while (currentIndexNote !=-1)
	{
		
		int sonNoteLeft = Tree.at(currentIndexNote).LeftChild;
		int sonNoteright = Tree.at(currentIndexNote).RightChild;
		int maxLeftH = 0, maxRightH = 0;
		if (sonNoteLeft != -1)
			 maxLeftH = max(Tree.at(sonNoteLeft).left_height, Tree.at(sonNoteLeft).right_height)+1;

		if (sonNoteright != -1)
			 maxRightH = max(Tree.at(sonNoteright).left_height, Tree.at(sonNoteright).right_height)+1;

		if (Tree.at(currentIndexNote).left_height != maxLeftH )
		{
			Tree.at(currentIndexNote).left_height = maxLeftH ;
			if (abs(Tree.at(currentIndexNote).right_height - Tree.at(currentIndexNote).left_height)>1)
			{
				if (wrongNote == -1)
					wrongNote = currentIndexNote;
			}
		}
		else if (Tree.at(currentIndexNote).right_height != maxRightH )
		{
			Tree.at(currentIndexNote).right_height = maxRightH ;
			if (abs(Tree.at(currentIndexNote).right_height - Tree.at(currentIndexNote).left_height)>1)
			{
				if (wrongNote == -1)
					wrongNote = currentIndexNote;
			}
		}
		else
		{
			return wrongNote;
		}
		currentIndexNote = Tree.at(currentIndexNote).parent;
	}
	return wrongNote;
}

//将c插入一个节点后被破坏的AVL树进行纠正
//NoteIndex 第一个被破坏的节点
//Tree 传入的节点树
bool reAVL(int NoteIndex, vector<note> &Tree)
{
	if (NoteIndex == -1)
	{
		return false;
	}
	int secendNote = -1;
	int thirdNote = -1;
	if (Tree.at(NoteIndex).left_height>Tree.at(NoteIndex).right_height)
	{
		secendNote = Tree.at(NoteIndex).LeftChild;
		if (Tree.at(secendNote).left_height>Tree.at(secendNote).right_height)    //LL
		{
	   
			if (Tree.at(secendNote).RightChild !=-1)
			{
				Tree.at(Tree.at(secendNote).RightChild).parent = NoteIndex;
			}
			Tree.at(NoteIndex).LeftChild = Tree.at(secendNote).RightChild;
			Tree.at(secendNote).parent = Tree.at(NoteIndex).parent;
			Tree.at(NoteIndex).parent = secendNote;
			Tree.at(secendNote).RightChild = NoteIndex;

			if (Tree.at(secendNote).parent != -1)
			{
				if (Tree.at(Tree.at(secendNote).parent).LeftChild == NoteIndex)   //第一个出问题的节点是其父节点的左子树
					Tree.at(Tree.at(secendNote).parent).LeftChild = secendNote;
				else
					Tree.at(Tree.at(secendNote).parent).RightChild = secendNote;

			}

			Tree.at(NoteIndex).left_height = Tree.at(secendNote).right_height;
			if (Tree.at(NoteIndex).left_height>Tree.at(NoteIndex).right_height)
			{
				Tree.at(secendNote).right_height = Tree.at(NoteIndex).left_height+1;
			}
			else
			{
				Tree.at(secendNote).right_height = Tree.at(NoteIndex).right_height + 1;
			}
			TreeHightRecorrect(secendNote, Tree);

		}
		else																    //LR
		{
			thirdNote = Tree.at(secendNote).RightChild;

			Tree.at(secendNote).RightChild = Tree.at(thirdNote).LeftChild;
			if (Tree.at(thirdNote).LeftChild !=-1)
			{
				Tree.at(Tree.at(thirdNote).LeftChild).parent = secendNote;
			}
	
			Tree.at(NoteIndex).LeftChild = Tree.at(thirdNote).RightChild;			
			if (Tree.at(thirdNote).RightChild != -1)
			{
				Tree.at(Tree.at(thirdNote).RightChild).parent = NoteIndex;
			}

			Tree.at(thirdNote).parent = Tree.at(NoteIndex).parent;

			Tree.at(thirdNote).LeftChild = secendNote;
			Tree.at(secendNote).parent = thirdNote;

			Tree.at(thirdNote).RightChild = NoteIndex;
			Tree.at(NoteIndex).parent = thirdNote;

			if (Tree.at(thirdNote).parent !=-1)
			{
				if (Tree.at(Tree.at(thirdNote).parent).LeftChild = NoteIndex)   //第一个出问题的节点是其父节点的左子树
					Tree.at(Tree.at(thirdNote).parent).LeftChild = thirdNote;
				else
					Tree.at(Tree.at(thirdNote).parent).RightChild = thirdNote;
			}

			Tree.at(secendNote).right_height = Tree.at(thirdNote).left_height;
			Tree.at(NoteIndex).left_height = Tree.at(thirdNote).right_height;
			if (Tree.at(secendNote).left_height > Tree.at(secendNote).right_height)
				Tree.at(thirdNote).left_height = Tree.at(secendNote).left_height + 1;
			else
				Tree.at(thirdNote).left_height = Tree.at(secendNote).right_height + 1;

			if (Tree.at(NoteIndex).left_height > Tree.at(NoteIndex).right_height)
				Tree.at(thirdNote).right_height = Tree.at(NoteIndex).left_height + 1;
			else
				Tree.at(thirdNote).right_height = Tree.at(NoteIndex).right_height + 1;

			TreeHightRecorrect(thirdNote, Tree);
		}
	}
	else
	{
		secendNote = Tree.at(NoteIndex).RightChild;
		if (Tree.at(secendNote).left_height>Tree.at(secendNote).right_height)  //RL
		{
			thirdNote = Tree.at(secendNote).LeftChild;

			Tree.at(secendNote).LeftChild = Tree.at(thirdNote).RightChild;
			if (Tree.at(thirdNote).RightChild !=-1)
			{
				Tree.at(Tree.at(thirdNote).RightChild).parent = secendNote;
			}
			
			Tree.at(NoteIndex).RightChild = Tree.at(thirdNote).LeftChild;
			if (Tree.at(thirdNote).LeftChild != -1)
			{
				Tree.at(Tree.at(thirdNote).LeftChild).parent = NoteIndex;
			}

			Tree.at(thirdNote).parent = Tree.at(NoteIndex).parent;
			Tree.at(thirdNote).LeftChild = NoteIndex;
			Tree.at(NoteIndex).parent = thirdNote;

			Tree.at(thirdNote).RightChild = secendNote;
			Tree.at(secendNote).parent = thirdNote;

			if (Tree.at(thirdNote).parent != -1)
			{
				if (Tree.at(Tree.at(thirdNote).parent).LeftChild == NoteIndex)   //第一个出问题的节点是其父节点的左子树
					Tree.at(Tree.at(thirdNote).parent).LeftChild = thirdNote;
				else
					Tree.at(Tree.at(thirdNote).parent).RightChild = thirdNote;
			}

			Tree.at(secendNote).left_height = Tree.at(thirdNote).right_height;
			Tree.at(NoteIndex).right_height = Tree.at(thirdNote).left_height;
			if (Tree.at(secendNote).left_height > Tree.at(secendNote).right_height)
				Tree.at(thirdNote).right_height = Tree.at(secendNote).left_height + 1;
			else
				Tree.at(thirdNote).right_height = Tree.at(secendNote).right_height + 1;

			if (Tree.at(NoteIndex).left_height > Tree.at(NoteIndex).right_height)
				Tree.at(thirdNote).left_height = Tree.at(NoteIndex).left_height + 1;
			else
				Tree.at(thirdNote).left_height = Tree.at(NoteIndex).right_height + 1;

			TreeHightRecorrect(thirdNote, Tree);

		}
		else																	//RR
		{

			if (Tree.at(secendNote).LeftChild != -1)
			{
				Tree.at(Tree.at(secendNote).LeftChild).parent = NoteIndex;
			}
			Tree.at(NoteIndex).RightChild = Tree.at(secendNote).LeftChild;
			Tree.at(secendNote).parent = Tree.at(NoteIndex).parent;
			Tree.at(NoteIndex).parent = secendNote;
			Tree.at(secendNote).LeftChild = NoteIndex;

			if (Tree.at(secendNote).parent != -1)
			{
				if (Tree.at(Tree.at(secendNote).parent).LeftChild == NoteIndex)   //第一个出问题的节点是其父节点的左子树
					Tree.at(Tree.at(secendNote).parent).LeftChild = secendNote;
				else
					Tree.at(Tree.at(secendNote).parent).RightChild = secendNote;
			}

			Tree.at(NoteIndex).right_height = Tree.at(secendNote).left_height;
			if (Tree.at(NoteIndex).left_height>Tree.at(NoteIndex).right_height)
			{
				Tree.at(secendNote).left_height = Tree.at(NoteIndex).left_height + 1;
			}
			else
			{
				Tree.at(secendNote).left_height = Tree.at(NoteIndex).right_height + 1;
			}
			TreeHightRecorrect(secendNote, Tree);
		}
	}
	return true;
}

int GetTheTree(int noteNuber, vector<note> &Tree)
{
	Tree.clear();

	for (int i = 0; i < noteNuber; i++)   //构造查找二叉树
	{
		note temp;
		cin >> temp.element;
		temp.add = Tree.size(); 
		temp.LeftChild = -1; 
		temp.RightChild = -1;
		temp.left_height = 0;
		temp.right_height = 0;
		if (Tree.empty())
		{
			temp.parent = -1;
			Tree.push_back(temp);
		}
		else
		{
			int IndexCurrentNote = 0;
			int ParentNote = 0;
			while (IndexCurrentNote !=-1)
			{
				ParentNote = IndexCurrentNote;
				IndexCurrentNote = Tree.at(IndexCurrentNote).parent;
			}
			IndexCurrentNote = ParentNote;
			
			while (IndexCurrentNote!=-1)
			{
				ParentNote = IndexCurrentNote;
				if (Tree.at(IndexCurrentNote).element >temp.element)
				{
					IndexCurrentNote = Tree.at(IndexCurrentNote).LeftChild;
				}
				else
				{
					IndexCurrentNote = Tree.at(IndexCurrentNote).RightChild;
				}
			}
			temp.parent = ParentNote;
			Tree.push_back(temp);
			if (Tree.at(ParentNote).element>temp.element)
			{
				Tree.at(ParentNote).LeftChild = temp.add;
			}
			else
			{
				Tree.at(ParentNote).RightChild = temp.add;
			}
			int AVLNote=TreeHightRecorrect(temp.add, Tree);
			if (AVLNote!=-1)                 //发生了不平衡的点
			{
				reAVL(AVLNote, Tree);        //重新纠正
			}
		}
	}

	int IndexCurrentNote = 0;
	int ParentNote = 0;
	while (IndexCurrentNote != -1)
	{
		ParentNote = IndexCurrentNote;
		IndexCurrentNote = Tree.at(IndexCurrentNote).parent;
	}
	return  ParentNote;
}



bool postorderout(int root1, const vector<note> & Tree1)
{
	if (root1 == -1)
	{
		return false;
	}
	if (Tree1.empty())
	{
		return false;
	}
	vector<int> stack ;
	vector<int> result;
	stack.push_back(root1);
	stack.push_back(root1);
	while (!stack.empty())
	{
		int currentAdd = stack.at(stack.size()-1);
		stack.pop_back();
		if (!stack.empty())
		{
			if (currentAdd==stack.at(stack.size()-1)) //第一次经过 然后添加左右子树
			{
				if (Tree1.at(currentAdd).RightChild != -1)
				{
					stack.push_back(Tree1.at(currentAdd).RightChild);
					stack.push_back(Tree1.at(currentAdd).RightChild);
				}
				if (Tree1.at(currentAdd).LeftChild != -1)
				{
					stack.push_back(Tree1.at(currentAdd).LeftChild);
					stack.push_back(Tree1.at(currentAdd).LeftChild);
				}
			}
			else					 //第二次经过 输出
			{
				result.push_back(Tree1.at(currentAdd).element);
			}
		}
		else
		{
			result.push_back(Tree1.at(currentAdd).element);
		}
	}

	
	int it = 0;
	for (; it < result.size()-1; it++)
	{
		cout << result.at(it) << ' ';
	}
	cout << result.at(it);
}



int _tmain(int argc, _TCHAR* argv[])
{

	vector<note> FirstTree;
	int noteNuber = 0,rootNumber=0;
	cin >> noteNuber;

	rootNumber=GetTheTree(noteNuber, FirstTree);
	cout << FirstTree.at(rootNumber).element;

	system("pause");

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值