一、前言
《二叉查找樹全面詳細介紹》中講解了二叉樹操作:搜索(查找)、遍歷、插入、刪除。《二叉樹遍歷詳解(遞歸遍歷、非遞歸棧遍歷,Morris遍歷)》詳細講解了二叉樹遍歷的幾種方法。本文介紹一種二叉樹平衡構建方法。
二、思路
根據二叉樹插入的規則,我們只需要按照正確順序將元素添加到二叉樹中,就可以構建一顆平衡二叉樹了。
三、總結
該方法需要額外空間記錄樹中所有元素,並對其排序,這個構建過程效率不高,且需要額外空間,當構建好平衡二叉樹之後,如果需要添加元素,是無法直接添加,需要刪除樹,重新構建纔行。
後面文章中會介紹幾種更好構建平衡二叉樹的方法。
四、編碼實現
二叉樹BST<T>代碼見《二叉查找樹全面詳細介紹》有完整代碼。
//==========================================================================
/**
* @file : BalanceBST.h
* @blogs :
* @author : niebingyu
* @title : 平衡二叉樹
* @purpose : 將一組元素,通過排序之後,通過插入構建一顆平衡二叉樹
*/
//==========================================================================
#pragma once
#include "GenBST.h"
#include <algorithm>
template<class T>
class BalanceBST : private BST<T>
{
public:
// 平衡二叉樹,通過插入讓樹滿足平衡,只適合樹的重建,不能中途插入節點
void createBalanceBST(T*, int);
// 前序遍歷二叉樹
void preorder() { BST<T>::preorder(); }
// 中序遍歷
void inorder() { BST<T>::inorder(); }
private:
// 平衡二叉樹,通過插入讓樹滿足平衡,只適合樹的重建,不能中途插入節點
void balance(T data[], int first, int last);
};
// 平衡二叉樹
template<class T>
void BalanceBST<T>::createBalanceBST(T* data, int len)
{
// 先將樹清空
BST<T>::clear();
std::sort(data, data+len);
balance(data, 0, len-1);
}
template<class T>
void BalanceBST<T>::balance(T data[], int first, int last)
{
if (first <= last)
{
int middle = (first + last) / 2;
BST<T>::insert(data[middle]);
balance(data, first, middle - 1);
balance(data, middle + 1, last);
}
}
測試代碼
//==========================================================================
/**
* @file : BalanceBSTTest.h
* @blogs : https://blog.csdn.net/nie2314550441/article/details/107092408
* @author : niebingyu
* @title : 測試平衡二叉樹
* @purpose : 測試平衡二叉樹
*
*/
//==========================================================================
#pragma once
#include "BalanceBST.h"
using namespace std;
#define NAMESPACE_BALANCEBSTTEST namespace NAME_BALANCEBSTTEST {
#define NAMESPACE_BALANCEBSTTESTEND }
NAMESPACE_BALANCEBSTTEST
// 測試用例
void Test1()
{
vector<int> data = { 2,1,3,4,7,5,6,9,0,8 };
BalanceBST<int> tree;
tree.createBalanceBST(data.data(), data.size());
cout << "Test1 前序遍歷: ";
tree.preorder();
cout << "\nTest1 中序遍歷: ";
tree.inorder();
cout << endl;
}
NAMESPACE_BALANCEBSTTESTEND
void BalanceBSTTest_Test()
{
NAME_BALANCEBSTTEST::Test1();
}
執行結果: