日撸 Java 三百行的 CPP 实现(21-30天, 树与二叉树)

Day 21-30

This part is the CPP implementation of 日撸 Java 三百行(21-30天,树与二叉树).

Day 21: 二叉树的深度遍历的递归实现

实现一个 BinaryCharTree 类, 并手动构建一个二叉树. 使用递归实现二叉树的前序遍历、中序遍历、后序遍历. 使用递归实现获取二叉树的层数、节点数函数.

日撸 Java 三百行的 CPP 实现(21-30天, 树与二叉树)_第1张图片

#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 22: 二叉树的存储

对于任意一棵二叉树, 我们可以将其转换为满二叉树来存储. 以 Day 21 的数据为例, 将其转换为满二叉树并编号的结果如图所示:
日撸 Java 三百行的 CPP 实现(21-30天, 树与二叉树)_第2张图片

其中, 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

Day 23: 使用具有通用性的队列

使用 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 24: 二叉树的建立

今天的内容相当于 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

Day 25: 二叉树的深度遍历的栈实现(中序)

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

Day 26: 二叉树的深度遍历的栈实现(前序和后序)

#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

Day 27: Hanoi 塔问题

#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: Huffman 编码(节点定义与文件读取)

Day 29: Huffman 编码(建树)

Day 30: Huffman 编码(编码与解码)

以下为 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%

你可能感兴趣的:(数据结构,c++)