AVL 트리 삽입을 구현하는 데 다음 코드를 사용하고 있지만 적절한 순서로 표시하지 않거나 높이를 업데이트하지 못했습니다. 삽입 기능이 완료되면 해당 기능을 완료 할 수 있기 때문에 일부 기능이 남아 있습니다.AVL 트리 재귀없이 삽입 C++
AVLNode.cpp
#include <iostream>
#include <string>
#include "AVLNode.h"
using namespace std;
AVLNode::AVLNode(string ss, string na){
ssn = ss;
name = na;
height = 0;
left = NULL;
right = NULL;
parent = NULL;
}
AVLNode.h
#include <iostream>
#include <string>
using namespace std;
struct AVLNode{
string ssn;
string name;
AVLNode *left;
AVLNode *right;
AVLNode *parent;
int height;
AVLNode(string ss, string na);
};
AVLTree.cpp
#include <iostream>
#include <string>
#include <stdio.h>
#include "AVLTree.h"
#include <iomanip>
#include <queue>
using namespace std;
AVLTree::AVLTree(){
root = NULL;
}
AVLTree::~AVLTree(){
}
AVLNode* AVLTree::getRoot(){
return root;
}
// search value ss in the AVL tree
bool AVLTree::find(string ss){
if (root == NULL) {
return false;
}
AVLNode* node = root;
while (node != NULL) {
if (ss.compare(node->ssn) == 0) {
return true;
}
if (ss.compare(node->ssn) < 0) {
node = node->left;
}
else{
node = node->right;
}
}
return false;
}
// return the height of the subtree rooted at node
// if subtree is empty, height is -1
// if subtree has one node, height is 0
int AVLTree::height(AVLNode* node){
if(node != NULL){
return node->height;
}
else{
return -1;
}
}
// return the balance factor of the node
int AVLTree::balanceFactor(AVLNode* node){
return height(node->left) - height(node->right);
}
// update the height of the node
// this should be done whenever the tree is modified
void AVLTree::updateHeight(AVLNode* node){
int hl = height(node->left);
int hr = height(node->right);
node->height = (hl > hr ? hl : hr) + 1;
}
// rotate right the subtree rooted at node
// return the new root of the subtree
AVLNode* AVLTree::rotateRight(AVLNode* node){
AVLNode* lp = node->left; // left child of node
if (node->parent != NULL) { // node is not root
if (node->parent->left == node) { // node is a left child
node->parent->left = lp;
}else{
node->parent->right = lp; // node is a right child
}
}
if (lp->right != NULL) { // pointer update
lp->right->parent = node;
}
lp->parent = node->parent;
node->left = lp->right;
lp->right = node;
node->parent = lp;
updateHeight(node); // after rotation, update height
updateHeight(lp); // after rotation, update height
if (node == root) {
root = lp;
}
return lp; // lp is the new root of the subtree
}
// rotate left the subtree rooted at node
// return the new root of the subtree
AVLNode* AVLTree::rotateLeft(AVLNode* node){
AVLNode* rp = node->right;
if (node->parent!=NULL) {
if (node->parent->left == node) {
node->parent->left = rp;
}else{
node->parent->right = rp;
}
}
if (rp->left != NULL) {
rp->left->parent = node;
}
rp->parent = node->parent;
node->right = rp->left;
rp->left = node;
node->parent = rp;
node->parent = rp;
updateHeight(node);
updateHeight(rp);
if (node == root) {
root = rp;
}
return rp;
}
// rebalance a tree rooted at node
// return the new root of the subtree
AVLNode* AVLTree::balance(AVLNode* node){
updateHeight(node);
if (balanceFactor(node) == 2) {
if (balanceFactor(node->left) < 0) {
node->left = rotateLeft(node->left); // for left right case
}
AVLNode* temp = rotateRight(node);
updateHeight(temp);
return temp;
}
if (balanceFactor(node) == -2) {
if (balanceFactor(node->right) > 0) {
node->right = rotateRight(node->right); // for right left case
}
AVLNode* temp2 = rotateLeft(node);
updateHeight(temp2);
return temp2;
}
return node;
}
// insert a new node with (ss, na) to the AVL tree
// if there exists ss value, return false
// otherwise, insert it, balance the tree, return true
bool AVLTree::insert(string ss, string na){
AVLNode *newNode=new AVLNode(ss,na);
AVLNode *Iterator;
if(root==NULL){
cout<<"Root Node Inserted"<<endl;
root=newNode;
} else {
Iterator = root;
int rootTempValue = atoi((Iterator->ssn).c_str());
int addTempValue = atoi((newNode->ssn).c_str());
if(rootTempValue <= addTempValue ){
// Right Portion of the tree
while(Iterator->right != NULL){
cout << "In the Right portion" <<endl;
int rootTempValue2 = atoi((Iterator->right->ssn).c_str());
int addTempValue2 = atoi((newNode->ssn).c_str()) ;
if(rootTempValue2 <= addTempValue2)
Iterator = Iterator->right;
else
Iterator = Iterator->left;
//Iterator = Iterator->right;
}
Iterator->right = newNode ;
newNode->parent = Iterator ;
} else {
// Left Portion of the tree
while(Iterator->left != NULL){
//Iterator = Iterator->left;
int rootTempValue2 = atoi((Iterator->left->ssn).c_str());
int addTempValue2 = atoi((newNode->ssn).c_str()) ;
if(rootTempValue2 <= addTempValue2)
Iterator = Iterator->right;
else
Iterator = Iterator->left;
}
newNode->parent = Iterator;
newNode->right = NULL ;
newNode->left = NULL;
Iterator->left = newNode ;
cout << "In the left portion : " <<Iterator->left->ssn<<endl;
}
}
balance(newNode);
updateHeight(newNode);
return true;
}
AVLNode* AVLTree::maxOfSubtree(AVLNode* node){
if (node == NULL) {
return NULL;
}
while (node->right != NULL) {
node = node->right;
}
return node;
}
// delete the node containing value ss
// if there is not such node, return false
// otherwise, delete the node, balance the tree, return true
bool AVLTree::deleteNode(string ss){
// please implement here
return true;
}
// internal function
// do not call it directly
void AVLTree::print(AVLNode* x, int indent){
if(x == NULL)
return;
if (x->right != NULL) {
print(x->right, indent+4);
}
if (indent != 0) {
cout << std::setw(indent) << ' ';
}
if(x->right != NULL){
cout << " /\n" << std::setw(indent) << ' ';
}
cout << x->ssn << endl;
if (x->left != NULL) {
cout << std::setw(indent) << ' ' <<" \\\n";
print(x->left, indent+4);
}
}
// print out the structure of the binary tree
// use it for debugging, I love this function
void AVLTree::print(){
int count = 0;
print(root, count);
}
// it does not level order traversal
// it prints out the number of node
// use it mainly for debugging
void AVLTree::levelOrder(){
// please implement it
}
MAIN.CPP는
#include <iostream>
#include "AVLTree.h"
int main(int argc, char** argv) {
AVLTree temp;
temp.insert("05", "a");
temp.insert("04", "b");
temp.insert("09", "c");
//temp.insert("03", "d");
//temp.insert("06", "d");
// temp.insert("07", "d");
//temp.insert("02", "d");
temp.print();
cout<<endl;
cout<<"The Height Of The Tree is :" << temp.height(temp.getRoot())<<endl;
cin.get();
return 0;
}
일부 의견 : 'AVLTree.h'는 질문에 없습니다. 'AVLTree'의 소멸자는 트리가 소유 한 노드를 삭제해야합니다. 이러한 클래스를 디버깅하려면 내부 구조가 일관성이 있는지 테스트하는 bool invariant() const' 메서드를 추가하면됩니다. 그런 다음 삽입 전후에 호출하여 삽입이 불변 형을 깨뜨리는 것을 감지 할 수 있습니다. 그런 다음 디버거를 사용하여보다 효율적으로 디버깅 할 수 있습니다. – Franck
당신은 내가 그것을 테스트하는 방법을 확인할 수있는 함수를 작성할 수 있습니까 –
나는 대답으로 그것을 작성했습니다. 테스트되지 않았기 때문에 컴파일 오류를 수정할 가능성이 있습니다. – Franck