3.递归
在函数定义中,出现自己调用自己的情形,称为递归。
递归的特点:
自身调用:原问题可以分解为子问题,子问题的求解方法和原问题是一致的,即都是调用自身同一个函数。
终止条件:递归必须有一个终止条件,即不能无限的调用自身。
经典的递归例子,汉诺塔问题:
设于三根标号为A,B,C的柱子,在A柱上放着n个盘子,每个盘子都比下面的盘子小一些,要求把A柱上的盘子全部移动到C柱上。移动的规则为:
1.一次只能移动一个盘子;
2.移动过程中,大盘子不能放在小盘子上面;
3.在移动过程中,盘子可以放在A,B,C的任意一个柱子上。
递归存在的问题:
当递归调用的层级太多时,就可能超出栈的容量,从而导致栈溢出。
重复计算,导致程序效率低下。
#include <iostream>
using namespace std;
//求n的阶乘
int factorial(int n)
{
if (n == 1)
{
return 1;
}
return n * factorial(n - 1);
}
int sum = 0;
//求解汉诺塔问题
void move(char m, char n)
{
cout << m << "---->" << n << endl;
sum++;
}
void hanoi(int n, char a, char b, char c)
{
//借助b柱,将n个盘子从a柱移动到c柱
if (n == 1)
{
move(a, c);
}
else
{
hanoi(n - 1, a, c, b);//借助c柱,将前n-1个盘子从a柱移动到b柱
move(a, c);//将剩下的n号盘子从a柱移动到c柱
hanoi(n - 1, b, a, c);//借助a柱,将前n-1个盘子从b柱移动到c柱
}
}
int main()
{
//cout << "5的阶乘是:" << factorial(5) << endl;
int n;
cout << "请输入盘子个数:";
cin >> n;
cout << "移动" << n << "个盘子的过程:" << endl;
hanoi(n, 'A', 'B', 'C');
cout << "总共运行:" << sum << endl;
return 0;
}
4.受限线性表
4.1栈(stack)
栈是一种特殊的线性表,只能在栈顶进行插入和删除操作,一般不能遍历数据。先进后出(FILO)
栈的应用:
所有的编译器(解释器)都有检测括号是否匹配的功能,如何检测呢?
例如,有如下字符串“6x(5+(3x(5-2)))”
要求,写一个函数,利用链式栈来判断字符串中小括号是否匹配
算法思路:
遍历字符串,碰到普通字符,忽略,当碰到左括号时入栈,碰到右括号时出栈,遍历完整个字符串后,如果栈为空,则说明匹配,否则不匹配。
设计一个栈的数据结构,用来计算一个逆波兰式。
算法思路:
遍历字符串碰到数字入栈,碰到符号,先从栈中弹出右操作数,再从栈中弹出左操作数,然后根据符号进行运算,再把运算结果入栈。。。。直到字符串遍历完毕。最后栈中唯一的数字即为结果。
顺序栈:
#pragma once
#define MAX_SIZE 512
class SeqStack
{
private:
int* data;
int size;
public:
SeqStack();
~SeqStack();
//入栈
void push(int value);
void pop(); //出栈
int getSize();//返回栈大小
int top();//返回栈顶元素
bool isEmpty();//判断栈是否为空
void clear();// 清空栈
};
//.c
#include <iostream>
#include "seqStack.h"
using namespace std;
SeqStack::SeqStack()
{
data = new int[MAX_SIZE];
size = 0;
}
SeqStack::~SeqStack()
{
if (data != nullptr)
{
delete[]data;
data = nullptr;
}
}
void SeqStack::push(int value)
{
if (size == MAX_SIZE)
{
return;
}
data[size] = value;
size++;
}
void SeqStack::pop()
{
if (size > 0)
{
size--;
}
}
int SeqStack::getSize()
{
return size;
}
int SeqStack::top()
{
if (size > 0)
{
return data[size - 1];
}
return NULL;
}
bool SeqStack::isEmpty()
{
if (size == 0)
{
return true;
}
else
{
return false;
}
// return size == 0;
}
void SeqStack::clear()
{
size = 0;
}
void test_seqstack()
{
SeqStack seqstack;
cout << "栈的大小为:" << seqstack.getSize() << endl;
cout << "栈是否为空:" << seqstack.isEmpty() << endl;
for (int i = 0; i < 8; i++)
{
seqstack.push(i + 50);
}
cout << "栈的大小为:" << seqstack.getSize() << endl;
cout << "栈是否为空:" << seqstack.isEmpty() << endl;
cout << "栈顶的元素为:" << seqstack.top() << endl;
}
链式栈:
解决栈内字符串内的括号是否匹配;计算逆波兰式
#pragma once
class LinkStackNode
{
public:
int data;
LinkStackNode* next;
public:
LinkStackNode();
LinkStackNode(int value);
};
class LinkStack
{
private:
LinkStackNode* head;
int size;
public:
LinkStack();
~LinkStack();
void push(int value);//入栈
void pop();//出栈
int getSize();//返回栈的大小
int top();//返回栈顶元素
bool isEmpty();//判断栈是否为空
void clear();//清空栈
};
//.c
#include <iostream>
#include "linkStack.h"
using namespace std;
LinkStackNode::LinkStackNode()
{
data = NULL;
next = nullptr;
}
LinkStackNode::LinkStackNode(int value)
{
data = value;
next = nullptr;
}
LinkStack::LinkStack()
{
head = new LinkStackNode();
size = 0;
}
LinkStack::~LinkStack()
{
LinkStackNode* curr = head;
LinkStackNode* temp = nullptr;
while (curr != nullptr)
{
temp = curr;
curr = curr->next;
delete temp;
}
}
void LinkStack::push(int value)
{
//新建节点
LinkStackNode* newNode = new LinkStackNode(value);
//新节点插在最前面
newNode->next = head->next;
head->next = newNode;
size++;
}
void LinkStack::pop()
{
if (size > 0)
{
//删除第一个节点
LinkStackNode* temp = head->next;
head->next = temp->next;
delete temp;
size--;
}
}
int LinkStack::getSize()
{
return size;
}
int LinkStack::top()
{
if (size > 0)
{
return head->next->data;
}
return NULL;
}
bool LinkStack::isEmpty()
{
return size == 0;
}
void LinkStack::clear()
{
while (size > 0)
{
pop();
}
}
void text_linkstack()
{
LinkStack* ls = new LinkStack();
cout << "栈大小为:" << ls->getSize() << endl;
cout << "栈是否为空:" << ls->isEmpty() << endl;
for (int i = 0; i < 8; i++)
{
ls->push(i + 50);
}
cout << "栈大小为:" << ls->getSize() << endl;
cout << "栈是否为空:" << ls->isEmpty() << endl;
cout << "栈顶元素为:" << ls->top() << endl;
ls->pop();
ls->pop();
ls->pop();
cout << "栈顶元素为:" << ls->top() << endl;
}
//判断括号是否匹配
bool match(string s)
{
LinkStack* ls = new LinkStack();
for (int i = 0; i < s.length(); i++)
{
if (s[i] == '(')
{
ls->push(s[i]);
}
else if (s[i] == ')')
{
if (ls->isEmpty())
{
return false;
}
else
{
ls->pop();
}
}
}
return ls->isEmpty();
}
void test_match()
{
string str1 = "6s(8i()8c())";
if (match(str1))
{
cout << "小括号匹配" << endl;
}
else
{
cout << "小括号不匹配" << endl;
}
}
//逆波兰式
int suffix_compute(string s)
{
LinkStack ls;
for (int i = 0; i < s.size(); i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
ls.push((s[i] - '0'));
cout << ls.top() << endl;
}
else
{
int n = ls.top();//右值
ls.pop();
int m = ls.top();//左值
ls.pop();
int m_n = 1;
if (s[i] == '+')
{
m_n = m + n;
}
if (s[i] == '-')
{
m_n = m - n;
}
if (s[i] == '*')
{
m_n = m * n;
}
if (s[i] == '/')
{
m_n = m / n;
}
ls.push(m_n);
}
}
return ls.top();
}
void test_suffix_compute()
{
string str1 = "831-5*+";
cout << "计算结果为:" << suffix_compute(str1) << endl;
}
4.2队列(queue)
队列是另外一种特殊的线性表,只允许在一端进行插入操作,而在另一端进行删除操作,允许插入的一端称为队尾,,允许删除的一段称为队头。先进先出(FIFO)
顺序队列:
//SeqQueue.h
#pragma once
#define MAX_SIZE 512
class SeqQueue
{
private:
int* data;
int size;
public:
SeqQueue();
~SeqQueue();
void push(int value);//从队尾入队
void pop();// 出队,从队头出
int getSize();
int front();
int back();
bool isEmpty();
void clear();//清空
};
//SeqQueue.c
#include <iostream>
#include"seqQueue.h"
using namespace std;
SeqQueue::SeqQueue()
{
data = new int[MAX_SIZE];
size = 0;
}
SeqQueue::~SeqQueue()
{
if (data != nullptr)
{
delete[]data;
data = nullptr;
}
}
void SeqQueue::push(int value)
{
if (size == MAX_SIZE)
{
return;
}
data[size++] = value;
}
void SeqQueue::pop()
{
if (size > 0)
{
for (int i = 0; i < size - 1 ; i++)
{
data[i] = data[i + 1];
}
size--;
}
}
int SeqQueue::getSize()
{
return size;
}
int SeqQueue::front()
{
if (size > 0)
{
return data[0];
}
return NULL;
}
int SeqQueue::back()
{
if (size > 0)
{
return data[size - 1];
}return NULL;
}
bool SeqQueue::isEmpty()
{
return size == 0;
}
void SeqQueue::clear()
{
size = 0;
}
void test_seqqueue()
{
SeqQueue* seq = new SeqQueue;
cout << "队列的大小为:" << seq->getSize() << endl;
cout << "队列是否为空:" << seq->isEmpty() << endl;
for (int i = 0; i < 8; i++)
{
seq->push(i + 70);
}
cout << "队列的大小为:" << seq->getSize() << endl;
cout << "队列是否为空:" << seq->isEmpty() << endl;
cout << "队头元素:" << seq->front() << endl;
cout << "队尾元素:" << seq->back() << endl;
seq->pop();
seq->pop();
cout << "队头元素:" << seq->front() << endl;
cout << "队列的大小为:" << seq->getSize() << endl;
seq->clear();
cout << "队列的大小为:" << seq->getSize() << endl;
}
链式队列:
练习:设计一个队列,用来解决约瑟夫问题。
//LinkQueue.h
#pragma
class LinkQueueNode
{
public:
int data;
LinkQueueNode* next;
public:
LinkQueueNode();
LinkQueueNode(int value);
};
class linkQueue
{
private:
int size;
LinkQueueNode* head;
public:
linkQueue();
~linkQueue();
void push(int value);
void pop();
int getSize();
int back();
int front();
int top();
bool isEmpty();
void clear();
};
//LinkQueue.c
#include <iostream>
#include "linkQueue.h"
using namespace std;
LinkQueueNode::LinkQueueNode()
{
data = NULL;
next = nullptr;
}
LinkQueueNode::LinkQueueNode(int value)
{
data = value;
next = nullptr;
}
linkQueue::linkQueue()
{
size = 0;
head =new LinkQueueNode();
}
linkQueue::~linkQueue()
{
LinkQueueNode* curr = head;
LinkQueueNode* temp = nullptr;
while (curr != nullptr)
{
temp = curr;
curr = curr->next;
delete temp;
}
}
void linkQueue::push(int value)
{
LinkQueueNode* newNode = new LinkQueueNode(value);
LinkQueueNode* curr = head;
while (curr->next != nullptr)
{
curr = curr->next;
}
curr->next = newNode;
size++;
}
int linkQueue::getSize()
{
return size;
}
void linkQueue::pop()
{
if (size == 0)
{
return;
}
LinkQueueNode* temp = head->next;
head->next = temp->next;
delete temp;
size--;
}
int linkQueue::back()
{
if (size == 0)
{
return NULL;
}
LinkQueueNode* curr = head;
while (curr->next != nullptr)
{
curr = curr->next;
}
return curr->next->data;
}
int linkQueue::front()
{
return head->next->data;
}
bool linkQueue::isEmpty()
{
return size == 0;
}
void test_linkqueue()
{
linkQueue lk;
for (int i = 0; i < 8; i++)
{
lk.push(i + 20);
}
cout << lk.getSize() << endl;
}
//约瑟夫问题
void test_yuesefu()
{
linkQueue* lk = new linkQueue;
for (int i = 0; i < 8; i++)
{
lk->push(i);
}
int n = 8;
int m = 3;
while (!lk->isEmpty())
{
for (int i = 1; i < 5; i++)
{
int temp = lk->front();
lk->pop();
lk->push(temp);
}
cout << lk->front() << " ";
lk->pop();
}
delete[]lk;
}
5.树
5.1树的基本概念
定义:由零个或者多个(n>=0)节点组成的有限集合,有且仅有一个节点称为根(root),当n>1时,其余节点可以分为m个互不相交的有限集合。每个集合本身又是一棵树,称为这个根的子树。
特点:非线性结构,,每个节点(除了根之外)都有一个直接前驱,但是有可能有多个直接后继;
树的定义具有递归性,树中还有树;
树可以为空,即节点个数为0。
树的术语: 根(root):即根节点,没有前驱;
叶子(leaf):即终端节点,没有后继;
双亲(parent):即节点的直接前驱;
孩子(child):即节点的直接后继;
兄弟(sibling):同一个双亲下的节点;
堂兄弟(cousin):双亲为兄弟的节点;
节点的度:节点下挂接的子树个数
树的度:树中节点度的最大值
节点的层数:从根开始到该节点的层数(根为第一层)
树的深度(高度):树中所有节点的最大层数
5.2二叉树
定义:n(n>=0)个节点的有限集合,由一个根节点以及最多两个互不相交的子树组成,也就是度为2的树。
二叉树的性质:
在二叉树的第i层上最多有2^i-1^个节点;
深度为k的二叉树上最多有2^k^-1个节点。
满二叉树:每一层都充满了节点,除了叶子之外的所有节点的度都是2。
深度为k的满二叉树上的节点个数为2^k^-1。
完全二叉树:除了最后一层,每一层上的节点数均达到最大值,在最后一层上只缺少右边的若干节点。
特点:高度为k的完全二叉树,k-1层是满二叉树,第k层上的节点都靠左
性质:对于一颗完全二叉树,如果从上到下,从左到右,给树中节点编号,根节点编号为0的话,则编号为i的节点,其左孩子编号为2i+1,右孩子编号为2i+2,双亲编号为(i-1)/2
练习:
计算一颗二叉树叶子节点的个数
计算一颗二叉树的高度
//binaryTree.h
#pragma once
class BinaryTreeNode
{
public:
int data;
BinaryTreeNode* left;
BinaryTreeNode* right;
public:
BinaryTreeNode();
BinaryTreeNode(int value);
};
//binaryTree.c
#include <iostream>
#include"binaryTree.h"
using namespace std;
BinaryTreeNode::BinaryTreeNode()
{
data = NULL;
left = nullptr;
right = nullptr;
}
BinaryTreeNode::BinaryTreeNode(int value)
{
data = value;
left = nullptr;
right = nullptr;
}
BinaryTreeNode* createBinaryTree()
{
BinaryTreeNode* a = new BinaryTreeNode(1);
BinaryTreeNode* b = new BinaryTreeNode(2);
BinaryTreeNode* c = new BinaryTreeNode(3);
BinaryTreeNode* d = new BinaryTreeNode(4);
BinaryTreeNode* e = new BinaryTreeNode(5);
BinaryTreeNode* f = new BinaryTreeNode(6);
BinaryTreeNode* g = new BinaryTreeNode(7);
BinaryTreeNode* h = new BinaryTreeNode(8);
BinaryTreeNode* i = new BinaryTreeNode(9);
BinaryTreeNode* j = new BinaryTreeNode(10);
a->left = b;
a->right = c;
b->left = d;
b->right = e;
c->left = f;
c->right = g;
d->left = h;
d->right = i;
e->left = j;
return a;
}
//先序遍历:根->左子树->右子树
void preOrder(BinaryTreeNode* root)
{
if (root == nullptr)
{
return;
}
cout << root->data << " ";
preOrder(root->left);//递归遍历左子树
preOrder(root->right);//递归遍历右子树
}
//中序遍历: 左子树->根->右子树
void inOrder(BinaryTreeNode* root)
{
if (root == nullptr)
{
return;
}
inOrder(root->left);//递归遍历左子树
cout << root->data << " ";
inOrder(root->right);//递归遍历右子树
}
//后序遍历:左子树->右子树->根
void postOrder(BinaryTreeNode* root)
{
if (root == nullptr)
{
return;
}
postOrder(root->left);//递归遍历左子树
postOrder(root->right);//递归遍历右子树
cout << root->data << " ";
}
//计算二叉树的叶子节点
int calculateLeafNum(BinaryTreeNode* root)
{
if (root == nullptr)
{
return 0;
}
else if (root->left== nullptr && root->right == nullptr)
{
return 1;
}
return calculateLeafNum(root->left) + calculateLeafNum(root->right);
}
//计算二叉树的高度
int binaryTree_height(BinaryTreeNode* root)
{
if (root == nullptr)
{
return 0;
}
/*if (root->left != nullptr)
{
return 1;
}
if (root->right != nullptr)
{
return 1;
}*/
return ((binaryTree_height(root->left) > binaryTree_height(root->right)) ? binaryTree_height(root->left) : binaryTree_height(root->right))+ 1 ;
}
int main()
{
BinaryTreeNode* root = createBinaryTree();
cout << "先序遍历:";
preOrder(root);
cout << endl;
cout << "中序遍历:";
inOrder(root);
cout << endl;
cout << "后序遍历:";
postOrder(root);
cout << endl;
cout << "此二叉树的叶子节点的个数为:" << calculateLeafNum(root) << endl;
cout << "此二叉树的高度为: " << binaryTree_height(root) << endl;
return 0;
}
5.3二叉搜索树
一颗二叉树的左子树上的节点都小于树根,右子树的节点都大于树根,对于任意一个节点及其子树,均要满足此要求。这样的树,称为二叉搜索树,亦称二叉排序树。
对于一颗二叉搜索树进行中序遍历的话,其结果为一个有序序列。
如何构建一颗二叉搜索树?
给一个序列,7 4 5 6 1 8 9,用来构建一颗二叉搜索树。
在一颗二叉搜索树上进行查找操作,最大查找次数,就是树的深度,类似于折半查找,每次都排除一半的树。
//binarySearchTree.h
#pragma once
class BinarySearchTreeNode
{
public:
int data;
BinarySearchTreeNode* left;
BinarySearchTreeNode* right;
public:
BinarySearchTreeNode();
BinarySearchTreeNode(int value);
};
//binarySearchTree.c
#include <iostream>
#include"binarySearchTree.h"
using namespace std;
BinarySearchTreeNode::BinarySearchTreeNode()
{
data = NULL;
left = nullptr;
right = nullptr;
}
BinarySearchTreeNode::BinarySearchTreeNode(int value)
{
data = value;
left = nullptr;
right = nullptr;
}
//先序遍历:根->左子树->右子树
void preOrder(BinarySearchTreeNode* root)
{
if (root == nullptr)
{
return;
}
cout << root->data << " ";
preOrder(root->left);//递归遍历左子树
preOrder(root->right);//递归遍历右子树
}
//中序遍历: 左子树->根->右子树
void inOrder(BinarySearchTreeNode* root)
{
if (root == nullptr)
{
return;
}
inOrder(root->left);//递归遍历左子树
cout << root->data << " ";
inOrder(root->right);//递归遍历右子树
}
//后序遍历:左子树->右子树->根
void postOrder(BinarySearchTreeNode* root)
{
if (root == nullptr)
{
return;
}
postOrder(root->left);//递归遍历左子树
postOrder(root->right);//递归遍历右子树
cout << root->data << " ";
}
//构建二叉搜索树,不用返回值
void addNode(BinarySearchTreeNode*& root, int value)
{
if (root == nullptr)
{
root = new BinarySearchTreeNode(value);
}
if (root->data > value)
{
addNode(root->left, value);//添加左子树
}
if (root->data < value)
{
addNode(root->right, value);//添加右子树
}
}
//构建二叉搜索树,有返回值
BinarySearchTreeNode* addNode2(BinarySearchTreeNode* root, int value)
{
if (root == nullptr)
{
root = new BinarySearchTreeNode(value);
}
else if (root->data > value)
{
root->left = addNode2(root->left, value);//添加左子树
}
else if (root->data < value)
{
root->right = addNode2(root->right, value);//添加右子树
}
return root;
}
// 构建二叉搜索树,非递归函数
void addNode3(BinarySearchTreeNode* root, int value)
{
//新建节点
BinarySearchTreeNode* newNode = new BinarySearchTreeNode(value);
BinarySearchTreeNode* temp = root;
while (temp != nullptr)
{
if (temp->data > value)//左插
{
if (temp->left == nullptr)
{
temp->left = newNode;
return;
}
else
{
temp = temp->left;
}
}
else if (temp->data < value)//右插
{
if (temp->right == nullptr)
{
temp->right = newNode;
return;
}
else
{
temp = temp->right;
}
}
}
}
void test_addnode()
{
int a[] = { 7,4,5,6,1,8,9 };
int lenght = sizeof(a) / sizeof(a[0]);
BinarySearchTreeNode* root = nullptr;
for (int i = 0; i < lenght; i++)
{
addNode(root, a[i]);
}
inOrder(root);
}
void test_addnode2()
{
int a[] = { 7,4,5,6,1,8,9 };
int lenght = sizeof(a) / sizeof(a[0]);
BinarySearchTreeNode* root = nullptr;
for (int i = 0; i < lenght; i++)
{
root = addNode2(root, a[i]);
}
inOrder(root);
}
void test_addnode3()
{
int a[] = { 7,4,5,6,1,8,9 };
int lenght = sizeof(a) / sizeof(a[0]);
BinarySearchTreeNode* root = new BinarySearchTreeNode(a[0]);
for (int i = 1; i < lenght; i++)
{
addNode3(root, a[i]);
}
inOrder(root);
}
// 在二叉树上查找节点
bool searchBinaryTree(BinarySearchTreeNode* root , int value)
{
cout << "=====查找=====" << endl;
static int sum = 0;
sum++;
cout << "查找次数为:" << sum << endl;
if (root == nullptr)
{
return false;
}
if (root->data == value)
{
return true;
}
if (root->data > value)
{
return searchBinaryTree(root->left, value);
}
if (root->data < value)
{
return searchBinaryTree(root->right, value);
}
return sum;
}
void test_search()
{
int a[] = { 7,4,5,6,1,8,9 };
int lenght = sizeof(a) / sizeof(a[0]);
BinarySearchTreeNode* root = nullptr;
for (int i = 0; i < lenght; i++)
{
addNode(root, a[i]);
}
if (searchBinaryTree(root, 10))
{
cout << " 找到了";
}
else
{
cout << "找不到";
}
cout << endl;
}
//计算二叉树的高度
int binaryTree_height(BinarySearchTreeNode* root)
{
if (root == nullptr)
{
return 0;
}
return ((binaryTree_height(root->left) > binaryTree_height(root->right)) ? binaryTree_height(root->left) : binaryTree_height(root->right)) + 1;
}
5.4平衡二叉树
二叉搜索树的优点就是查找效率很高,但是在某些极端情况下,例如给一个序列,1 2 3 4 5 6 7,用次序列构建的二叉搜索树将退化成一个线性表,其查找时间复杂度将变为O(n),因此我们需要将这种二叉搜索树调整为平衡二叉树。
平衡二叉树:是一颗空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。
平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 最小二叉平衡树的节点总数的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci(斐波那契)数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。
判断一颗二叉树是否是平衡二叉树
//判断一颗二叉树是否是平衡二叉树
bool isBanlanced(BinarySearchTreeNode* root)
{
if (root == nullptr)
{
return true;
}
int heiht_left = binaryTree_height(root->left);
int heihet_right = binaryTree_height(root->right);
if (abs(heihet_right - heiht_left) > 1)
{
return false;
}
/*if (abs(binaryTree_height(root->left) - binaryTree_height(root->right)) < 1)
{
return true;
}
else
{
return false;
}*/
return isBanlanced(root->left) && isBanlanced(root->right);
}
void test_isbalanced()
{
int a[] = { 7,4,5,6,1,8,9 };
//int a[] = { 1,2,3 };
int lenght = sizeof(a) / sizeof(a[0]);
BinarySearchTreeNode* root = nullptr;
for (int i = 0; i < lenght; i++)
{
addNode(root, a[i]);
}
if (isBanlanced(root))
{
cout << "这棵树是平衡二叉树" << endl;
}
else
{
cout << "这棵树不是平衡二叉树" << endl;
}
}