[Data Structure and Algorithm] Learning Record Collection (05) Binary Tree

  • This collection is the study record of the "C++ Data Structure and Algorithm" course that the author self-study on the b station. It aims to record the important learning points, thinking content and part of the code, so that it can be read by yourself later, and it can also bring some information to other readers. refer to
  • The content is based on the author’s own understanding or perception, and may contain inappropriate or incorrect contents.
  • System environment: Win10, Visual Studio 2019
  • The pictures in the article refer to the online course handouts of Northeastern University's "Data Structure and Algorithm Design" (2020)

Table of contents

1. BinaryTree binary tree

2. Binary linked list

3. Binary array 

4. Traversals

5. Non-recursive call of binary tree

6. Clue tree

7. Priority Queue

8. Huffman tree

9. Tree (ordinary)

10. Trees in STL

Attached binary tree C++ implementation code


1. BinaryTree binary tree

A nonlinear hierarchical abstract model

A binary tree has its constituent elements:

root: root node, the starting point of the tree, if there is no root node, it is an empty tree

nodes: nodes, the constituent elements of the tree, roots and leaves also belong to nodes

branches: branch. A node can have branches or no branches. A node in a binary tree can have at most two branches.

leaves: leaves, the "end" of the tree, leaf nodes have no successor nodes

Nouns used to describe the building blocks of a tree:

Depth (of a node): Depth, the number of upward generations that a node has, the depth of the root is 0

height(of a tree): height, the maximum depth of the entire tree

Degree (of a node): degree, the number of descendants of the node in the next generation, the maximum number of binary trees is 2

degree(of a tree): the maximum value of the node degree in the tree

subtree: subtree, a tree rooted at the successor node of a node

Siblings: sibling nodes. Nodes that share a parent node are brothers of each other.

internal node: internal node, a node with at least one child node

external node: external node, a node without child nodes

ancestors: ancestors, their parent nodes, grandparent nodes, great-grandfather nodes...

descendant: descendant, its child nodes, grandchild nodes...

Characteristics of binary trees

  • The degree of a binary tree is less than or equal to 2. Its child nodes have left and right positions, and their positions cannot be interchanged.
  • Assuming that a binary tree has n nodes, there are (2n!) / ((n+1)! n!) possible structures that this binary tree may present.
  • A binary tree of height k can have at most 2^(k+1) - 1 nodes.
  • Assume n0 is the number of nodes with degree 0 in the binary tree, and n2 is the number of nodes with degree 2, then there is the equation n0 = n2 + 1
Possible styles of binary trees

Full binary tree full binary tree

That is to say, a binary tree that meets the requirement of "a binary tree with a height of k has 2^(k+1) - 1 nodes". From a visual point of view, the tree has no "default nodes", and some foreign textbooks have a definition of a full binary tree. The difference is that "as long as a node in the binary tree has child nodes, the number of its child nodes must be 2."

If a full binary tree is numbered row by row in increasing order from left to right, the result obtained by dividing its number by 2 is the parent node (except the root), the number *2 is its left subtree (if it exists), and the number *2+1 is its left subtree Right subtree (if exists)

Complete binary tree Complete binary tree

Different from the full binary tree, the complete binary tree can continuously default the right elements of the last level.


2. Binary linked list

Represent binary tree structure in the form of linked list

Binary linked lists use a large number of null pointers to represent nodes that have no children.

Memory space is spent in the node of the binary linked list to point to its parent


3. Binary array 

Use arrays to represent binary tree structures

The array implementation of a binary tree uses the positional relationship of elements in memory to cleverly represent the inheritance relationship between nodes. However, if a binary array is used to represent a degenerate binary tree, space will be wasted (a large number of φ is used to represent empty elements)


4. Traversals

Use the root-first order (rLR), middle-root order (LrR) and late-root order (LRr) methods to traverse binary trees

  • First traverse in root order:

  • Middle root order traversal:

  • Post-root order traversal:


5. Non-recursive call of binary tree

Users manage Runtime Stack by themselves

  •  The non-recursive call of the binary tree allows programmers to manage the runtime stack (explicit stack) by themselves, and it is executed in the user thread. There is no need to frequently switch and interrupt handover permissions. It is necessary to manually save important historical node addresses into the stack and pop them up when needed.
  • You can design an Iterater class to assist
  • Level order level traversal/breadth traversal


 

6. Clue tree

Binary tree with pointer clues

 The leaf node of the binary tree has two null pointers, which is a waste of space. We use this part of the space to store the address of the predecessor or successor node under certain traversal rules, which can help improve the efficiency of binary tree traversal. The null pointer in the binary linked list The address added on becomes a clue

 left child: When Pred is 0, it points to the left subtree address; when Pred is 1, it points to the predecessor node.

Pred: left mark, used to mark the situation where the left child points to the address

data: data content

Succ: right mark, used to mark the situation where the right child points to the address

right child: When Succ is 0, it points to the right subtree address; when Succ is 1, it points to the successor node.

Under Pre traversal, there are as many clues as there are nuptr

Post traversal, the clues did not provide much help

In traversal, no stack is needed, there is a "head node"


 

7. Priority Queue

Binary tree structure with priority distinction

 Based on Heap implementation, when using an unordered linked list, insertion can reach O(1) and deletion can reach O(n). When using an ordered list, insertion can reach O(n) and deletion can reach O(1).

Windows divides priorities into 0~31, with a total of 32 levels. Among them, the system process has a higher priority, occupying 16~31, and the user process occupies 0~15. This is PCB-level support, so we want to achieve priority from the data structure direction. level, you can consider a binary heap

The binary heap is implemented using a complete binary tree and has ordered characteristics. It can also be divided into a large root heap (Max-Heap) and a small root heap (Min-Heap). The former is more commonly used, and the time complexity of both insertion and deletion operations is O. (log2n), better than chain linear order


 

8. Huffman tree

Optimal solution

Path, path length, weight, weighted path length ( WPL , P ath Length of a tree with W eights)

Construct a tree using the weight sequence as the leaves of the tree. There are n leaves, 2n-1 nodes, and n-1 nodes with degree 2. Construct a binary tree in the minimum WPL form, which is a Huffman tree (may not be unique) , can be used to find optimal solutions, optimize code efficiency, create prefix codes for communication, etc.


 

9. Tree (ordinary)

If ordinary trees and forests are converted into binary trees, you can use binary tree related methods to operate.

parent means

Suitable for situations where parent nodes are often searched

children means

The parent node has a pointer pointing to the head of the child node list (there can be multiple child nodes), which is suitable for frequently searching for child nodes.

parent - children means

Combining the above two methods of expression

First child - Next sibling display

Convert an ordinary tree into a unique binary tree according to certain rules. The binary tree has no right subtree. The pre traversal result before conversion is the same as after conversion. The post traversal result before conversion is the same as the in traversal result after conversion.

forest to binary tree

Convert multiple ordinary trees into a binary tree according to certain rules. The pre traversal result before conversion is the same as after conversion. The in traversal result before conversion is the same as the in traversal result after conversion.


 

10. Trees in STL

Functions provided in C++’s STL

 set

Binary search tree can reach O(logn), the elements are not repeatable, and it is suitable for set operations.

priority queues

Based on Heap, the priority can be customized

map

Find collection elements by key, <key value, data>, for example:

#include <map>

map<string, string> m1;
m1.insert(pair<string, string>("apple", "a amall red fruit"));
cout << m1["apple"] << endl; //类似于数组的下标索引


 

Attached binary tree C++ implementation code

Programming in C++ to implement a simple binary tree class

#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;

// 定义二叉树节点类
class BiTreeNode {
public:
	int data;
	BiTreeNode* leftChild;
	BiTreeNode* rightChild;
	// 初始化列表,直接将 elem 置入data中
	BiTreeNode(int elem) :data(elem) {}
};

// 二叉树类,借助节点类来实现
class BinaryTree {
private:
	// 节点* 类型的根节点
	BiTreeNode* root;
	// 置空函数,运用递归思想,将current指向的二叉树回收
	void makeEmpty(BiTreeNode* current);
	// 重载方法Create,注意是引用参数,方便递归
	void Create(BiTreeNode*& current);
	// 重载递归实现
	void PreOrder(BiTreeNode* current);
	void InOrder(BiTreeNode* current);
	void PostOrder(BiTreeNode* current);
public:
	// 构造函数, 初始化列表构造空树
	BinaryTree() :root(NULL) {}
	// 析构方法
	~BinaryTree();
	// 对外提供Create接口,实现二叉树的创建
	void Create();
	// 对外提供三种遍历接口,先根,中根,后根遍历
	void PreOrder();
	void InOrder();
	void PostOrder();
};

// 析构方法的实现
BinaryTree::~BinaryTree() {
	// 将整个二叉树删除
	makeEmpty(root);
}

// 置空方法的实现,传入的是节点类型的current指针
void BinaryTree::makeEmpty(BiTreeNode* current) {
	// 递归条件,只要current不为空
	if (current != NULL) {
		// 递归删除左右子树
		makeEmpty(current->leftChild);
		makeEmpty(current->rightChild);
		delete current;
	}
}

// 创建树方法的实现,调用其重载方法
void BinaryTree::Create() {
	Create(root);
}


void BinaryTree::Create(BiTreeNode*& current) {
	int elem;
	// 读入一个元素到elem中
	cin >> elem;
	// elem等于零,则是空树
	if (elem == 0) {
		current = NULL;
	}
	else {
		current = new BiTreeNode(elem);
		// 递归创建树
		Create(current->leftChild);
		Create(current->rightChild);
	}
}

void BinaryTree::PreOrder() {
	// 对以root为根的二叉树进行先根序遍历
	PreOrder(root);
}

void BinaryTree::PreOrder(BiTreeNode* current) {
	if (current != NULL) {
		cout << current->data << "    ";
		PreOrder(current->leftChild);
		PreOrder(current->rightChild);
	}
}

void BinaryTree::InOrder() {
	// 对以root为根的二叉树进行中根序遍历
	InOrder(root);
}

void BinaryTree::InOrder(BiTreeNode* current) {
	if (current != NULL) {
		InOrder(current->leftChild);
		cout << current->data << "    ";
		InOrder(current->rightChild);
	}
}

void BinaryTree::PostOrder() {
	// 对以root为根的二叉树进行后根序遍历
	PostOrder(root);
}

void BinaryTree::PostOrder(BiTreeNode* current) {
	if (current != NULL) {
		PostOrder(current->leftChild);
		PostOrder(current->rightChild);
		cout << current->data << "    ";
	}
}

int main()
{
	BinaryTree myTree;
	myTree.Create();
	myTree.PreOrder(); cout << endl;
	myTree.InOrder(); cout << endl;
	myTree.PostOrder(); cout << endl;
	return 0;
}

The End

 

 

 

Guess you like

Origin blog.csdn.net/Norths_/article/details/125588950