二叉树相关代码

#include <bits/stdc++.h>
using namespace std;
typedef char ElemType; 

//二叉树
//1.二叉树链式储存定义
typedef struct BiNode{	// 二叉树的定义 
	ElemType data;	// 数据域 
	BiNode* lchild;	// 左孩子指针域 
	BiNode* rchild;	// 右孩子指针域 
	
	// 构造函数:给成员遍历做初始化
	BiNode(ElemType data, BiNode* lchild, BiNode* rchild) {
		this->data = data;
		this->lchild = lchild;
		this->rchild = rchild;
	}
	
}* BiTree;

void visit(BiNode* T) {
	if(T!=NULL) cout << T->data;
}
//递归遍历:
//2.二叉树先序遍历
void preOrder(BiTree T) {
// 先序递归遍历二叉树T
	if(T) {
		visit(T);	// 访问根节点
		preOrder(T->lchild);	// 递归访问左子树
		preOrder(T->rchild); 	// 递归访问右子树
	}		
} 
//3.	二叉树中序遍历
void inOrder(BiTree T) {
// 中序递归遍历二叉树T:LNR 
	if(T) {
		inOrder(T->lchild);	// 递归访问左子树
		visit(T);	// 访问根节点
		inOrder(T->rchild); 	// 递归访问右子树
	}		
} 
//4.	二叉树后序遍历
void postOrder(BiTree T) {
// 中序递归遍历二叉树T:LRN 
	if(T) {
		postOrder(T->lchild);	// 递归访问左子树
		postOrder(T->rchild); 	// 递归访问右子树
		visit(T);	// 访问根节点
	}		
} 

//非递归遍历:
//5.二叉树层次遍历
void level(BiTree T) {
// 层次遍历二叉树T:从上到下,从左到右
	if(T) {
		queue<BiNode*> Q;	// 队列	保存正在访问的结点 
		Q.push(T);			// 将根结点入队 
		while(!Q.empty()) {	// 队列里面还有结点,需要继续遍历
			BiNode* u = Q.front();	// 访问队头 
			Q.pop(); 				// 出队列(出队列的时候访问) 
			visit(u);
			if(u->lchild) Q.push(u->lchild);	// 如果有左孩子,则加入队尾 
			if(u->rchild) Q.push(u->rchild);	// 如果有右孩子,则加入队尾
		}
	} 
}
//6.	二叉树的先序非递归
void preOrder_NoRecursion(BiTree T) {
// 先序非递归函数 
	stack<BiNode*> S;	// 栈,保存递归入栈访问的结点 
	BiNode* p = T;		// 扫描指针 
	while(p || !S.empty()) {
		if(p) {	// 当前结点非空 
			visit(p);	// 先访问当前结点 
			S.push(p);	// 压入栈 
			p = p->lchild;	// 继续访问左子树 
		} else {	// 左子树访问完毕,要出栈访问右子树 
			p = S.top();	// 访问栈顶结点 
			S.pop(); 		// 出队 
			p = p->rchild;	// 往右走 
		}
	}
} 
//7.	二叉树的中序非递归
void inOrder_NoRecursion(BiTree T) {
// 中序非递归函数 
	stack<BiNode*> S;	// 栈,保存递归入栈访问的结点 
	BiNode* p = T;		// 扫描指针 
	while(p || !S.empty()) {
		if(p) {	// 当前结点非空  
			S.push(p);	// 压入栈 
			p = p->lchild;	// 继续访问左子树 
		} else {	// 左子树访问完毕,要出栈访问右子树 
			p = S.top();	// 访问栈顶结点 
			S.pop(); 		// 出队
			visit(p);	// 先访问当前结点 
			p = p->rchild;	// 往右走 
		}
	}
} 
//8.	二叉树的后序非递归
void postOrder_NoRecursion(BiTree T) {
// 后序非递归函数 LRN 
	stack<BiNode*> S;	// 栈,保存递归入栈访问的结点 
	BiNode* p = T;		// 扫描指针 
	BiNode* r = NULL;			// r指针来标记是从左子树返回还是右子树返回 
	while(p || !S.empty()) {
		if(p) {	// 当前结点非空  
			S.push(p);	// 压入栈 
			p = p->lchild;	// 继续访问左子树 
		} else {	// 左子树访问完毕,要出栈访问右子树 
			p = S.top();	// 访问栈顶结点 
			if(p->rchild && p->rchild!=r) {	// 如果右子树存在,没有被访问过 
				p = p->rchild;	// 往右走 
			} else {
				S.pop();	//	出栈 
				visit(p);		// 访问根
				r = p;		// 	记录最近被访问的结点
				p = NULL;	// 重置p指针,让他继续出栈访问上一层 
			}	
		}
	}
} 

struct Node {
	BiNode* node;
	bool flag;
}; 

void NoRecursion(BiTree T) {
	if(T==NULL) return;
	stack<Node> S;
	S.push(Node{T, false});		// 加入更节点
	while(!S.empty()) {
		Node u = S.top();
		S.pop();
		if(!u.flag) {	// flag为false说明第一次弹出,孩子节点还没有压入 
			u.flag = true;
			//先序 
//			if(u.node->rchild!=NULL) S.push(Node{u.node->rchild, false});
//			if(u.node->lchild!=NULL) S.push(Node{u.node->lchild, false});
//			S.push(u);
			//中序 
//			if(u.node->rchild!=NULL) S.push(Node{u.node->rchild, false});
//			S.push(u);
//			if(u.node->lchild!=NULL) S.push(Node{u.node->lchild, false});
			//后序
			S.push(u);
			if(u.node->rchild!=NULL) S.push(Node{u.node->rchild, false});
			if(u.node->lchild!=NULL) S.push(Node{u.node->lchild, false});
		} else {		// 第二次弹出,直接访问 
			visit(u.node);
		}
	} 
}


//二叉树的构造:
//9.	二叉树的先序+中序构造
BiTree buildFromPreIn(ElemType pre[], int l1, int r1, ElemType in[], int l2, int r2) {
// 根据先序遍历序列pre[l1, r1]和中序遍历in[l2, r2]构造二叉树
	if(l1>r1) return NULL;	// 递归边界:序列为空
	BiNode* root = new BiNode(pre[l1], NULL, NULL);	// 构造根结点
	int ind = l2;	// 中序里面根结点的位置
	while(in[ind] != root->data) ind++; 	// 在中序中查找根
	// 此时的先序 l1[l1+1, l1+llen][l1+llen+1, r1]  中序序列为[l2, ind-1]ind[ind+1, r2] 
	int llen = ind - l2; 
	root->lchild=buildFromPreIn(pre, l1+1, l1+llen, in, l2, ind-1); // 递归构造左子树 
	root->rchild=buildFromPreIn(pre, l1+llen+1, r1, in, ind+1, r2);// 递归构造右子树 
	return root; 
}
//10.	二叉树的后序+中序构造
BiTree buildFromPostIn(ElemType post[], int l1, int r1, ElemType in[], int l2, int r2) {
// 根据后序遍历序列post[l1, r1]和中序遍历in[l2, r2]构造二叉树
	if(l1>r1) return NULL;	// 递归边界:序列为空
	BiNode* root = new BiNode(post[r1], NULL, NULL);	// 构造根结点
	int ind = l2;	// 中序里面根结点的位置
	while(in[ind] != root->data) ind++; 	// 在中序中查找根
	// 此时的后序 [l1, l1+llen-1][l1+llen, r1-1] r1  中序序列为[l2, ind-1]ind[ind+1, r2] 
	int llen = ind - l2; 
	root->lchild=buildFromPostIn(post, l1, l1+llen-1, in, l2, ind-1); // 递归构造左子树 
	root->rchild=buildFromPostIn(post, l1+llen, r1-1, in, ind+1, r2);// 递归构造右子树 
	return root; 
}
//11.	二叉树的层次+中序构造
BiTree buildFromLevelIn(ElemType level[], int n, ElemType in[], int l2, int r2) {
// 根据层次遍历序列level[0, n)和中序遍历in[l2, r2]构造二叉树
	if(n<=0) return NULL;	// 递归边界:序列为空
	BiNode* root = new BiNode(level[0], NULL, NULL);	// 构造根结点
	int ind = l2;	// 中序里面根结点的位置
	while(in[ind] != root->data) ind++; 	// 在中序中查找根
	int llen = ind - l2; 
	// 筛选构造左子树的层次遍历和右子树的层次遍历 
	ElemType lchildLevel[llen];	
	ElemType rchildLevel[n-1-llen];
	int lind = 0, rind = 0;
	for(int i=1; i<n; i++) {	// 将整棵树的层次遍历筛选分为左右子树的层次遍历 
		int existL = 0;	// 标记level[i]是否存在左子树 
		for(int j=l2; j<ind; j++) {	// 在左子树中查找 中序序列为[l2, ind-1]ind[ind+1, r2] 
			if(level[i]==in[j]) {	// 找到 
				existL = 1; 	// 标记在左子树中 
				break;
			}
		}
		if(existL) {	// 不在左子树中 
			lchildLevel[lind++] = level[i];
		}
		else{
			rchildLevel[rind++] = level[i];	// 加入右子树 
		} 
	}
	
	root->lchild=buildFromLevelIn(lchildLevel, lind, in, l2, ind-1); // 递归构造左子树 
	root->rchild=buildFromLevelIn(rchildLevel, rind, in, ind+1, r2);// 递归构造右子树 
	return root; 
}
//二叉树相关统计:
//12.	统计二叉树度的叶子节点、单支节点、双枝节点的数量
int cnt = 0; 	// 全局变量在递归函数中统计 
void preOrderLeaf(BiTree T) {
// 先序递归遍历二叉树T中叶子结点 
	if(T) {
		if(T->lchild==NULL && T->rchild==NULL) cnt++;  
		preOrderLeaf(T->lchild);	// 递归访问左子树
		preOrderLeaf(T->rchild); 	// 递归访问右子树
	}		
} 

// 用返回值 
int preOrderLeaf2(BiTree T) {
// 先序递归遍历二叉树T中叶子结点 
	if(T) {
		if(T->lchild==NULL && T->rchild==NULL) return 1 + preOrderLeaf2(T->lchild) + preOrderLeaf2(T->rchild);  
		else return preOrderLeaf2(T->lchild) + preOrderLeaf2(T->rchild);	// 递归访问左子树
	}
	return 0;		
} 

//13.	统计二叉树中结点的最大值、最小值
ElemType maxV = 0; 	// 全局变量在递归函数中统计最大值 
void MaxByPreOrder(BiTree T) {
// 先序递归遍历二叉树T中最大值 
	if(T) {
		if(T->data>maxV) maxV = T->data; //在遍历中如果发现更大的值则更新当前最大值 
		MaxByPreOrder(T->lchild);	// 递归访问左子树
		MaxByPreOrder(T->rchild); 	// 递归访问右子树
	}		
} 
//14.	求二叉树高度(递归,非递归)
int HeithByPostOrder(BiTree T) {
// 通过后序递归遍历二叉树T求二叉树高度:LRN 
	if(T==NULL) return 0;	// 空树	
	int lh = HeithByPostOrder(T->lchild);	// 递归访问左子树
	int rh = HeithByPostOrder(T->rchild); 	// 递归访问右子树
	return (lh>rh?lh:rh) + 1; 				// 自己的高度等于子树中最大高度加1 
} 

int HeithByLevel(BiTree T) {
// 层次遍历二叉树T:从上到下,从左到右
	if(T) {
		queue<BiNode*> Q;	// 队列	
		Q.push(T);	// 将根结点入队 
		BiNode* r = T;	// 指向每一层最后一个节点,第一层的根节点就是最后一个节点 
		int level = 0;	// 统计二叉树的层次 
		while(!Q.empty()) {	// 队列里面还有结点,需要继续遍历
			BiNode* u = Q.front();	// 访问队头 
			Q.pop(); 				// 出队列 
			if(u->lchild) Q.push(u->lchild);	// 如果有左孩子,则加入队尾 
			if(u->rchild) Q.push(u->rchild);	// 如果有右孩子,则加入队尾
			//加入孩子以后再设置r的指向 
			if(u==r) {	// 当前已经访问这一层最后一个节点 
				level++;	// 层次增1
				r = Q.back();	// r指向下一层最后一个节点 
			}
		}
		return level; 
	} 
	return 0;	// 空树 
}
//15.	求二叉树宽度(递归,非递归)
int WeithByLevel(BiTree T) {
// 层次遍历二叉树T统计树的宽度:具有最多节点的层次的节点数量 
	if(T) {
		queue<BiNode*> Q;	// 队列	
		Q.push(T);	// 将根结点入队 
		int cnt = 0;	// 每一层的节点数量
		int maxcnt = 0;	// 树的宽带 
		BiNode* r = T;	// 标记每一层最后一个结点 
		while(!Q.empty()) {	// 队列里面还有结点,需要继续遍历
			BiNode* u = Q.front();	// 访问队头 
			Q.pop(); 				// 出队列 
			cnt++;	// 这一层的结点数量加1 
			if(u->lchild) Q.push(u->lchild);	// 如果有左孩子,则加入队尾 
			if(u->rchild) Q.push(u->rchild);	// 如果有右孩子,则加入队尾
			if(u==r) {	// 当前已经访问到最后一个结点 
				r = Q.back();	// 标记一下层最后一个结点
				if(cnt>maxcnt) maxcnt = cnt;	// 如果这一层的结点数量大于当前最大层结点数量,则更新
				cnt = 0;	// 清零,方便统计下一层结点数量 
			}
		}
		return maxcnt;
	} 
	return 0;	// 空树 
}

void WidthByPreOrder(BiTree T, int d, int* level) {
// 先序递归遍历二叉树T, d表示结点T所在层次,level数组统计每一层结点数量 
	if(T) {
		level[d]++;	// 第d层结点数量加1 
		WidthByPreOrder(T->lchild, d+1, level);	// 递归访问左子树
		WidthByPreOrder(T->rchild, d+1, level); 	// 递归访问右子树
	}		
} 
int Width(BiTree T) {
	int level[100];	 // level数组统计每一层结点数量
	memset(level, 0, sizeof(level));
	WidthByPreOrder(T, 1, level);
	int maxWidth = 0;
	for(int i=1; i<100 && level[i]>0; i++) {	// 遍历所有层次 
		if(level[i]>maxWidth) {	// 如果第i层结点数量大于maxWidth 
			maxWidth = level[i];	// 更新 
		}
	}
	return maxWidth;
}
//16.	求二叉树中第k层中结点数量
int cntLevelK(BiTree T, int d, int k) {
// 先序递归遍历二叉树T,统计第k层的结点数量。d表示当前结点层次 
	if(T && d<=k) { 										//  k <= 0 表示层次大于K 
		if(k==d) return 1;									// 第K层的结点 
		return cntLevelK(T->lchild, d+1, k) + cntLevelK(T->rchild, d+1, k);	// 递归统计左右子树的第K层结点数量 
	}	
	return 0;	// 空树或者大于第K层的结点	
} 
//17.	求x结点的所在层次
int getXLevel(BiTree T, ElemType x, int d) {
// 先序递归遍历二叉树T,得到x结点的所在层次d 
	if(T) { 	//  非空树
		if(T->data == x) return d;	// 第K层的结点 
		int k;
		if((k = getXLevel(T->lchild, x, d+1))>0) return k ;	// 在左子树上找,找到返回
		else return getXLevel(T->rchild, x, d+1);			// 否则在右子树上找 
	}	
	return 0;	// 没有找到	
} 
//二叉树性质判断:
//18.	判断二叉树是否为完全二叉树(使用层次遍历判断) 
int JudgeCBiTree(BiTree T) {
// 判断二叉树T是否为完全二叉树 
	if(T) {
		queue<BiNode*> Q;		// 队列	
		Q.push(T);				// 将根结点入队 
		while(!Q.empty()) {			// 队列里面还有结点,需要继续遍历
			BiNode* u = Q.front();	// 访问队头 
			Q.pop(); 				// 出队列 
			if(u==NULL) {			// 如果结点为空树
				// 判断队列里剩余的结点是否全部为空 
				while(!Q.empty()) {
					u = Q.front();		// 访问队头 
					Q.pop(); 			// 出队列 
					if(u!=NULL) {		// 有不为空结点 
						return 0;
					}
				} 
			} else {
				Q.push(u->lchild);	// 如果有左孩子,则加入队尾 
				Q.push(u->rchild);	// 如果有右孩子,则加入队尾
			}
			
		}
	} 
	return 1;	// 空树,或者非空完全二叉树 
} 
//=========================================判断============================================= 
//19.	判断两个二叉树是否为镜像(形状和值完全一样) 
int JudgeSame(BiTree T1, BiTree T2) {
// 判断二叉树T1和T2是否互为镜像树
	if(T1==NULL && T2==NULL) return 1;	// 空树互为镜像树
	if(T1==NULL || T2==NULL) return 0; 	// 一个为空,一个不为空,不是互为镜像
	return T1->data == T2->data && 		// 在两个都不为空数,数据域相同 
		JudgeSame(T1->lchild, T2->lchild) &&		// 并且左子树互为镜像 
		JudgeSame(T1->rchild, T2->rchild); 		// 并且右子树互为镜像时,这两棵												// 树才互为镜像  
}
//20.	同构 (有的翻转,有的不翻转)
int Judge(BiTree T1, BiTree T2) {
// 判断二叉树T1和T2是否互为镜像树
	if(T1==NULL && T2==NULL) return 1;	// 空树互为镜像树
	if(T1==NULL || T2==NULL) return 0; 	// 一个为空,一个不为空,不是互为镜像
	return T1->data == T2->data && 		// 在两个都不为空数,数据域相同 
		(JudgeSame(T1->lchild, T2->lchild) && JudgeSame(T1->rchild, T2->rchild))
		||JudgeSame(T1->lchild, T2->rchild) && JudgeSame(T1->rchild, T2->lchild)); 									
}
//21.	判断是否为二叉排序树
int JudgeBiSortTree(BiTree T, BiNode* & pre) {
// 利用二叉排序树的中序序列有序的特点来判断T是否为二叉排序树, pre表示当前节点T的中序序列前驱 
	if(T) {	// 非空 
		if(!JudgeBiSortTree(T->lchild, pre)) return 0;	// 如果左子树不是二叉排序树 
		if(pre!=NULL && T->data <= pre->data) return 0;	// 中序序列非升序  
		pre = T;	// 更新pre 
		if(!JudgeBiSortTree(T->rchild, pre)) return 0; // 如果左子树不是二叉排序树 
	}
	return 1;	// 空树或者if中的三个条件都不满足 
}
//22.	判断二叉排序树是否为平衡二叉树
int JudgebalancedBiTree(BiTree T, int& d) {
// 判断二叉树T是否为平衡二叉树:左右子树是平衡二叉树,平衡平衡因子为-1或者0或者1,d表示T树的高度 
	if(T==NULL) {	// 空树 
		d = 0;		// 高度为1 
		return 1;	// 是平衡二叉树 
	} 
	int ld, rd;	
	if(!JudgebalancedBiTree(T->lchild, ld)) return 0;	// 判断左子树不是平衡二叉树,并得到其高度 
	if(!JudgebalancedBiTree(T->rchild, rd)) return 0;
	d = (ld>rd?ld:rd)+1;	// 计算T的高度 
	return abs(ld-rd)<=1;	// 到这里表示左右子树已经平衡,只要判断平衡平衡因子是否为-1, 0, 1 
} 
//二叉树修改:
//23.	交换二叉树左右孩子
void swap(BiTree T) {
// 递归交换二叉树T左右孩子	
	if(T) {	// 非空 
		BiNode* temp = T->lchild;	// 交换该节点左右孩子 
		T->lchild = T->rchild;
		T->rchild = temp;
		swap(T->lchild);	// 递归交换左右子树 
		swap(T->rchild);			
	}
}
//24.	删除二叉树,并释放空间
void deleteBiTree(BiTree T) {
	if(T) {	// 非空 
		deleteBiTree(T->lchild);	// 递归删除左右子树 
		deleteBiTree(T->rchild);
		delete(T);					// 删除根节点,C语言用free(T)	
	}
}
//25.	删除以结点值X为根的子树(要拿到父结点)
BiNode* deleteAllXByLevel(BiTree T, ElemType x) {
// 通过层次遍历二叉树T删除结点X,已经以他为根的子树,返回删除后的二叉树 
	if(T) {
		if(T->data == x) {	// 根结点为x 
			deleteBiTree(T);
			return NULL;
		} 
		queue<BiNode*> Q;	// 队列	
		Q.push(T);	// 将根结点入队 
		while(!Q.empty()) {	// 队列里面还有结点,需要继续遍历
			BiNode* u = Q.front();	// 访问队头 
			Q.pop(); 				// 出队列 
			
			if(u->lchild) {	// 如果有左孩子 
				if(u->lchild->data == x) {	// 左孩子为x 
					deleteBiTree(u->lchild);	// 删除左子树 
					u->lchild = NULL;	
				} else {	// 否则加入队尾 
					Q.push(u->lchild);	 
				}
			} 
			if(u->rchild) {
				if(u->rchild->data == x) {
					deleteBiTree(u->rchild);
					u->rchild = NULL;	
				} else {
					Q.push(u->rchild);	// 如果有左孩子,则加入队尾 
				}
			} 
		}
	} 
	return T;
}
//二叉树祖先结点:
//26.	 查找结点x的所有祖先结点
void findFather(BiTree T, ElemType x) {
// 后序非递归函数 LRN 
	stack<BiNode*> S;	// 栈,保存递归入栈访问的结点 
	BiNode* p = T;		// 扫描指针 
	BiNode* r = NULL;			// r指针来标记是从左子树返回还是右子树返回 
	while(p || !S.empty()) {
		if(p) {	// 当前结点非空  
			S.push(p);	// 压入栈 
			p = p->lchild;	// 继续访问左子树 
		} else {	// 左子树访问完毕,要出栈访问右子树 
			p = S.top();	// 访问栈顶结点 
			if(p->rchild && p->rchild!=r) {	// 如果右子树存在,没有被访问过 
				p = p->rchild;	// 往右走 
			} else {
				S.pop();	//	出栈 
				if(p->data == x) {	// 如果当前访问到x了,则栈中所有元素都是x的祖先 
					while(!S.empty()) {	// 依次访问栈中所有元素 
						visit(S.top());
						S.pop();
					}
				}
				r = p;		// 	记录最近被访问的结点
				p = NULL;	// 重置p指针,让他继续出栈访问上一层 
			}	
		}
	}
} 

stack<BiNode*> s;
int found = 0;	// 标记是否找到x 
void findFather2(BiTree T, ElemType x) {
	if(T && found==0) {	// T非空并且没有找到x 
		if(T->data == x) {	// 栈中所有元素都是x的祖先 
			while(!s.empty()) {	// 依次访问栈中所有元素 
				visit(s.top());
				s.pop();
			}
			found = 1;
		} else {
			s.push(T); // 访问当前结点,这将当前结点加入到栈中 
			findFather2(T->lchild, x);
			findFather2(T->rchild, x);
			s.pop();
		} 
	}
} 

//27.	查找二叉树结点p和q的最近公共祖先结点
BiNode* findLastFather(BiTree T, ElemType x1, ElemType x2) {
// 后序非递归函数 LRN 
	stack<BiNode*> S;	// 栈,保存递归入栈访问的结点 
	BiNode* p = T;		// 扫描指针 
	BiNode* r = NULL;			// r指针来标记是从左子树返回还是右子树返回
	stack<BiNode*> s1;	// 保存x1的祖先
	stack<BiNode*> s2;	// 保存x2的祖先
	 
	while(p || !S.empty()) {
		if(p) {	// 当前结点非空  
			S.push(p);	// 压入栈 
			p = p->lchild;	// 继续访问左子树 
		} else {	// 左子树访问完毕,要出栈访问右子树 
			p = S.top();	// 访问栈顶结点 
			if(p->rchild && p->rchild!=r) {	// 如果右子树存在,没有被访问过 
				p = p->rchild;	// 往右走 
			} else {
				S.pop();	//	出栈 
				if(p->data == x1) {	// 如果当前访问到x了,则栈中所有元素都是x的祖先 
					s1 = S;
				} else if(p->data == x2) {
					s2 = S;
				}
				r = p;		// 	记录最近被访问的结点
				p = NULL;	// 重置p指针,让他继续出栈访问上一层 
			}	
		}
	}
	if(s1.empty() || s2.empty()) return NULL;	// x1或x2不在树中 
	
	while(s1.size() != s2.size()) {	// 将祖先结点多的出栈,让栈顶元素在二叉树的同一层 
		if(s1.size()>s2.size()) {	 
			s1.pop();
		} else {
			s2.pop();
		}
	}
	while(s1.top() != s2.top()) {	// 如果当前祖先不相同,同时往上退栈 
		s1.pop();
		s2.pop();
	}
	return s1.top();
} 
//二叉树的存储转换
//28.	顺序存储转换为链式存储
void BiTreeSeqToLink(ElemType ST[], int n, int u, BiTree& T) {
// 将顺序存储的二叉树ST(长度为n)转换为链式存储T, u为当前节点
	if(u>=n || ST[u]==0) {		// 空树 
		T = NULL; return;
	}
	T = (BiTree)malloc(sizeof(BiNode));		// 构造根节点 
	T->data = ST[u];
	BiTreeSeqToLink(ST, n, u*2, T->lchild);		// 递归构造做子树
	BiTreeSeqToLink(ST, n, u*2+1, T->rchild);	// 递归构造做子树
} 
//29.	链式存储转换为顺序存储
int BiTreeLinkToSeq(BiTree T, ElemType* ST, int& n, int u) {
// 将顺序存储的二叉树ST(长度为n)转换为链式存储T, u为当前节点
	if(u>=n) {
		ST = (ElemType*)realloc(ST, sizeof(ElemType)*n*2);
		n = n*2;
		if(!ST) return 0;
	} 
	if(T = NULL) {		// 空树 
		 ST[u] = 0 ;
		 return 1;
	}		 
 	ST[u] = T->data; 	// 构造根节点
	if(!BiTreeLinkToSeq(T->lchild, ST, n, u*2)) return 0;		// 递归构造做子树
	if(!BiTreeLinkToSeq(T->rchild, ST, n, u*2+1)) return 0;		// 递归构造做子树
	return 1;
} 
//二叉排序树
//30.	二叉排序树查找值x
BiNode* BSTSearch(BiTree T, ElemType key, BiNode* &p) {
// 在二叉排序树中查找结点值为key的结点并返回,p为它的父节点	
	p = NULL;
	while(T!=NULL && T->data != key) {	// 没有找到,并且没有查找完 
		p = T;	// 更新父节点 
		if(key<T->data) {	// 带查找的值在左子树 
			T = T->lchild;
		} else { // 带查找的值在右子树
			T = T->rchild;
		}
	}
	return T; 
}
//31.	二叉排序树插入
int BSTInsert(BiTree& T, ElemType key) {
// 将关键子k插入二叉排序树T中
	if(T==NULL) {	// 递归边界,树为空,则将关键字作为根结点 
		T = new BiNode(key, NULL, NULL);
		return 1; 
	} else if(T->data == key){ // 关键字在树中,无法插入 
		return 0;
	} else if(key < T->data) {	// key小于根结点,应该插入到左子树中 
		return BSTInsert(T->lchild, key);
	} else {
		return BSTInsert(T->rchild, key);
	}
}
//32.	二叉排序树的构造
void buildBST(BiTree& T, ElemType keys[], int n) {
// 将长度为n的关键字数组依次插入到二叉排序T
	T = NULL;
	for(int i=0; i<n; i++) {	// 依次插入二叉排序树中 
		BSTInsert(T, keys[i]);
	} 
}

int main() {
	//自己手动构造一棵二叉树
	BiNode* a1 = new BiNode('1', NULL, NULL);
	BiNode* a4 = new BiNode('4', NULL, NULL);
	BiNode* a3 = new BiNode('3', a1, a4);
	BiNode* a9 = new BiNode('9', NULL, NULL);
	BiNode* a8 = new BiNode('8', NULL, a9);
	BiNode* a5 = new BiNode('5', a3, a8);
	BiNode* root = a5;
	
	//preOrder(root);
	//inOrder(root);
	//postOrder(root);
	
	//level(root);
	//preOrder_NoRecursion(root);
	//inOrder_NoRecursion(root);
	//inOrder_NoRecursion(root);
	//postOrder_NoRecursion(root);
	
	//NoRecursion(root);
//	ElemType pre[] = "531489";
//	ElemType in[] = "134589";
//	ElemType post[] = "143985";
	return 0;
}
发布了44 篇原创文章 · 获赞 1 · 访问量 2313

猜你喜欢

转载自blog.csdn.net/Do_________/article/details/102992391