6.2 Tree and binary tree - storage structure and traversal of binary tree

1. Storage structure of binary tree

1.1. Sequential storage structure

#define MAX_TREE_SIZE 100 // 二叉树的最大结点数
typedef int TElemType;
typedef TElemType SqBiTree[MAX_TREE_SIZE]; // 0号单元存储根结点
SqBiTree bt;

1.2. Binary linked list storage structure

typedef struct BiTNode{
    
    
	TElemType data;
	struct BiTNode * lchild, * rchild;
} BiTNode, * BiTree;

1.3, triple linked list storage structure

typedef struct TriTNode{
    
    
	TElemType data;
	struct TriTNode * lchild, * rchild;
	struct TriTNode * parent;
} TriTNode, * TriTree;

1.4, parent linked list storage structure

typedef struct BiPTNode{
    
    
	TElemType data;
	int * parent;
	char LRTag;
}BiPTNode;

typedef struct BiPTree{
    
    
	BiPTNode nodes[MAX_TREE_SIZE];
	int num_node;
	int root;
}BiPTree;

2. Binary tree traversal (graphic)

2.1 Preorder traversal: [ 先访问根节点] around the root

Visit the root node first, then visit the left subtree in sequence, and then visit the right subtree in sequence
insert image description here

2.2 Inorder traversal: [ 中间访问根节点] left root right

First traverse the left subtree in inorder, then visit the root node, and then traverse the right subtree in inorder
insert image description here

2.3 Post-order traversal: [ 最后访问根节点] left and right roots

First traverse the left subtree in inorder, then traverse the right subtree in inorder, and then visit the root node
insert image description here

2.4 Two kinds of traversal sequences are known to find the original binary tree

Through [pre-order and in-order] or [in-order and post-order] we can restore the original binary tree.
However, the original binary tree cannot be restored through [preorder and postorder].


Example 1 : Known, preorder: ABCDEFGH, inorder: BDCEAFHG, find postorder.
Answer: DECBHGFA (the original binary tree needs to be drawn according to the pre-order and in-order).
insert image description here


Example 2 : Known, preorder: ABDGHCEFI, inorder: GDHBAECIF, find postorder.
Answer: GHDBEIFCA (the original binary tree needs to be drawn according to the pre-order and in-order).
insert image description here


Example 3 : Known, inorder: BDCEAFHG, postorder: DECBHGFA, find preorder.
Answer: ABCDEFGH (the original binary tree needs to be drawn according to the inorder and postorder).
insert image description here


3. Binary tree traversal (code)

3.1, recursive traversal binary tree description

	//先序遍历二叉树
	/*
	采用二叉链表存储结构,Visit是对数据元素操作的应用函数
	先序遍历二叉树T的递归算法,对每个数据元素调用函数Visit。
	最简单的Visit函数是:
	Status PrintElement(TElemType e){// 输出e的值
		printf(e);					 // 使用时,加上格式串
		return OK;
	}
	// 调用实例:PreOrder(T, PrintElement);
	*/
void PreOrder(BiTree T, void (*visit)(TElemType &e)){
    
    
	if(T){
    
    
		visit(T->data); //访问结点
		PreOrder(T->lchild, visit); //遍历左子树
		PreOrder(T->rchild, visit); //遍历右子树
	}
} //PreOrder

3.2, non-recursive traversal binary tree description

// 非递归中序遍历二叉树 -- start
BiTNode * GoFarLeft(BiTree T, Stack * S){
    
    
	if(!T){
    
    
		return NULL;
	}
	while(T->lchild){
    
    
		Push(S, T);
		T = T->lchild;
	}
	return T;
}
void InOrderNonRecursive(BiTree T, void (* visit)(TElemType &e)){
    
    
	Stack * S;
	BiTNode * t = GoFarLeft(T, S);// 找到最左下的结点
	while(t){
    
    
		visit(t->data);
		if(t->rchild){
    
    // 
			t = GoFarLeft(t->rchild, S);
		}else if(!StackEmpty(S)){
    
     // 栈不空时退栈
			t = Pop(S);
		}else{
    
    // 栈空表明遍历结束
			t = NULL;
		}
	}
}

4. The application of traversal

4.1. Count the number of leaf nodes in the binary tree (recursive pre-order traversal)

void CountLeaf(BiTree T, int &count){
    
    
	if(T){
    
    
		if((!T->lchild) && (!T->rchild)){
    
    
			count++;
		}
		CountLeaf(T->lchild, count); 
		CountLeaf(T->rchild, count);
	}
}

4.2. Find the depth of the binary tree (post-order traversal)

The depth of the binary tree = M ax {the depth of the left subtree, the depth of the right subtree} + 1 depth = M ax { dl , dr } + 1 \begin{aligned} & the depth of the binary tree=Max\{the depth of the left subtree ,\ The depth of the right subtree\}+1 \\ &depth=Max\{d_{l},\ d_{r}\}+1 \end{aligned}The depth of the binary tree=M a x { the depth of the left subtree , depth of right subtree }+1depth=Max{ dl, dr}+1

int Depth(BiTree T){
    
    
	if(!T){
    
    
		depthVal = 0;
	}else{
    
    
		depthLeft = Depth(T->lchild);
		depthRight = Depth(T->rchild);
		depthVal = 1 + (depthLeft > depthRight ? depthLeft : depthRight);
	}
	return depthVal;
}

4.3, Copy the binary tree (post-order traversal)

//生成一个二叉树的结点
BiTNode * GetTreeNode(TElemType item, BiTNode *lptr, BiTNode *rptr){
    
    
	T = (BiTNode *)malloc(sizeof(BiTNode));
	if(!T){
    
    
		exit(1);
	}
	T->data = item;
	T->lchild = lptr;
	T->rchild = rptr;
	return T;
}

BiTNode *CopyTree(BiTNode *T){
    
    
	if(!T){
    
    
		return NULL;
	}
	if(T->lchild){
    
    
		newlptr = CopyTree(T->lchild);
	}else{
    
    
		newlptr = NULL;
	}
	if(T->rchild){
    
    
		newrptr = CopyTree(T->rchild)
	}else{
    
    
		newrptr = NULL;
	}
	newnode = GetTreeNode(T->data, newlptr, newrptr);
	return newnode;
}

先序序列4.4. Build a binary tree according to the given

Tentative:
the empty tree uses " "
"root" "left subtree" "right subtree" to build a binary tree
according to the given添加空格的完整的先序序列
insert image description here

Status CreateBiTree(BiTree &T){
    
    
	scanf(&ch);
	if(ch == ' '){
    
    
		T = NULL;
	}else{
    
    
		T = (BiTNode *)malloc(sizeof(BiTNode));
		if(!T){
    
    
			exit(OVERFLOW);
		}
		T->data = ch; //生成根结点
		CreateBiTree(T->lchild); //构造左子树
		CreateBiTree(T->rchild); //构造右子树
	}
	return OK;
} //CreateBiTree

4.5. Build a binary tree from a sequence of expressions

Build a tree from a prefix expression
For example: the prefix expression of a known expression − × + a b c / d e -\times+a\ b\ c/d\ e×+ a b c / d e   

1 A binary tree is built from an expression sequence with spaces
2 先序A binary tree is built from 后序an expression expression
3 A binary tree is built from an original expression

原表达式 建立二叉树
void CrtExpTree(BiTree &T, char exp[]){
    
    
	InitStack(S); //运算符栈
	Push(S, '#');
	InitStack(PTR); //操作数栈
	p = exp;
	ch = *p;
	while(!(GetTop(S) == '#' && ch == '#')){
    
    
		if(!IN(ch, OP)){
    
     //ch不是运算符
			CrtNode(t, ch); //建叶子结点并入栈
		}else{
    
     //ch是运算符
			switch(ch){
    
    
				case '(': 
					Push(S, ch);
					break; //
				case ')':
					Pop(S, c);
					while(c != '('){
    
    
						CrtSubTree(t, c);//建二叉树并入栈
						Pop(S, c);
					}
					break;
				default: 
					while(!GetTop(S, c)&& (Precede(c, ch))){
    
    
						CrtSubTree(t, c);
						Pop(S, c);
					}
					if(ch != '#'){
    
    
						Push(S, ch);
					}
					break;// default
			}// switch
		}// else
		if(ch != '#'){
    
    
			p++;
			ch = *p;
		}
	}// while
	Pop(PTR, T);
} //CrtExpTree

//建叶子结点的算法为:
void CrtNode(BiTree &T, char ch){
    
    
	T = (BiTNode *)malloc(sizeof(BiTNode));
	T->data = ch;
	T->lchild = T->rchild = NULL;
	Push(PTR, T);
}


//建子树的算法为:
void CrtSubTree(BiTree& T, char c){
    
    
	T = (BiTNode *)malloc(sizeof( BiTNode));
	T->data = c;
	Pop(PTR, rc);
	T->rchild = rc;
	Pop(PTR, lc);
	T->lchild = lc;
	Push(PTR, T);
}

4.6. Build a tree from the preorder and inorder sequences of the binary tree

Inorder: left subtree root right subtree
Preorder: root...
postorder:...root

For example:
the preorder sequence of the known binary tree: abcdefg
inorder sequence: cdbaegf
analysis can be obtained:
the root node is a,
the left subtree is cdb,
the right subtree is egf

=========================================================================

typedef enum PointerTag {
    
    Link, Thread};// Link==0指针, Thread==1线索
typedef int TElemType;

//线索链表,线索二叉树,线索化
typedef struct BiThrNode{
    
    
	TElemType data;
	struct BiThrNode * lchild, * rchild;//左右孩子指针
	PointerTag LTag, RTag;// 左右标志
}BiThrNode, * BiThrTree;

// 4. The clue linked list storage structure


Guess you like

Origin blog.csdn.net/Michael_lcf/article/details/88114616#comments_25555982