在学习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;
}