This part is the CPP implementation of 日撸 Java 三百行(21-30天,树与二叉树).
实现一个 BinaryCharTree 类, 并手动构建一个二叉树. 使用递归实现二叉树的前序遍历、中序遍历、后序遍历. 使用递归实现获取二叉树的层数、节点数函数.
#include
class BinaryCharTree
{
public:
char value;
BinaryCharTree* left_child;
BinaryCharTree* right_child;
BinaryCharTree()
{
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char name)
{
this->value = name;
this->left_child = NULL;
this->right_child = NULL;
}
void pre_order_visit()
{
std::cout << this->value << " ";
if (this->left_child != NULL) this->left_child->pre_order_visit();
if (this->right_child != NULL) this->right_child->pre_order_visit();
}
void in_order_visit()
{
if (this->left_child != NULL) this->left_child->in_order_visit();
std::cout << this->value << " ";
if (this->right_child != NULL) this->right_child->in_order_visit();
}
void post_order_visit()
{
if (this->left_child != NULL) this->left_child->post_order_visit();
if (this->right_child != NULL) this->right_child->post_order_visit();
std::cout << this->value << " ";
}
int get_depth()
{
if (this->left_child == NULL && this->right_child == NULL)
{
return 1;
}
int temp_left_depth = 0;
if (this->left_child != NULL) temp_left_depth = this->left_child->get_depth();
int temp_right_depth = 0;
if (this->right_child != NULL) temp_right_depth = this->right_child->get_depth();
return 1 + std::max(temp_left_depth, temp_right_depth);
}
int get_num_nodes()
{
if (this->left_child == NULL && this->right_child == NULL) return 1;
int temp_left_nodes = 0;
if (this->left_child != NULL) temp_left_nodes = this->left_child->get_num_nodes();
int temp_right_nodes = 0;
if (this->right_child != NULL) temp_right_nodes = this->right_child->get_num_nodes();
return temp_left_nodes + temp_right_nodes + 1;
}
};
BinaryCharTree* manual_construct_tree()
{
BinaryCharTree* tree = new BinaryCharTree('a');
BinaryCharTree* treeB = new BinaryCharTree('b');
BinaryCharTree* treeC = new BinaryCharTree('c');
BinaryCharTree* treeD = new BinaryCharTree('d');
BinaryCharTree* treeE = new BinaryCharTree('e');
BinaryCharTree* treeF = new BinaryCharTree('f');
BinaryCharTree* treeG = new BinaryCharTree('g');
tree->left_child = treeB;
tree->right_child = treeC;
treeB->right_child = treeD;
treeC->left_child = treeE;
treeD->left_child = treeF;
treeD->right_child = treeG;
return tree;
}
int main()
{
BinaryCharTree* tree = manual_construct_tree();
std::cout << "Preorder visit: ";
tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
tree->post_order_visit();
std::cout << std::endl;
std::cout << "The depth is: " << tree->get_depth() << std::endl;
std::cout << "The number of nodes is: " << tree->get_num_nodes() << std::endl;
return 0;
}
output:
Preorder visit: a b d f g c e
In-order visit: b f d g a e c
Post-order visit: f g d b e c a
The depth is: 4
The number of nodes is: 7
对于任意一棵二叉树, 我们可以将其转换为满二叉树来存储. 以 Day 21 的数据为例, 将其转换为满二叉树并编号的结果如图所示:
其中, N 表示空节点. 设根结点的编号为 1 1 1, 对于任意一个节点 i i i, 其左儿子的编号为 i × 2 i\times2 i×2 右儿子的编号为 i × 2 + 1 i\times2+1 i×2+1. 然后用两个数组分别存储节点的值和节点的编号.
value array: [A, B, C, D, E, F, G]
index array: [1, 2, 3, 5, 6, 10, 11]
#include
#include
#include
class BinaryCharTree
{
public:
int index;
char value;
BinaryCharTree* left_child;
BinaryCharTree* right_child;
BinaryCharTree()
{
this->index = 1;
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char name)
{
this->index = 1;
this->value = name;
this->left_child = NULL;
this->right_child = NULL;
}
void pre_order_visit()
{
std::cout << this->value << " ";
if (this->left_child != NULL) this->left_child->pre_order_visit();
if (this->right_child != NULL) this->right_child->pre_order_visit();
}
void in_order_visit()
{
if (this->left_child != NULL) this->left_child->in_order_visit();
std::cout << this->value << " ";
if (this->right_child != NULL) this->right_child->in_order_visit();
}
void post_order_visit()
{
if (this->left_child != NULL) this->left_child->post_order_visit();
if (this->right_child != NULL) this->right_child->post_order_visit();
std::cout << this->value << " ";
}
int get_depth()
{
if (this->left_child == NULL && this->right_child == NULL)
{
return 1;
}
int temp_left_depth = 0;
if (this->left_child != NULL) temp_left_depth = this->left_child->get_depth();
int temp_right_depth = 0;
if (this->right_child != NULL) temp_right_depth = this->right_child->get_depth();
return 1 + std::max(temp_left_depth, temp_right_depth);
}
int get_num_nodes()
{
if (this->left_child == NULL && this->right_child == NULL) return 1;
int temp_left_nodes = 0;
if (this->left_child != NULL) temp_left_nodes = this->left_child->get_num_nodes();
int temp_right_nodes = 0;
if (this->right_child != NULL) temp_right_nodes = this->right_child->get_num_nodes();
return temp_left_nodes + temp_right_nodes + 1;
}
};
BinaryCharTree* manual_construct_tree()
{
BinaryCharTree* tree = new BinaryCharTree('A');
BinaryCharTree* treeB = new BinaryCharTree('B');
BinaryCharTree* treeC = new BinaryCharTree('C');
BinaryCharTree* treeD = new BinaryCharTree('D');
BinaryCharTree* treeE = new BinaryCharTree('E');
BinaryCharTree* treeF = new BinaryCharTree('F');
BinaryCharTree* treeG = new BinaryCharTree('G');
tree->left_child = treeB;
treeB->index = tree->index * 2;
tree->right_child = treeC;
treeC->index = tree->index * 2 + 1;
treeB->right_child = treeD;
treeD->index = treeB->index * 2 + 1;
treeC->left_child = treeE;
treeE->index = treeC->index * 2;
treeD->left_child = treeF;
treeF->index = treeD->index * 2;
treeD->right_child = treeG;
treeG->index = treeD->index * 2 + 1;
return tree;
}
void binary_tree_to_array(BinaryCharTree* tree, std::vector<char>& value_array, std::vector<int>& index_array)
{
std::queue<BinaryCharTree*> child_tree_queue;
if (tree->left_child != NULL && tree->right_child != NULL) child_tree_queue.push(tree);
while (!child_tree_queue.empty())
{
BinaryCharTree* tree = child_tree_queue.front();
child_tree_queue.pop();
value_array.push_back(tree->value);
index_array.push_back(tree->index);
if (tree->left_child != NULL) child_tree_queue.push(tree->left_child);
if (tree->right_child != NULL) child_tree_queue.push(tree->right_child);
}
}
int main()
{
BinaryCharTree* tree = manual_construct_tree();
std::cout << "Preorder visit: ";
tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
tree->post_order_visit();
std::cout << std::endl;
std::cout << "The depth is: " << tree->get_depth() << std::endl;
std::cout << "The number of nodes is: " << tree->get_num_nodes() << std::endl;
std::vector<char> value_array;
std::vector<int> index_array;
binary_tree_to_array(tree, value_array, index_array);
std::cout << "value array: ";
for (int i = 0; i < value_array.size(); i ++) std::cout << value_array[i] << ' ';
std::cout << std::endl;
std::cout << "index array: ";
for (int i = 0; i < index_array.size(); i ++) std::cout << index_array[i] << ' ';
std::cout << std::endl;
return 0;
}
output:
Preorder visit: A B D F G C E
In-order visit: B F D G A E C
Post-order visit: F G D B E C A
The depth is: 4
The number of nodes is: 7
value array: A B C D E F G
index array: 1 2 3 5 6 10 11
使用 CPP 类模板实现一个循环队列, 替换 Day 22 使用的 std::vector 和 std::queue.
#include
#include
class BinaryCharTree
{
public:
int index;
char value;
BinaryCharTree* left_child;
BinaryCharTree* right_child;
BinaryCharTree()
{
this->index = 1;
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char name)
{
this->index = 1;
this->value = name;
this->left_child = NULL;
this->right_child = NULL;
}
void pre_order_visit()
{
std::cout << this->value << " ";
if (this->left_child != NULL) this->left_child->pre_order_visit();
if (this->right_child != NULL) this->right_child->pre_order_visit();
}
void in_order_visit()
{
if (this->left_child != NULL) this->left_child->in_order_visit();
std::cout << this->value << " ";
if (this->right_child != NULL) this->right_child->in_order_visit();
}
void post_order_visit()
{
if (this->left_child != NULL) this->left_child->post_order_visit();
if (this->right_child != NULL) this->right_child->post_order_visit();
std::cout << this->value << " ";
}
int get_depth()
{
if (this->left_child == NULL && this->right_child == NULL)
{
return 1;
}
int temp_left_depth = 0;
if (this->left_child != NULL) temp_left_depth = this->left_child->get_depth();
int temp_right_depth = 0;
if (this->right_child != NULL) temp_right_depth = this->right_child->get_depth();
return 1 + std::max(temp_left_depth, temp_right_depth);
}
int get_num_nodes()
{
if (this->left_child == NULL && this->right_child == NULL) return 1;
int temp_left_nodes = 0;
if (this->left_child != NULL) temp_left_nodes = this->left_child->get_num_nodes();
int temp_right_nodes = 0;
if (this->right_child != NULL) temp_right_nodes = this->right_child->get_num_nodes();
return temp_left_nodes + temp_right_nodes + 1;
}
};
BinaryCharTree* manual_construct_tree()
{
BinaryCharTree* tree = new BinaryCharTree('A');
BinaryCharTree* treeB = new BinaryCharTree('B');
BinaryCharTree* treeC = new BinaryCharTree('C');
BinaryCharTree* treeD = new BinaryCharTree('D');
BinaryCharTree* treeE = new BinaryCharTree('E');
BinaryCharTree* treeF = new BinaryCharTree('F');
BinaryCharTree* treeG = new BinaryCharTree('G');
tree->left_child = treeB;
treeB->index = tree->index * 2;
tree->right_child = treeC;
treeC->index = tree->index * 2 + 1;
treeB->right_child = treeD;
treeD->index = treeB->index * 2 + 1;
treeC->left_child = treeE;
treeE->index = treeC->index * 2;
treeD->left_child = treeF;
treeF->index = treeD->index * 2;
treeD->right_child = treeG;
treeG->index = treeD->index * 2 + 1;
return tree;
}
template<typename T>
class MyQueue
{
public:
const static int MAX_LENGTH = 20;
T* data;
int head;
int tail;
MyQueue()
{
data = new T[MAX_LENGTH];
this->head = 0;
this->tail = 0;
}
~MyQueue()
{
delete []data;
}
void push(T value)
{
if ((this->tail + 1) % MAX_LENGTH == this->head)
{
std::cout << "The queue is full." << std::endl;
return;
}
this->data[this->tail] = value;
this->tail = (this->tail + 1) % MAX_LENGTH;
}
void pop()
{
if (this->tail == this->head)
{
std::cout << "The queue is empty." << std::endl;
return;
}
this->head = (this->head + 1) % MAX_LENGTH;
}
T front()
{
return this->data[this->head];
}
bool empty()
{
if (this->head == this->tail) return true;
return false;
}
std::string to_string()
{
std::stringstream ss;
for (int i = this->head; i != this->tail; i = (i + 1) % MAX_LENGTH)
ss << this->data[i] << ' ';
return ss.str();
}
};
void binary_tree_to_array(BinaryCharTree* tree, MyQueue<char>& value_array, MyQueue<int>& index_array)
{
MyQueue<BinaryCharTree*> child_tree_queue;
if (tree->left_child != NULL && tree->right_child != NULL) child_tree_queue.push(tree);
while (!child_tree_queue.empty())
{
BinaryCharTree* tree = child_tree_queue.front();
child_tree_queue.pop();
value_array.push(tree->value);
index_array.push(tree->index);
if (tree->left_child != NULL) child_tree_queue.push(tree->left_child);
if (tree->right_child != NULL) child_tree_queue.push(tree->right_child);
}
}
int main()
{
BinaryCharTree* tree = manual_construct_tree();
std::cout << "Preorder visit: ";
tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
tree->post_order_visit();
std::cout << std::endl;
std::cout << "The depth is: " << tree->get_depth() << std::endl;
std::cout << "The number of nodes is: " << tree->get_num_nodes() << std::endl;
MyQueue<char> value_array;
MyQueue<int> index_array;
binary_tree_to_array(tree, value_array, index_array);
std::cout << "value array: " << value_array.to_string() << std::endl;
std::cout << "index array: " << index_array.to_string() << std::endl;
return 0;
}
output:
Preorder visit: A B D F G C E
In-order visit: B F D G A E C
Post-order visit: F G D B E C A
The depth is: 4
The number of nodes is: 7
value array: A B C D E F G
index array: 1 2 3 5 6 10 11
今天的内容相当于 Day 22 的逆过程, 根据层次遍历的结果构建二叉树.
#include
#include
#include
template<typename T>
class MyQueue
{
public:
const static int MAX_LENGTH = 20;
T* data;
int head;
int tail;
MyQueue()
{
data = new T[MAX_LENGTH];
this->head = 0;
this->tail = 0;
}
~MyQueue()
{
delete []data;
}
void push(T value)
{
if ((this->tail + 1) % MAX_LENGTH == this->head)
{
std::cout << "The queue is full." << std::endl;
return;
}
this->data[this->tail] = value;
this->tail = (this->tail + 1) % MAX_LENGTH;
}
void pop()
{
if (this->tail == this->head)
{
std::cout << "The queue is empty." << std::endl;
return;
}
this->head = (this->head + 1) % MAX_LENGTH;
}
T front()
{
return this->data[this->head];
}
bool empty()
{
if (this->head == this->tail) return true;
return false;
}
std::string to_string()
{
std::stringstream ss;
for (int i = this->head; i != this->tail; i = (i + 1) % MAX_LENGTH)
ss << this->data[i] << ' ';
return ss.str();
}
};
class BinaryCharTree
{
public:
int index;
char value;
BinaryCharTree* left_child;
BinaryCharTree* right_child;
BinaryCharTree()
{
this->index = 1;
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char name)
{
this->index = 1;
this->value = name;
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char* value_array, int* index_array)
{
this->value = value_array[0];
this->index = index_array[0];
std::queue<BinaryCharTree*> tree_node_queue;
for (int i = 1; value_array[i] != '#'; i ++)
{
tree_node_queue.push(this);
while (!tree_node_queue.empty())
{
BinaryCharTree* temp = tree_node_queue.front();
tree_node_queue.pop();
if (temp->index * 2 == index_array[i])
{
BinaryCharTree* new_tree = new BinaryCharTree(value_array[i]);
new_tree->index = index_array[i];
temp->left_child = new_tree;
while (!tree_node_queue.empty()) tree_node_queue.pop();
}
else if (temp->index * 2 + 1== index_array[i])
{
BinaryCharTree* new_tree = new BinaryCharTree(value_array[i]);
new_tree->index = index_array[i];
temp->right_child = new_tree;
while (!tree_node_queue.empty()) tree_node_queue.pop();
}
else
{
if (temp->left_child != NULL) tree_node_queue.push(temp->left_child);
if (temp->right_child != NULL) tree_node_queue.push(temp->right_child);
}
}
}
}
void pre_order_visit()
{
std::cout << this->value << " ";
if (this->left_child != NULL) this->left_child->pre_order_visit();
if (this->right_child != NULL) this->right_child->pre_order_visit();
}
void in_order_visit()
{
if (this->left_child != NULL) this->left_child->in_order_visit();
std::cout << this->value << " ";
if (this->right_child != NULL) this->right_child->in_order_visit();
}
void post_order_visit()
{
if (this->left_child != NULL) this->left_child->post_order_visit();
if (this->right_child != NULL) this->right_child->post_order_visit();
std::cout << this->value << " ";
}
int get_depth()
{
if (this->left_child == NULL && this->right_child == NULL)
{
return 1;
}
int temp_left_depth = 0;
if (this->left_child != NULL) temp_left_depth = this->left_child->get_depth();
int temp_right_depth = 0;
if (this->right_child != NULL) temp_right_depth = this->right_child->get_depth();
return 1 + std::max(temp_left_depth, temp_right_depth);
}
int get_num_nodes()
{
if (this->left_child == NULL && this->right_child == NULL) return 1;
int temp_left_nodes = 0;
if (this->left_child != NULL) temp_left_nodes = this->left_child->get_num_nodes();
int temp_right_nodes = 0;
if (this->right_child != NULL) temp_right_nodes = this->right_child->get_num_nodes();
return temp_left_nodes + temp_right_nodes + 1;
}
};
BinaryCharTree* manual_construct_tree()
{
BinaryCharTree* tree = new BinaryCharTree('A');
BinaryCharTree* treeB = new BinaryCharTree('B');
BinaryCharTree* treeC = new BinaryCharTree('C');
BinaryCharTree* treeD = new BinaryCharTree('D');
BinaryCharTree* treeE = new BinaryCharTree('E');
BinaryCharTree* treeF = new BinaryCharTree('F');
BinaryCharTree* treeG = new BinaryCharTree('G');
tree->left_child = treeB;
treeB->index = tree->index * 2;
tree->right_child = treeC;
treeC->index = tree->index * 2 + 1;
treeB->right_child = treeD;
treeD->index = treeB->index * 2 + 1;
treeC->left_child = treeE;
treeE->index = treeC->index * 2;
treeD->left_child = treeF;
treeF->index = treeD->index * 2;
treeD->right_child = treeG;
treeG->index = treeD->index * 2 + 1;
return tree;
}
void binary_tree_to_array(BinaryCharTree* tree, MyQueue<char>& value_array, MyQueue<int>& index_array)
{
MyQueue<BinaryCharTree*> child_tree_queue;
if (tree->left_child != NULL && tree->right_child != NULL) child_tree_queue.push(tree);
while (!child_tree_queue.empty())
{
BinaryCharTree* tree = child_tree_queue.front();
child_tree_queue.pop();
value_array.push(tree->value);
index_array.push(tree->index);
if (tree->left_child != NULL) child_tree_queue.push(tree->left_child);
if (tree->right_child != NULL) child_tree_queue.push(tree->right_child);
}
}
int main()
{
BinaryCharTree* tree = manual_construct_tree();
std::cout << "Preorder visit: ";
tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
tree->post_order_visit();
std::cout << std::endl;
std::cout << "The depth is: " << tree->get_depth() << std::endl;
std::cout << "The number of nodes is: " << tree->get_num_nodes() << std::endl;
MyQueue<char> value_array;
MyQueue<int> index_array;
binary_tree_to_array(tree, value_array, index_array);
std::cout << "value array: " << value_array.to_string() << std::endl;
std::cout << "index array: " << index_array.to_string() << std::endl;
char new_value_array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', '#'};
int new_index_array[20] = {1, 2, 3, 5, 6, 10, 11, -1};
BinaryCharTree* new_tree = new BinaryCharTree(new_value_array, new_index_array);
std::cout << "Preorder visit: ";
new_tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
new_tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
new_tree->post_order_visit();
std::cout << std::endl;
return 0;
}
output:
Preorder visit: A B D F G C E
In-order visit: B F D G A E C
Post-order visit: F G D B E C A
The depth is: 4
The number of nodes is: 7
value array: A B C D E F G
index array: 1 2 3 5 6 10 11
Preorder visit: A B D F G C E
In-order visit: B F D G A E C
Post-order visit: F G D B E C A
Part 1 栈的实现
template<typename T>
class MyStack
{
public:
const int MAX_LENGTH = 10;
int depth;
T* data;
MyStack()
{
this->depth = 0;
this->data = new T[MAX_LENGTH];
}
std::string to_string()
{
std::stringstream ss;
for (int i = 0; i < this->depth; i ++)
{
ss << this->data[i];
}
return ss.str();
}
bool push(T value)
{
if (this->depth == MAX_LENGTH)
{
std::cout << "Stack full." << std::endl;
return false;
}
this->data[this->depth] = value;
this->depth ++;
return true;
}
void pop()
{
if (this->depth == 0)
{
std::cout << "Stack empty." << std::endl;
return;
}
this->depth --;
}
T top()
{
return this->data[this->depth - 1];
}
bool empty()
{
if (this->depth == 0) return true;
return false;
}
};
Part 2 中序遍历
#include
#include
#include
template<typename T>
class MyStack
{
public:
const int MAX_LENGTH = 10;
int depth;
T* data;
MyStack()
{
this->depth = 0;
this->data = new T[MAX_LENGTH];
}
std::string to_string()
{
std::stringstream ss;
for (int i = 0; i < this->depth; i ++)
{
ss << this->data[i];
}
return ss.str();
}
bool push(T value)
{
if (this->depth == MAX_LENGTH)
{
std::cout << "Stack full." << std::endl;
return false;
}
this->data[this->depth] = value;
this->depth ++;
return true;
}
void pop()
{
if (this->depth == 0)
{
std::cout << "Stack empty." << std::endl;
return;
}
this->depth --;
}
T top()
{
return this->data[this->depth - 1];
}
bool empty()
{
if (this->depth == 0) return true;
return false;
}
};
template<typename T>
class MyQueue
{
public:
const static int MAX_LENGTH = 20;
T* data;
int head;
int tail;
MyQueue()
{
data = new T[MAX_LENGTH];
this->head = 0;
this->tail = 0;
}
~MyQueue()
{
delete []data;
}
void push(T value)
{
if ((this->tail + 1) % MAX_LENGTH == this->head)
{
std::cout << "The queue is full." << std::endl;
return;
}
this->data[this->tail] = value;
this->tail = (this->tail + 1) % MAX_LENGTH;
}
void pop()
{
if (this->tail == this->head)
{
std::cout << "The queue is empty." << std::endl;
return;
}
this->head = (this->head + 1) % MAX_LENGTH;
}
T front()
{
return this->data[this->head];
}
bool empty()
{
if (this->head == this->tail) return true;
return false;
}
std::string to_string()
{
std::stringstream ss;
for (int i = this->head; i != this->tail; i = (i + 1) % MAX_LENGTH)
ss << this->data[i] << ' ';
return ss.str();
}
};
class BinaryCharTree
{
public:
int index;
char value;
BinaryCharTree* left_child;
BinaryCharTree* right_child;
BinaryCharTree()
{
this->index = 1;
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char name)
{
this->index = 1;
this->value = name;
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char* value_array, int* index_array)
{
this->value = value_array[0];
this->index = index_array[0];
std::queue<BinaryCharTree*> tree_node_queue;
for (int i = 1; value_array[i] != '#'; i ++)
{
tree_node_queue.push(this);
while (!tree_node_queue.empty())
{
BinaryCharTree* temp = tree_node_queue.front();
tree_node_queue.pop();
if (temp->index * 2 == index_array[i])
{
BinaryCharTree* new_tree = new BinaryCharTree(value_array[i]);
new_tree->index = index_array[i];
temp->left_child = new_tree;
while (!tree_node_queue.empty()) tree_node_queue.pop();
}
else if (temp->index * 2 + 1== index_array[i])
{
BinaryCharTree* new_tree = new BinaryCharTree(value_array[i]);
new_tree->index = index_array[i];
temp->right_child = new_tree;
while (!tree_node_queue.empty()) tree_node_queue.pop();
}
else
{
if (temp->left_child != NULL) tree_node_queue.push(temp->left_child);
if (temp->right_child != NULL) tree_node_queue.push(temp->right_child);
}
}
}
}
void pre_order_visit()
{
std::cout << this->value << " ";
if (this->left_child != NULL) this->left_child->pre_order_visit();
if (this->right_child != NULL) this->right_child->pre_order_visit();
}
void in_order_visit()
{
if (this->left_child != NULL) this->left_child->in_order_visit();
std::cout << this->value << " ";
if (this->right_child != NULL) this->right_child->in_order_visit();
}
void in_order_visit_by_stack()
{
MyStack<BinaryCharTree*> stack;
BinaryCharTree* tree = this;
while (!stack.empty() || tree != NULL)
{
if (tree != NULL)
{
stack.push(tree);
tree = tree->left_child;
}
else
{
tree = stack.top();
stack.pop();
std::cout << tree->value << ' ';
tree = tree->right_child;
}
}
std::cout << std::endl;
}
void post_order_visit()
{
if (this->left_child != NULL) this->left_child->post_order_visit();
if (this->right_child != NULL) this->right_child->post_order_visit();
std::cout << this->value << " ";
}
int get_depth()
{
if (this->left_child == NULL && this->right_child == NULL)
{
return 1;
}
int temp_left_depth = 0;
if (this->left_child != NULL) temp_left_depth = this->left_child->get_depth();
int temp_right_depth = 0;
if (this->right_child != NULL) temp_right_depth = this->right_child->get_depth();
return 1 + std::max(temp_left_depth, temp_right_depth);
}
int get_num_nodes()
{
if (this->left_child == NULL && this->right_child == NULL) return 1;
int temp_left_nodes = 0;
if (this->left_child != NULL) temp_left_nodes = this->left_child->get_num_nodes();
int temp_right_nodes = 0;
if (this->right_child != NULL) temp_right_nodes = this->right_child->get_num_nodes();
return temp_left_nodes + temp_right_nodes + 1;
}
};
BinaryCharTree* manual_construct_tree()
{
BinaryCharTree* tree = new BinaryCharTree('A');
BinaryCharTree* treeB = new BinaryCharTree('B');
BinaryCharTree* treeC = new BinaryCharTree('C');
BinaryCharTree* treeD = new BinaryCharTree('D');
BinaryCharTree* treeE = new BinaryCharTree('E');
BinaryCharTree* treeF = new BinaryCharTree('F');
BinaryCharTree* treeG = new BinaryCharTree('G');
tree->left_child = treeB;
treeB->index = tree->index * 2;
tree->right_child = treeC;
treeC->index = tree->index * 2 + 1;
treeB->right_child = treeD;
treeD->index = treeB->index * 2 + 1;
treeC->left_child = treeE;
treeE->index = treeC->index * 2;
treeD->left_child = treeF;
treeF->index = treeD->index * 2;
treeD->right_child = treeG;
treeG->index = treeD->index * 2 + 1;
return tree;
}
void binary_tree_to_array(BinaryCharTree* tree, MyQueue<char>& value_array, MyQueue<int>& index_array)
{
MyQueue<BinaryCharTree*> child_tree_queue;
if (tree->left_child != NULL && tree->right_child != NULL) child_tree_queue.push(tree);
while (!child_tree_queue.empty())
{
BinaryCharTree* tree = child_tree_queue.front();
child_tree_queue.pop();
value_array.push(tree->value);
index_array.push(tree->index);
if (tree->left_child != NULL) child_tree_queue.push(tree->left_child);
if (tree->right_child != NULL) child_tree_queue.push(tree->right_child);
}
}
int main()
{
BinaryCharTree* tree = manual_construct_tree();
std::cout << "Preorder visit: ";
tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
tree->post_order_visit();
std::cout << std::endl;
std::cout << "The depth is: " << tree->get_depth() << std::endl;
std::cout << "The number of nodes is: " << tree->get_num_nodes() << std::endl;
MyQueue<char> value_array;
MyQueue<int> index_array;
binary_tree_to_array(tree, value_array, index_array);
std::cout << "value array: " << value_array.to_string() << std::endl;
std::cout << "index array: " << index_array.to_string() << std::endl;
char new_value_array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', '#'};
int new_index_array[20] = {1, 2, 3, 5, 6, 10, 11, -1};
BinaryCharTree* new_tree = new BinaryCharTree(new_value_array, new_index_array);
std::cout << "Preorder visit: ";
new_tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
new_tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
new_tree->post_order_visit();
std::cout << std::endl;
std::cout << "In-order visit by stack: ";
new_tree->in_order_visit_by_stack();
return 0;
}
output:
Preorder visit: A B D F G C E
In-order visit: B F D G A E C
Post-order visit: F G D B E C A
The depth is: 4
The number of nodes is: 7
value array: A B C D E F G
index array: 1 2 3 5 6 10 11
Preorder visit: A B D F G C E
In-order visit: B F D G A E C
Post-order visit: F G D B E C A
In-order visit by stack: B F D G A E C
#include
#include
#include
template<typename T>
class MyStack
{
public:
const int MAX_LENGTH = 10;
int depth;
T* data;
MyStack()
{
this->depth = 0;
this->data = new T[MAX_LENGTH];
}
std::string to_string()
{
std::stringstream ss;
for (int i = 0; i < this->depth; i ++)
{
ss << this->data[i];
}
return ss.str();
}
bool push(T value)
{
if (this->depth == MAX_LENGTH)
{
std::cout << "Stack full." << std::endl;
return false;
}
this->data[this->depth] = value;
this->depth ++;
return true;
}
void pop()
{
if (this->depth == 0)
{
std::cout << "Stack empty." << std::endl;
return;
}
this->depth --;
}
T top()
{
return this->data[this->depth - 1];
}
bool empty()
{
if (this->depth == 0) return true;
return false;
}
};
template<typename T>
class MyQueue
{
public:
const static int MAX_LENGTH = 20;
T* data;
int head;
int tail;
MyQueue()
{
data = new T[MAX_LENGTH];
this->head = 0;
this->tail = 0;
}
~MyQueue()
{
delete []data;
}
void push(T value)
{
if ((this->tail + 1) % MAX_LENGTH == this->head)
{
std::cout << "The queue is full." << std::endl;
return;
}
this->data[this->tail] = value;
this->tail = (this->tail + 1) % MAX_LENGTH;
}
void pop()
{
if (this->tail == this->head)
{
std::cout << "The queue is empty." << std::endl;
return;
}
this->head = (this->head + 1) % MAX_LENGTH;
}
T front()
{
return this->data[this->head];
}
bool empty()
{
if (this->head == this->tail) return true;
return false;
}
std::string to_string()
{
std::stringstream ss;
for (int i = this->head; i != this->tail; i = (i + 1) % MAX_LENGTH)
ss << this->data[i] << ' ';
return ss.str();
}
};
class BinaryCharTree
{
public:
int index;
char value;
BinaryCharTree* left_child;
BinaryCharTree* right_child;
BinaryCharTree()
{
this->index = 1;
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char name)
{
this->index = 1;
this->value = name;
this->left_child = NULL;
this->right_child = NULL;
}
BinaryCharTree(char* value_array, int* index_array)
{
this->value = value_array[0];
this->index = index_array[0];
std::queue<BinaryCharTree*> tree_node_queue;
for (int i = 1; value_array[i] != '#'; i ++)
{
tree_node_queue.push(this);
while (!tree_node_queue.empty())
{
BinaryCharTree* temp = tree_node_queue.front();
tree_node_queue.pop();
if (temp->index * 2 == index_array[i])
{
BinaryCharTree* new_tree = new BinaryCharTree(value_array[i]);
new_tree->index = index_array[i];
temp->left_child = new_tree;
while (!tree_node_queue.empty()) tree_node_queue.pop();
}
else if (temp->index * 2 + 1== index_array[i])
{
BinaryCharTree* new_tree = new BinaryCharTree(value_array[i]);
new_tree->index = index_array[i];
temp->right_child = new_tree;
while (!tree_node_queue.empty()) tree_node_queue.pop();
}
else
{
if (temp->left_child != NULL) tree_node_queue.push(temp->left_child);
if (temp->right_child != NULL) tree_node_queue.push(temp->right_child);
}
}
}
}
void pre_order_visit()
{
std::cout << this->value << " ";
if (this->left_child != NULL) this->left_child->pre_order_visit();
if (this->right_child != NULL) this->right_child->pre_order_visit();
}
void in_order_visit()
{
if (this->left_child != NULL) this->left_child->in_order_visit();
std::cout << this->value << " ";
if (this->right_child != NULL) this->right_child->in_order_visit();
}
void pre_order_visit_by_stack()
{
MyStack<BinaryCharTree*> stack;
BinaryCharTree* tree = this;
while (!stack.empty() || tree != NULL)
{
if (tree != NULL)
{
std::cout << tree->value << ' ';
stack.push(tree);
tree = tree->left_child;
}
else
{
tree = stack.top();
stack.pop();
tree = tree->right_child;
}
}
std::cout << std::endl;
}
void in_order_visit_by_stack()
{
MyStack<BinaryCharTree*> stack;
BinaryCharTree* tree = this;
while (!stack.empty() || tree != NULL)
{
if (tree != NULL)
{
stack.push(tree);
tree = tree->left_child;
}
else
{
tree = stack.top();
stack.pop();
std::cout << tree->value << ' ';
tree = tree->right_child;
}
}
std::cout << std::endl;
}
void post_order_visit_by_stack()
{
MyStack<BinaryCharTree*> stack;
MyStack<char> output_stack;
BinaryCharTree* tree = this;
while (!stack.empty() || tree != NULL)
{
if (tree != NULL)
{
output_stack.push(tree->value);
stack.push(tree);
tree = tree->right_child;
}
else
{
tree = stack.top();
stack.pop();
tree = tree->left_child;
}
}
while (!output_stack.empty())
{
std::cout << output_stack.top() << ' ';
output_stack.pop();
}
std::cout << std::endl;
}
void post_order_visit()
{
if (this->left_child != NULL) this->left_child->post_order_visit();
if (this->right_child != NULL) this->right_child->post_order_visit();
std::cout << this->value << " ";
}
int get_depth()
{
if (this->left_child == NULL && this->right_child == NULL)
{
return 1;
}
int temp_left_depth = 0;
if (this->left_child != NULL) temp_left_depth = this->left_child->get_depth();
int temp_right_depth = 0;
if (this->right_child != NULL) temp_right_depth = this->right_child->get_depth();
return 1 + std::max(temp_left_depth, temp_right_depth);
}
int get_num_nodes()
{
if (this->left_child == NULL && this->right_child == NULL) return 1;
int temp_left_nodes = 0;
if (this->left_child != NULL) temp_left_nodes = this->left_child->get_num_nodes();
int temp_right_nodes = 0;
if (this->right_child != NULL) temp_right_nodes = this->right_child->get_num_nodes();
return temp_left_nodes + temp_right_nodes + 1;
}
};
BinaryCharTree* manual_construct_tree()
{
BinaryCharTree* tree = new BinaryCharTree('A');
BinaryCharTree* treeB = new BinaryCharTree('B');
BinaryCharTree* treeC = new BinaryCharTree('C');
BinaryCharTree* treeD = new BinaryCharTree('D');
BinaryCharTree* treeE = new BinaryCharTree('E');
BinaryCharTree* treeF = new BinaryCharTree('F');
BinaryCharTree* treeG = new BinaryCharTree('G');
tree->left_child = treeB;
treeB->index = tree->index * 2;
tree->right_child = treeC;
treeC->index = tree->index * 2 + 1;
treeB->right_child = treeD;
treeD->index = treeB->index * 2 + 1;
treeC->left_child = treeE;
treeE->index = treeC->index * 2;
treeD->left_child = treeF;
treeF->index = treeD->index * 2;
treeD->right_child = treeG;
treeG->index = treeD->index * 2 + 1;
return tree;
}
void binary_tree_to_array(BinaryCharTree* tree, MyQueue<char>& value_array, MyQueue<int>& index_array)
{
MyQueue<BinaryCharTree*> child_tree_queue;
if (tree->left_child != NULL && tree->right_child != NULL) child_tree_queue.push(tree);
while (!child_tree_queue.empty())
{
BinaryCharTree* tree = child_tree_queue.front();
child_tree_queue.pop();
value_array.push(tree->value);
index_array.push(tree->index);
if (tree->left_child != NULL) child_tree_queue.push(tree->left_child);
if (tree->right_child != NULL) child_tree_queue.push(tree->right_child);
}
}
int main()
{
BinaryCharTree* tree = manual_construct_tree();
std::cout << "Preorder visit: ";
tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
tree->post_order_visit();
std::cout << std::endl;
std::cout << "The depth is: " << tree->get_depth() << std::endl;
std::cout << "The number of nodes is: " << tree->get_num_nodes() << std::endl;
MyQueue<char> value_array;
MyQueue<int> index_array;
binary_tree_to_array(tree, value_array, index_array);
std::cout << "value array: " << value_array.to_string() << std::endl;
std::cout << "index array: " << index_array.to_string() << std::endl;
char new_value_array[20] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', '#'};
int new_index_array[20] = {1, 2, 3, 5, 6, 10, 11, -1};
BinaryCharTree* new_tree = new BinaryCharTree(new_value_array, new_index_array);
std::cout << "Preorder visit: ";
new_tree->pre_order_visit();
std::cout << std::endl;
std::cout << "In-order visit: ";
new_tree->in_order_visit();
std::cout << std::endl;
std::cout << "Post-order visit: ";
new_tree->post_order_visit();
std::cout << std::endl;
std::cout << "In-order visit by stack: ";
new_tree->in_order_visit_by_stack();
std::cout << "Preorder visit by satck: ";
new_tree->pre_order_visit_by_stack();
std::cout << "Post-order visit by stack: ";
new_tree->post_order_visit_by_stack();
return 0;
}
output:
Preorder visit: A B D F G C E
In-order visit: B F D G A E C
Post-order visit: F G D B E C A
The depth is: 4
The number of nodes is: 7
value array: A B C D E F G
index array: 1 2 3 5 6 10 11
Preorder visit: A B D F G C E
In-order visit: B F D G A E C
Post-order visit: F G D B E C A
In-order visit by stack: B F D G A E C
Preorder visit by satck: A B D F G C E
Post-order visit by stack: F G D B E C A
#include
void hanoi(char source, char intermediary, char destination, int number)
{
if (number == 1)
{
std::cout << source << "->" << destination << " ";
return;
}
hanoi(source, destination, intermediary, number - 1);
std::cout << source << "->" << destination << " ";
hanoi(intermediary, source, destination, number - 1);
}
int main()
{
hanoi('a', 'b', 'c', 3);
std::cout << std::endl;
return 0;
}
output:
a->c a->b c->b a->c b->a b->c a->c
以下为 Day 28、Day 29 和 Day 30 的全部代码
#include
#include
#include
#include
const int INF = 0x3f3f3f3f;
// Huffman Tree
typedef struct Node {
int weight;
int parent;
int lchild;
int rchild;
}*HuffmanTree;
// Huffman Code
typedef struct Code {
char data;
int weight;
std::string code;
}*HuffmanCode;
void initTree(HuffmanTree& tree, HuffmanCode& code, std::map<char, int> m, int n);
void Select(HuffmanTree& tree, int& a, int& b, int n);
void createHuffmanTree(HuffmanTree& tree, int n);
void HuffCode(HuffmanTree& tree, HuffmanCode& code, int n);
std::string HuffDeCode(HuffmanCode& code, std::string s, int n);
void printTest(HuffmanTree tree, HuffmanCode code, std::string s, std::map<char, int> m, int n);
int main()
{
std::string s;
std::cout << "Please input a string: " << std::endl;
getline(std::cin, s);
std::cout << "Your input: " << std::endl;
std::cout << s << std::endl;
std::map<char, int> m; // char count
for (int i = 0; i < s.size(); i ++)
{
m[s[i]]++;
}
int n = m.size();
HuffmanTree tree = new Node[2 * n];
HuffmanCode code = new Code[n + 1];
initTree(tree, code, m, n);
createHuffmanTree(tree, n);
HuffCode(tree, code, n);
printTest(tree, code, s, m, n);
return 0;
}
void initTree(HuffmanTree& tree, HuffmanCode& code, std::map<char, int> m, int n)
{
std::map<char, int>::iterator it;
it = m.begin();
for (int i = 1; i < 2 * n; i ++)
{
if (i <= n)
{
tree[i].weight = it->second; // count
code[i].weight = it->second; // count
code[i].data = it->first; // char
it++;
}
else
{
tree[i].weight = 0;
}
tree[i].parent = tree[i].lchild = tree[i].rchild = 0;
}
}
//select two smallest trees
void Select(HuffmanTree& tree, int& a, int& b, int n)
{
int minWeight = INF;
for (int i = 1; i <= n; i ++)
{
if (tree[i].weight < minWeight && tree[i].parent == 0)
{
minWeight = tree[i].weight;
a = i;
}
}
minWeight = INF;
for (int i = 1; i <= n; i ++)
{
if (tree[i].weight < minWeight && tree[i].parent == 0 && i != a)
{
minWeight = tree[i].weight;
b = i;
}
}
}
//create Huffman Tree
void createHuffmanTree(HuffmanTree& tree, int n)
{
int a, b;
for (int i = n + 1; i < 2 * n; i ++)
{
Select(tree, a, b, i - 1);
tree[a].parent = i;
tree[b].parent = i;
tree[i].lchild = a;
tree[i].rchild = b;
tree[i].weight = tree[a].weight + tree[b].weight;
}
}
// encode
void HuffCode(HuffmanTree& tree, HuffmanCode& code, int n)
{
std::string s;
int j, k;
for (int i = 1; i <= n; i ++)
{
s = "";
j = i;
while (tree[j].parent != 0) // root.parent == 0
{
k = tree[j].parent;
if (j == tree[k].lchild) // left_child = 0 right_child = 1
{
s += "0";
}
else
{
s += "1";
}
j = tree[j].parent;
}
reverse(s.begin(), s.end());
code[i].code = s;
}
}
// decode
std::string HuffDeCode(HuffmanCode& code, std::string s, int n)
{
std::string res = "";
std::string temp = "";
for (int i = 0; i < s.size(); i ++)
{
temp += s[i];
for (int j = 1; j <= n; j ++)
{
if (temp == code[j].code)
{
res += code[j].data;
temp = "";
break;
}
}
}
return res;
}
// test
void printTest(HuffmanTree tree, HuffmanCode code, std::string s, std::map<char, int> m, int n)
{
std::string arr = "";
std::cout << "the frequency of each char: " << std::endl;
std::map<char, int>::iterator it;
for (it = m.begin(); it != m.end(); it ++)
{
std::cout << it->first << ":" << it->second << " ";
}
std::cout << std::endl;
std::cout << "Huffman Tree struct(value、parent、left_child、right_child): " << std::endl;
for (int i = 1; i <= 2 * n - 1; i ++)
{
std::cout << i << " " << tree[i].weight << " " << tree[i].parent << " " << tree[i].lchild << " " << tree[i].rchild << std::endl;
}
std::cout << "the Huffman Code of each char: " << std::endl;
for (int i = 1; i <= n; i ++)
{
std::cout << code[i].data << ":" << code[i].code << " ";
}
std::cout << std::endl;
std::cout << "the Huffman Code of the string: " << std::endl;
for (int i = 0; i < s.size(); i ++)
{
for (int j = 1; j <= n; j ++)
{
if (s[i] == code[j].data)
{
std::cout << code[j].code;
arr += code[j].code;
break;
}
}
}
std::cout << std::endl;
std::cout << "The decode of the Huffman Code: " << std::endl;
std::cout << HuffDeCode(code, arr, n) << std::endl;
std::cout << "Data compression ratio: " << ((float)arr.size() / s.size() * 8) << "%" << std::endl;
}
output:
1 1 9 0 0
2 2 12 0 0
3 1 9 0 0
4 1 10 0 0
5 1 10 0 0
6 2 12 0 0
7 1 11 0 0
8 1 11 0 0
9 2 13 1 3
10 2 13 4 5
11 2 14 7 8
12 4 14 2 6
13 4 15 9 10
14 6 15 11 12
15 10 0 13 14
the Huffman Code of each char:
g:000 i:110 m:001 n:010 o:011 s:111 u:100 y:101
the Huffman Code of the string:
001110111111110010000101011100
The decode of the Huffman Code:
missingyou
Data compression ratio: 24%