二叉树相关知识点
- 前序遍历与中序遍历可以唯一确定一棵二叉树。在前序遍历中,第一个结点必定是二叉树的根结点;在中序遍历中,该根结点必定可以将中序遍历的序列拆分为两个子序列,前一个子序列就是根结点左子树的中序遍历序列,而后一个子序列就是根结点右子树的中序遍历序列。
- 后序遍历与中序遍历也可以唯一确定一棵二叉树。后序遍历的最后一个结点就如同前序遍历的第一个结点,必定是二叉树的根节点。
- 先序遍历与后序遍历不唯一确定一颗二叉树。但若该树是一颗满二叉树,即每个结点都只有0个或2个子结点的二叉树,那么可以唯一确定。
中序序列可以与先序序列、后序序列、层序序列中的任意一个来构建唯一的二叉树,而后三者两两搭配或是三个一起上都无法构建唯一的二叉树。(中序序列能区分出左右子树)
二叉树要么为空,要么由根结点、左子树、右子树构成,而左右两个子树又分别是一棵二叉树。
二叉排序树相关知识点
若各个数字插入的顺序不同,那么得到的二叉排序树的形态很可能不同
但,对二叉排序树进行中序遍历,不管插入顺序是什么,其遍历结果必然是一个升序序列
- 若左子树非空,则左子树上所有结点关键字的值均小于根结点关键字的值
- 若右子树非空,则右子树上所有结点关键字的值均大于根结点关键字的值
- 左右子树本身也是一棵二叉排序树
代码
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
struct TreeNode{ // 树结点定义
char data;
TreeNode* leftChild;
TreeNode* rightChild;
TreeNode(char c):data(c),leftChild(NULL),rightChild(NULL){}
};
struct TreeNodeInt{
int data;
TreeNodeInt* leftChild;
TreeNodeInt* rightChild;
TreeNodeInt(int c):data(c),leftChild(NULL),rightChild(NULL){}
};
// 根据先序遍历的结果,建立对应的二叉树
// 注意参数position是整型引用,而非整型变量
// str 形如 'abc##de#g##f###'
TreeNode* Build(int& position, string str){
char c = str[position++];
if(c=='#'){
return NULL;
}
TreeNode* root = new TreeNode(c);
root->leftChild = Build(position, str);
root->rightChild = Build(position, str);
return root;
}
// 根据前序遍历(str1)和中序遍历(str2)的结果,建立对应的二叉树
// 例如:str1=abc, str2=bac,可以得到后序遍历的结果是bca
TreeNode* Build(string str1, string str2){
if(str1.size()==0) return NULL;
char c = str1[0];
TreeNode* root = new TreeNode(c);
int position = str2.find(c); // 寻找切分点
root->leftChild = Build(str1.substr(1,position),str2.substr(0,position));
root->rightChild = Build(str1.substr(position+1),str2.substr(position+1));
return root;
}
// 根据后序遍历(str1)和中序遍历(str2)的结果,建立对应的二叉树
// 例如:str1=bca, str2=bac,可以得到先序遍历的结果是abc
TreeNode* BuildInPost(string str1, string str2){
int len = str1.size();
if(len==0) return NULL;
char c = str1[len-1];
TreeNode* root = new TreeNode(c);
int position = str2.find(c); // 寻找切分点
root->leftChild = BuildInPost(str1.substr(0,position),str2.substr(0,position));
root->rightChild = BuildInPost(str1.substr(position,len-position-1),str2.substr(position+1));
return root;
}
// 向二叉排序树插入新值 x
TreeNodeInt* InsertOrder(TreeNodeInt* root, int x, int father){
if(root==NULL){
root = new TreeNodeInt(x);
printf("%d\n",father);
}else if(x<root->data){
root->leftChild = InsertOrder(root->leftChild,x,root->data);
}else{
root->rightChild = InsertOrder(root->rightChild,x,root->data);
}
return root;
}
// 构建一棵二叉排序树
TreeNodeInt* BuildOrder(int arr[],int num){
TreeNodeInt* root = NULL;
for(int i=0;i<num;i++){
root = InsertOrder(root, arr[i], -1);
}
return root;
}
void PreOrder(TreeNode* root){ // 前序遍历
if(root==NULL) return;
printf("%c ", root->data);
PreOrder(root->leftChild);
PreOrder(root->rightChild);
}
void InOrder(TreeNode* root){ // 中序遍历
if(root==NULL) return;
InOrder(root->leftChild);
printf("%c ", root->data);
InOrder(root->rightChild);
}
void PostOrder(TreeNode* root){ // 后序遍历
if(root==NULL) return;
PostOrder(root->leftChild);
PostOrder(root->rightChild);
printf("%c ", root->data);
}
int main(){
/*//根据前序遍历串,构造二叉树 https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&tqId=29483&tPage=1&ru=/kaoyan/retest/1001&qru=/ta/tsing-kaoyan/question-ranking
string str;
while(cin>>str){
int position = 0; // 标记字符串的处理位置
TreeNode* root = Build(position, str);
PreOrder(root);
printf("\n");
InOrder(root);
printf("\n");
PostOrder(root);
printf("\n");
}*/
/*//根据前序遍历序列和中序遍历序列构造二叉树 https://www.nowcoder.com/practice/6e732a9632bc4d12b442469aed7fe9ce?tpId=40&tqId=21544&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking
string str1, str2;
while(cin>>str1>>str2){
TreeNode* root = Build(str1, str2);
PostOrder(root);
printf("\n");
}*/
/*//根据后序遍历序列和中序遍历序列构造二叉树
string str1, str2;
while(cin>>str1>>str2){
TreeNode* root = BuildInPost(str1, str2);
PreOrder(root);
printf("\n");
}*/
/*//构建一棵二叉排序树 https://www.nowcoder.com/practice/30a0153649304645935c949df7599602?tpId=69&tqId=29654&tPage=1&ru=/kaoyan/retest/11002&qru=/ta/hust-kaoyan/question-ranking
int n,elem;
int arr[101];
while(~scanf("%d",&n)){
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
BuildOrder(arr,n);
}*/
return 0;
}