二叉树-存储/数组表示/遍历/增删改查/根据前序中序构造二叉树

二叉树-存储/数组表示/遍历

#include<iostream>
using namespace std;

	struct node{
	int lc;
	int rc;
	node(){	lc=rc=0;}
	}; 
	int ch[N][2];
	//先序遍历 
	void preorder(int x)
	{
		printf("%d",x)
		if(ch[x][0])preorder(ch[x][0]);
		if(ch[x][1])preorder(ch[x][1]) ;
	}
	//中序遍历
	void inorder(int x)
	{
		if(ch[x][0])inorder(ch[x][0]);
		printf("%d",x);
		if(ch[x][1])inorder(ch[x][1]) ;
	 } 
	 //后序遍历
	 void posorder(int x)
	 {
	 	if(ch[x][0])posorder(ch[x][0]);
		if(ch[x][1])posorder(ch[x][1]) ;
		printf("%d",x);
	  } 

利用数组增删改查


#include <iostream>
#include<algorithm>
using namespace std;
int l[2001],r[2001],pre[2001],next[2001],n=0,p=0,hend=0; 
char a[2001];

//插入数据
int input()
{
    cout<<"--------插入数据-------"<<endl;
    cout<<"插入格式:值 父  L/R  父节点为0时是插入根节点:"<<endl;
    cout<<"请输入需要插入数据:";
    char z,f,w;   //z 输入的值   f 输入的父节点  w 左右位置 
    cin >>z>>f>>w;
    
    if(f=='0')
    {
    	n++;
    	a[n]=z;
    	l[n]=0;
    	r[n]=0;
    	
	}else
	{
	 
	 for(int i=1;i<=n;i++)
	 {
	 	if(a[i]==f)
	 	{
	 		n++;
	 		a[n]=z;
	 		if(w=='R')
	 		  r[i]=n;
	 		if(w=='L')
	 		  l[i]=n;
	 		
		 }
	 }
		
	}

	return 0;
 } 
 
//输出数据 
int output()
{
    cout <<endl; 
	cout <<"-------总共有"<<n<<"个数据---------"<<endl<<endl<<endl;
	cout<<"数据:   ";//由于next  0是头指针从0开始为了对比好看 
	for(int i=1;i<=n;i++)
	{
		cout<<a[i]<<' ';
	 } 
	cout<<endl; 
	cout<<"左边: ";
	for(int i=0;i<=n;i++)
	{
		cout<<l[i]<<' ';
	 }
	cout<<endl; 
	cout<<"右边: ";
	for(int i=0;i<=n;i++)
	{
		cout<<r[i]<<' ';
	 }
	cout<<endl; 
	cout<<"下标: ";
	for(int i=0;i<=n;i++)
	{
		cout<<i<<' ';
	 }    
	cout <<endl<<endl<<"-------------------"<<endl;
	cout <<endl; 
	return 0;
 } 
 
 //查找值的下标
 int find(int pos) 
 {
 	 int hp=hend;
	 for(int i=1;i<=pos;i++) hp=next[hp];
	 return hp; 
 }
 
//在某个位置插入数据 
int add(int pos,int value)
{
  int p=find(pos-1);
  n++;
  a[n]=value;
  next[n]=next[p];
  pre[next[p]]=n;
  next[p]=n;
  //pre[next[n]]=n;
  pre[n]=p;
  return 0;
}

//删除指定数据
int dell(int pos){
	
	int p=find(pos-1);
	next[p]=next[next[p]];
	
} 

//修改指定数据
//pos 为逻辑顺序的位置
//value 数据值 
int update(int pos,int value)
{
	a[find(pos)]=value;
	
}


//树的遍历
int find_1(int n)
{
   cout<<a[n];
   if(l[n]) find_1(l[n]);
   if(r[n]) find_1(r[n]);
 } 
 
int find_2(int n)
{
   
   if(l[n]) find_2(l[n]);
   cout<<a[n];
   if(r[n]) find_2(r[n]);
 } 
 
 int find_3(int n)
{
   
   if(l[n]) find_3(l[n]);
   if(r[n]) find_3(r[n]);
   cout<<a[n];
 } 

int main()
{
	//通过循环来控制对线性表的操作
	while(1)
	{
		cout <<"单链表表的操作"<<endl;
		cout <<"输入1:初始化插入数据"<<endl;
		cout <<"输入2:插入数据"<<endl;
		cout <<"输入3:删除数据"<<endl;
		cout <<"输入4:修改数据"<<endl;
		cout <<"输入5:查找数据"<<endl;
		cout <<"输入6:存储状态"<<endl;
		cout <<"输入7:数据排序"<<endl;
		cout <<"输入8:输出数据"<<endl;
		cout <<"输入0:退出"<<endl;
		cout <<"请输入你的操作:";
		cin >>p; 
		if(p==1)
		{
		//新增数据
		input();
		
		}else if(p==2){
		//在某个位置插入数据
		int pos,value;
		cout <<endl<<"请输入你的插入位置:";
		cin >>pos;
		cout <<endl<<"请输入你的插入位置的值:";
		cin >>value; 
		add(pos,value); 
		}else if(p==3){
		//删除数据 
		char de;
		cout <<endl<<"请输入你的要删除那个数据:";
		
		cin >>de;
		
		for(int i=1;i<=n;i++)
		{
			if(a[i]==de)
			{
			     for(int j=1;j<=n;j++)
				 {
				 	if(l[j]==i)
				 	{
				 		l[j]=0;
					 }
				}
				
				for(int k=1;k<=n;k++)
				 {
				 	if(r[k]==i)
				 	{
				 		r[k]=0;
					 }
				}		
			}
		}
		
		
		 
		}else if(p==4){
		//修改数据
		int pos,value;
		cout <<endl<<"请输入你的修改位置:";
		cin >>pos;
		cout <<endl<<"请输入你的修改位置的值:";
		cin >>value; 
		update(pos,value); 
		}else if(p==5){
		//查找数据
		int pos;
		cout <<endl<<"请输入你的查找位置:";
		cin >>pos;
		cout <<"-------查找第"<<pos<<"个数据---------"<<endl<<endl<<endl;
        cout <<a[find(pos)]; 
	    cout <<endl<<endl<<"-------------------"<<endl;
		
		}else if(p==6){
		//输出数据 
		output(); 
		}else if(p==0){
		//退出
		cout <<"感谢您的使用";
		break; 
		}else if(p==7){
		//排序 
		sort(a+1,a+n);
		cout <<"排序完成"<<endl;
		}else if(p==8){
		//排序 
		cout <<endl<<endl<<"-------------------"<<endl;
		cout<<"输出树数据:"<<endl;
		
		cout<<"前序:"<<endl;
		find_1(1);
		cout<<endl;
		cout<<"中序:"<<endl;
		find_2(1);
		cout<<endl;
	    cout<<"后序:"<<endl; 
		find_3(1);
		cout<<endl;
	  cout <<endl<<endl<<"-------------------"<<endl;	
	 	 
	 } 
}
	return 0;
 } 
在这里插入代码片

应用

  • 给定一棵树的前序遍历序列和中序遍历序列,求出这颗二叉树
/* 1.后序最后一个---找到root; 
   2.搜索root-----将中序分为两段;
   3.如此循环
   前序:acehifbgzk 
   后序:hiefczgkba
   中序:heicfazgbk
   画图
             a
        c         b
     e    f      g  k
    h i         z
    
    输入前序S[]=#acehifbgzk, n=11;
        中序T[]=0heicfazgbk传入solve(ls=ls+1=2,rs=11,lt=1,rt=11);//rs为前序长度,rt为中序长度; 
        S[1]=a,在T[6]中找到a ,pos=6;
        左子树大小len=5
		递归左子树lc=solve(ls=ls+1=2,rs=ls+len=6,lt=1,rt=pos-1=5) 
        S[2]=c,在T[4]中找到c,pos=5...... 
		递归右子树solve(ls=ls+len+1=7,rs=11,lt=pos+1=6,rt=11)
		......
    
    
*/



#include <bits/stdc++.h>
using namespace std;
char S[1000],T[1000];
int n;
int solve(int ls,int rs,int lt,int rt)//将前序遍历和中序遍历分别存在S和T中 
{
	if(ls>rs)	return 0;//这是一个空结点 
	if(ls==rs)
	{
		printf("For %c,it is a leaf\n",S[ls]);//输出它是一个叶子 
		return ls; //递归的最底层 
		}
	int pos;
	for(int i=lt;i<=rt;i++)
	{
		if(T[i]==S[ls])
		{
			pos=i;
			break;
		}
	}
	int len=pos-lt;//左子树的大小 
	int lc=solve(ls+1,ls+len,lt,pos-1);//递归左子树  起点+1,截至位置6
	int rc=solve(ls+len+1,rs,pos+1,rt);//递归右子树  起点左子树大小+2,截至位置11
	printf("For\40%c,left child is%c,right child is%c\n",S[ls],S[lc],S[rc]) ;//ls:父 lc:左孩 rc:右孩 
	return ls;
}
 
int main()
{
	scanf("%s",S+1);n=strlen(S+1);S[0]='#';
	scanf("%s",T+1);
	solve(1,n,1,n);
	return 0;
}

在这里插入图片描述

/* 1.后序最后一个---找到root; 
   2.搜索root-----将中序分为两段;
   3.如此循环
   前序:acehifbgzk 
   后序:hiefczgkba
   中序:heicfazgbk
   画图
             a
        c         b
     e    f      g  k
    h i         z
    
    输入前序S[]=#acehifbgzk, n=11;
        中序T[]=0heicfazgbk传入solve(ls=ls+1=2,rs=11,lt=1,rt=11);//rs为前序长度,rt为中序长度; 
        S[1]=a,在T[6]中找到a ,pos=6;
        左子树大小len=5
		递归左子树lc=solve(ls=ls+1=2,rs=ls+len=6,lt=1,rt=pos-1=5) 
        S[2]=c,在T[4]中找到c,pos=5...... 
		递归右子树solve(ls=ls+len+1=7,rs=11,lt=pos+1=6,rt=11)
		......
    
    
*/



#include <bits/stdc++.h>
using namespace std;
char S[1000],T[1000];
int n;
int solve(int ls,int rs,int lt,int rt)//将前序遍历和中序遍历分别存在S和T中 
{
	if(ls>rs)	return 0;//这是一个空结点 
	if(ls==rs)
	{
		printf("For %c,it is a leaf\n",S[ls]);//输出它是一个叶子 
		return ls; //递归的最底层 
		}
	int pos;
	for(int i=lt;i<=rt;i++)
	{
		if(T[i]==S[ls])
		{
			pos=i;
			break;
		}
	}
	int len=pos-lt;//左子树的大小 
	int lc=solve(ls+1,ls+len,lt,pos-1);//递归左子树  起点+1,截至位置6
	int rc=solve(ls+len+1,rs,pos+1,rt);//递归右子树  起点左子树大小+2,截至位置11
	printf("For\40%c,left child is%c,right child is%c\n",S[ls],S[lc],S[rc]) ;//ls:父 lc:左孩 rc:右孩 
	return ls;
}
 
int main()
{
	scanf("%s",S+1);n=strlen(S+1);S[0]='#';
	scanf("%s",T+1);
	solve(1,n,1,n);
	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值