一、递归遍历O(n)
二、层次遍历O(n)
三、二叉搜索O(logn*logn)
参考网址:Count Number of Nodes in a Complete Binary Tree (Leetcode Problem Solution) (includehelp.com)
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<ctime>
#include<iomanip>
using namespace std;
struct TreeNode {
int val = 0;
TreeNode *left = NULL;
TreeNode *right = NULL;
};
//利用队列,生成的完全二叉树
void CreateTreeNode(TreeNode *root, int Num) {
queue<TreeNode *> Q;
Q.push(root);//根结点入队
int data = 1;//根的值为1
while (data < Num) {
TreeNode *curr_node = Q.front();//取队首元素
Q.pop();//队首出队
curr_node->left = new TreeNode;
curr_node->left->val = data++;
Q.push(curr_node->left);//左子树入队尾
curr_node->right = new TreeNode;
curr_node->right->val = data++;
Q.push(curr_node->right);//右子树入队尾
}
}
//利用队列,层次遍历二叉树,计数
int LevelOrderTraversal(TreeNode *root) {
queue<TreeNode *> Q;
int count = 0;
Q.push(root);//根节点入队
while (!Q.empty()) {//队不为空,则一直遍历
TreeNode *curr_node = Q.front();//取队首元素
cout << setw(4) << curr_node->val;//输出当前元素的值
Q.pop();//队首出队
count++;
if (curr_node->left) {//左子树不为空
Q.push(curr_node->left);//左子树入队尾
}
if (curr_node->right) {//同上
Q.push(curr_node->right);
}
}
return count;
}
//递归实现的遍历
//flag 1 2 3 对应于先序 中序 后序遍历
int RecursiveTraversal(const TreeNode *root) {
if (!root)
return 0;
return 1 + RecursiveTraversal(root->left) + RecursiveTraversal(root->right);
}
bool is_exists(TreeNode *root, int h, int no_of_nodes) {
TreeNode *cur = root;
int left = 1, right = pow(2, h);
//loop runs for h=O(logn) time
//binary search to find the
//no_of_nodes th node exist or not
for (int i = 0; i < h; ++i) {//一定要走完h层,到根节点
int mid = left + (right - left) / 2;
if (no_of_nodes <= mid) {
cur = cur->left;
right = mid;
} else {
cur = cur->right;
left = mid + 1;
}
}
//if no_of_nodes at last level exists
//then cur will point to that no_of_nodes th node
//else NULL
//指向最后一层,cur为空,不存在,不为空,则存在
return cur != NULL;
}
//since it's a complete tree we can traverse
//towards the left child always
//since the last level nodes will be as
//left as far possible,
// while循环直到最右边为空,即为树高
int height(TreeNode *root) {
if (!root)
return 0;
TreeNode *cur = root;
int count = 0;
while (cur) {
count++;
cur = cur->left;
}
return count;
}
//calculate number of nodes in
//the complete tree efficiently
int binary_search_countNodes(TreeNode *root) {
if (!root)
return 0;
else if (!root->left && !root->right)
return 1;
int h_except_last_level = height(root) - 1;
//number of nodes except the last level
//is calculated as follow
// 前h - 1 层节点都是满的,
int no_of_nodes_except_last_level = pow(2, h_except_last_level) - 1;
//number of possible nodes at the last level
//最后一层,数量在1 到 前面数量 + 1
int left = 1, right = no_of_nodes_except_last_level + 1;
//do binary search to check
//if predicted number of node exists or not
while (left <= right) {
int mid = left + (right - left) / 2;
//finds if last level has mid number of nodes or not
if (is_exists(root, h_except_last_level, mid)) {
left = mid + 1;
} else
right = mid - 1;
}//left 与right 相等后,再查找,left++,因此真实数量为right
return no_of_nodes_except_last_level + right;
}
// 所有的代码都需要写在 Algo 类内,自行定义其他需要的变量或函数
class Algo {
public:
Algo() {
cout << "algo ok" << endl;
}
int run(TreeNode *head) {
//在此写入你的代码
cout << "\n层次遍历计数:\t" << LevelOrderTraversal(head)
<< "\n递归遍历计数:\t" << RecursiveTraversal(head)
<< "\n二叉搜索计数:\t" << binary_search_countNodes(head)
<< '\n';
return 0; //修改为返回正确的结果
}
};
int main() {
Algo algo;
TreeNode head;
CreateTreeNode(&head, 100); //10 为生成的二叉树结点的数量,生成的二叉树为完全二叉树
time_t start = clock();
algo.run(&head);
time_t end = clock();
cout << "程序耗时: " << double(end - start) / CLOCKS_PER_SEC << " ms" << endl;
cout << "占用内存:" << sizeof(algo) << " byte" << endl;
return 0;
}