const int maxn=100;
//-------------------------二叉树------------------------------
//二叉树的存储结构
struct node{
int data;
int layer;
node* lchild;
node* rchild;
};
//新建结点
node* newNode(int v){
node* Node=new node;
Node->data=v;
Node->lchild=Node->rchild=NULL;
return Node;
}
//二叉树的查找和修改
//使用递归查找
void search(node* root,int x,int newdata){
if(rootNULL){
return;
}//查找失败或者查找完毕
if(root->datax){
root->data=newdata;
}
search(root->lchild,x,newdata);
search(root->rchild,x,newdata);
}
//二叉树的插入,即查找失败时到达叶子节点,就是要插入的地方
void insert(node* &root,int x){
if(root==NULL){
root=newNode(x);
}
if(){
insert(root->lchild,x);
}else{
insert(root->rchild,x);
}
}
//二叉树的创立
node* createTree(int data[],int n){
node* root=NULL;
for(int i=0;i<n;i++){
insert(root,data[i]😉
}
return root;
}
//二叉树的 遍历
//先序遍历
void preorder(node* root){
if(root==NULL){
return;
}
printf("%d\n",root->data);//先访问根节点,再先左后右
preorder(root->lchild);
preorder(root->rchild);
}
//中序遍历
//中序遍历的性质
//中序遍历总是把根结点放在左子树和右子树中间
void inorder(node* root){
if(root==NULL){
return;
}
inorder(root->lchild);
printf("%d\n",root->data);
inorder(root->rchild);
}
//后序遍历
void postorder(node* root){
if(root==NULL) return;
postorder(root->lchild);
postorder(root->rchild);
printf("%d\n",root->data);
}
//层序遍历
void LayerOrder(node* root){
queue<node*> q;
root->layer=1;
q.push(root);
while(!q.empty()){
node* now=q.front();
q.pop();
printf("%d %d",now->data,now->layer);
//非空的时候才能push
if(now->lchild!=NULL){
now->lchild->layer=now->layer+1;
q.push(now->lchild);
}
if(now->rchild!=NULL) {
now->rchild->layer=now->layer+1;
q.push(root->rchild);
}
}
}
int pre[N],in[N];
//给出先序遍历和中序遍历,重建二叉树
node* create(int preL,int preR,int inL,int inR){
if(preL>preR){
return NULL;
}
node* root=new node;
root->data=pre[preL];
int k;//定义在外面,方便使用
for(k=inL,k<=inR;k++){
if(root->data==in[k]);
break;
}
//k为根节点
int numleft=k-inL;//左子树
root->lchild=create(preL+1,preL+numleft,inL,k-1);
root->rchild=create(preL+numleft+1,preR,k+1,inR);
return root;
}
//二叉树的静态实现
struct node{
int data;
int lchild;
int rchild;
}Node[maxn];//使用数组来存储结点
//结点的生成
int index=0;
int newNode(int v){
Node[index].data=v;
Node[index].lchild=-1;
Node[index].rchild=-1;
return index++;//先返回index再++
}
//------------------------树-------------------------------------
//树的静态写法
struct node{
int data;
vector child;
}Node[maxn];
//新建结点
int index=0;
int newNode(int v){
Node[index].data=v;
Node[index].child.clear();
return index++;
}
//树的先根遍历
void preorder(int root){
printf("%d",Node[root].data);
for(int i=0;i<Node[root].child.size();i++){
preorder(Node[root].child[i]);
}
}
//从树的遍历看dfs和bfs
//对所有合法的dfs求解过程,都可以把他化成树的形式,分岔口时树的非叶子结点,边界是树的叶子节点
//碰到可以用dfs做的题目,不妨把一些状态作为树的结点,然后问题就会转换为对树进行先根遍历!!!
//对所有合法的bs求解过程,都可以把状态作为结点,将广度优先搜索问题转变为树的层序遍历问题
//-------------------------------二叉查找树(二叉搜索树、排序树)-------------------------------------
//二叉树的递归定义:1.要么二叉查找树是一棵空树 2.要么二叉树的左子树上所有节点的数据小于等于根节点数据,右子树上所有节点的数据大于等于根节点的数据
//二叉查找树的查找
void search(node* root,int x){
if(root==NULL){
printf("failed");
return;
}//查找失败
if(root->data==x){
printf("%d",root->data);
}else if(x<root->data){
search(root->lchild,x);
}else{
search(root->rchild,x);
}
}
//二叉查找树的插入操作,插入要用引用
void insert(node* &root,int x){
if(rootNULL){
root=newNode(x);
}
if(root->datax){
return;//查找成功直接返回
}else if(xdata){
search(root->lchild,x);
}else{
search(root->rchild,x);
}
}
//二叉查找树的建立,就是不断插入的过程
node* Create(int data[],int n){
node* root=NULL;
for(int i=0;i<n;i++){
insert(root,data[i]);
}
return root;
}
//二叉查找树的删除
//寻找二叉查找树中以root为根节点的树中的最大权值结点
node* findMax(node* root){
while(root->rchild!=NULL){
root=root->rchild;//不断往右,直到没有右孩子
}
return root;
}
//寻找二叉查找树中以root为根节点的树中的最小权值结点
node* findMIn(node* root){
while(root->lchild!=NULL){
root=root->lchild;//不断往左,直到没有左孩子
}
return root;
}
//删除root为根节点的树中权值为x的结点
void deleteNode(node* root,int x){
if(rootNULL) return;
if(root->datax){
if(root->lchildNULL&&root->rchildNULL){
root==NULL;//叶子结点直接删除
}else if(root->lchild!=NULL){
//左子树不为空,找root的前驱,用前驱覆盖root再递归删除pre
node* pre=findMax(root->lchild);
root->data=pre->data;
deleteNode(root->lchild,pre->data);//注意要递归删除,因为最右结点可能非叶子节点,不能直接删除
}else if(root->rchild!=NULL){
//右子树不为空,找root的后继next,用后继覆盖root再递归删除next
node* next=findMin(root->rchild);
root->data=next->data;
deleteNode(root->rchild,next->data);
}
}else if(root->data>x){
deleteNode(root->lchild,x);
}else{
deleteNode(root->rchild,x);
}
}
//二叉查找树的性质:对二叉查找树进行中序遍历,得到的遍历结果是有序的