二叉树(Binary Tree)

  1. 树(Tree):非线性数据结构:树,图
  2. 术语:
    根结点(root):树中没有前驱的结点
    叶子结点(leaf):没有后继的结点
    双亲结点:是子女结点的前驱
    子女结点:是双亲结点的后继
    兄弟结点:同一个双亲结点的子女之间互称为兄弟结点
    度:结点的度:一个结点的子女个数(叶子结点度为0)
    树的度:树中度值最大的结点的度
    树的深度:树的层次数
  3. 二叉树:度值最大为2的树
    树状结构:
    i:有且只有一个结点无前驱:根结点
    ii:可有多个结点无后继:叶子结点
    iii:除根和叶子外,其余结点只有一个双亲,可有多个子女
  4. 二叉树性质:
    a》任意一棵非空二叉树的叶子结点总比双分支结点多一个
    n0=n2+1
    b》对二叉树按层编号:0,1,2,3…
    编号为i的层最多可放2^i个结点(最大值)
  5. 满二叉树:一棵h层的二叉树的每一层的结点个数都达到最大值
    结点个数为:2^h - 1
  6. 完全二叉树:一棵h层的完全二叉树:
    i:前h-1层是满的
    ii:最后一层连续缺失右边的结点
    特点:
    ①h-1<log2(n+1)<=h
    ②n为奇数无单分支结点,n为偶数有单分支结点
    ③满二叉树是特殊的完全二叉树
  7. 理想平衡二叉树(理想树):前h-1层是满的,最后一层任意摆放
    满二叉树<=完全二叉树<=平衡二叉树
  8. 对任意一棵二叉树按层对结点进行编号:1,2,3… 注意:对缺失结点也要编号
    编号为i的结点:若有左子女:编号为:2i
    若有右子女:编号为:2i+1
    编号为i的结点:双亲编号为:【i/2】
    (i>1)

创建一棵二叉查找树,及前中后序遍历输出

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *left;
	struct node *right;
}BTNode;
BTNode *CreateBTree(int a[],int n)
{
	BTNode *p,*parent,*root,*c;
	int i;
	//创建根结点 
	root=(BTNode *)malloc(sizeof(BTNode));
	root->data=a[0];
	root->left=root->right=NULL;
	//创建其他结点 
	for(i=1;i<n;i++){
		p=(BTNode *)malloc(sizeof(BTNode));
		p->data=a[i];
		p->left=p->right=NULL;
		c=root;//每次循环都要从根开始遍历判断 
		while(c){
			parent=c;//联动指针 
			if(c->data>p->data){
				c=c->left;
			}
			else{
				c=c->right;
			}
		}
		if(parent->data>p->data){//判断要挂哪边的链 
			parent->left=p;
		}
		else{
			parent->right=p;
		}
	} 
	return root;
} 
void Forder(BTNode *root)
{
	if(root){
		printf("%4d",root->data);
		Forder(root->left);//递归遍历左子树 
		Forder(root->right);//递归遍历右子树 
	}
} 
void Inorder(BTNode *root)
{
	if(root){
		Inorder(root->left);
		printf("%4d",root->data);
		Inorder(root->right);
	}
} 
void Porder(BTNode *root)
{
	if(root){
		Porder(root->left);
		Porder(root->right);
		printf("%4d",root->data);
	}
} 
int main()
{
	int n;
	BTNode *root;
	scanf("%d",&n);
	int *a;
	a=(int *)malloc(sizeof(int)*n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	root=CreateBTree(a,n);//创建二叉查找树 
	Forder(root);//前序遍历 
	printf("\n"); 
	Inorder(root);//中序遍历 
	printf("\n"); 
	Porder(root);//后序遍历 
	return 0;
}

//设root指向一棵非空二叉树,在二叉树中查找关键字为key的结点,
//并返回地址,若未找到返回null,设每个结点数据域值不重复

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *left,*right;
}BTNode;
BTNode *CreateBiTree(int a[],int n)
{
	BTNode *root,*c,*p,*q;
	root=(BTNode *)malloc(sizeof(BTNode));
	root->data=a[0];
	root->left=root->right=NULL;
	for(int i=1;i<n;i++){
		p=(BTNode *)malloc(sizeof(BTNode));
		p->data=a[i];
		p->left=p->right=NULL;
		c=root;
		while(c){
			q=c;
			if(c->data>p->data){
				c=c->left;
			}
			else{
				c=c->right;
			}
		}
		if(q->data>p->data){
			q->left=p;
		}
		else{
			q->right=p;
		}
	}
	return root;
}
BTNode *Findkey(BTNode *r,int key)
{
	BTNode *lr,*rr;
	if(!r)
	{
		return NULL;
	}
		if(r->data==key){
			return r;
		}
		else{
			lr=Findkey(r->left,key);
			rr=Findkey(r->right,key);
			if(lr){
				return lr;
			}
			else if(rr){
				return rr;
			}
			else{
				return NULL;
			}
		}
			
}
int main()
{	
	int *a;
	int n,key;
	printf("请输入数组长度:");
	scanf("%d",&n);
	a=(int *)malloc(n*sizeof(int));
	printf("请输入数组元素:");
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	printf("请输入key值:");
	scanf("%d",&key);
	BTNode *root=CreateBiTree(a,n);
	root=Findkey(root,key);
	if(root){
		printf("%d",root->data); 
	}
	else{
		printf("NULL");
	}
	
	return 0;
}

//按行遍历二叉树的每个结点(非递归)

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *left,*right;
}BTNode;
BTNode *CreateBiTree(int a[],int n)
{
	BTNode *root,*c,*p,*q;
	root=(BTNode *)malloc(sizeof(BTNode));
	root->data=a[0];
	root->left=root->right=NULL;
	for(int i=1;i<n;i++){
		p=(BTNode *)malloc(sizeof(BTNode));
		p->data=a[i];
		p->left=p->right=NULL;
		c=root;
		while(c){
			q=c;
			if(c->data>p->data){
				c=c->left;
			}
			else{
				c=c->right;
			}
		}
		if(q->data>p->data){
			q->left=p;
		}
		else{
			q->right=p;
		}
	}
	return root;
}
void LevelOrder(BTNode *root)
{
	BTNode **Q,*p;//声明指向存储指针的队列的指针
	int front=0,rear=0;//头指针和尾指针 
	Q=(BTNode **)malloc(sizeof(BTNode *)*1000);//队列空间不为循环队列,要尽可能大
	 Q[++rear]=root;
	 while(front!=rear){//队列不空,执行出队,输出,入队操作 
	 	p=Q[++front];//出队 
	 	printf("%5d",p->data);//输出
	 	if(p->left){
		Q[++rear]=p->left;//左子女入队 
		}
		if(p->right){
		Q[++rear]=p->right;//右子女入队 
		}
	 }
}
int main()
{	
	int *a;
	int n,key;
	printf("请输入数组长度:");
	scanf("%d",&n);
	a=(int *)malloc(n*sizeof(int));
	printf("请输入数组元素:");
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	BTNode *root=CreateBiTree(a,n);//建立二叉排序树 
	LevelOrder(root);//二叉树的层次遍历 
	return 0;
}

//非递归前序遍历二叉树

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *left,*right;
}BTNode;
BTNode *CreateBiTree(int a[],int n)
{
	BTNode *root,*c,*p,*q;
	root=(BTNode *)malloc(sizeof(BTNode));
	root->data=a[0];
	root->left=root->right=NULL;
	for(int i=1;i<n;i++){
		p=(BTNode *)malloc(sizeof(BTNode));
		p->data=a[i];
		p->left=p->right=NULL;
		c=root;
		while(c){
			q=c;
			if(c->data>p->data){
				c=c->left;
			}
			else{
				c=c->right;
			}
		}
		if(q->data>p->data){
			q->left=p;
		}
		else{
			q->right=p;
		}
	}
	return root;
}
void PreOrder(BTNode *root)
{
	BTNode **Q,*p;
	int top=-1;//栈顶指针 
	Q=(BTNode **)malloc(sizeof(BTNode *)*1000);//栈空间尽可能大
	 Q[++top]=root;
	 while(top!=-1){//栈不空 
	 	p=Q[top--];//出栈
	 	printf("%5d",p->data);
	 	if(p->right){//右子女压栈
	 		Q[++top]=p->right;
	 	}
	 	if(p->left){//左子女压栈
	 		Q[++top]=p->left;
	 	}
	 }
}
int main()
{	
	int *a;
	int n,key;
	printf("请输入数组长度:");
	scanf("%d",&n);
	a=(int *)malloc(n*sizeof(int));
	printf("请输入数组元素:");
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	BTNode *root=CreateBiTree(a,n);//建立二叉排序树 
	PreOrder(root);//二叉树的层次遍历 
	return 0;
}

//非递归中序遍历二叉树

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *left,*right;
}BTNode;
BTNode *CreateBiTree(int a[],int n)
{
	BTNode *root,*c,*p,*q;
	root=(BTNode *)malloc(sizeof(BTNode));
	root->data=a[0];
	root->left=root->right=NULL;
	for(int i=1;i<n;i++){
		p=(BTNode *)malloc(sizeof(BTNode));
		p->data=a[i];
		p->left=p->right=NULL;
		c=root;
		while(c){
			q=c;
			if(c->data>p->data){
				c=c->left;
			}
			else{
				c=c->right;
			}
		}
		if(q->data>p->data){
			q->left=p;
		}
		else{
			q->right=p;
		}
	}
	return root;
}
void InOrder(BTNode *root)
{
	BTNode **Q,*p;
	int top=-1;//栈顶指针 
	Q=(BTNode **)malloc(sizeof(BTNode *)*1000);//栈空间尽可能大
	p=root;
	while(p){//将左线入栈
		Q[++top]=p;
		p=p->left;
	} 
	 while(top!=-1){//栈不空 
	 	p=Q[top--];//出栈
	 	printf("%5d",p->data);
	 	if(p->right){//判断p的右子女是否为空,为空则不做处理
	 		p=p->right;//p指向右子女
	 		while(p){//入栈新的左线
			Q[++top]=p;
			p=p->left;
		} 
	 	}
	 }
}
int main()
{	
	int *a;
	int n,key;
	printf("请输入数组长度:");
	scanf("%d",&n);
	a=(int *)malloc(n*sizeof(int));
	printf("请输入数组元素:");
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	BTNode *root=CreateBiTree(a,n);//建立二叉排序树 
	InOrder(root);//二叉树的层次遍历 
	return 0;
}
//非递归后序遍历
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *left,*right;
}ElemSN;
ElemSN *CreateBiTree(int a[],int n)
{
	ElemSN *root,*c,*p,*q;
	root=(ElemSN *)malloc(sizeof(ElemSN));
	root->data=a[0];
	root->left=root->right=NULL;
	for(int i=1;i<n;i++){
		p=(ElemSN *)malloc(sizeof(ElemSN));
		p->data=a[i];
		p->left=p->right=NULL;
		c=root;
		while(c){
			q=c;
			if(c->data>p->data){
				c=c->left;
			}
			else{
				c=c->right;
			}
		}
		if(q->data>p->data){
			q->left=p;
		}
		else{
			q->right=p;
		}
	}
	return root;
}
/*void ProBiTree(ElemSN *root)
{
	ElemSN **stack,*p=NULL;
	stack=(ElemSN **)malloc(sizeof(ElemSN *)*1000);//分配栈空间 
	int top=-1;//栈顶指针
	while(root||top!=-1){//根结点不空且栈不空 
		while(root){//将左子树压栈 
			stack[++top]=root;
			root=root->left;
		}
		if(top!=-1){//栈不空 
			root=stack[top];//出栈 
			if(root->right==NULL||root->right==p){//无右孩子或者有孩子已经访问过 
				printf("%4d",root->data);
				top--;
				p=root;
				root=NULL;//避免重复入栈 
			}
			else{//有右孩子,但未被访问过 
				root=root->right;
			}
		}
	} 
}*/
void ProBiTree(ElemSN *root)
{
	ElemSN **stack,*p=NULL;
	stack=(ElemSN **)malloc(sizeof(ElemSN *)*1000);//分配栈空间 
	int top=-1;//栈顶指针
	while(root||top!=-1){//根结点不空且栈不空 
		if(root){//将左子树压栈 
			stack[++top]=root;
			root=root->left;
		}
		else{//栈不空 
			root=stack[top];//出栈 
			if(root->right==NULL||root->right==p){//无右孩子或者有孩子已经访问过 
				printf("%4d",root->data);
				top--;
				p=root;
				root=NULL;//避免重复入栈 
			}
			else{//有右孩子,但未被访问过 
				root=root->right;
			}
		}
	} 
}
int main()
{
	int n;
	int *a;
	printf("请输入数组长度:");
	scanf("%d",&n);
	a=(int *)malloc(sizeof(int)*n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	ElemSN *root=CreateBiTree(a,n);
	ProBiTree(root);
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值