c树的存储
① 二叉树的存储结构是怎样的有哪些类型的存储结构对应的c语言描述是
楼上回答的是树的存储,不是二叉树的存储,主要如下:
1、顺序存储:适用于完全二叉树,如果根从1开始编号,则第i结点的左孩子编号为2i,右孩子为2i+1,双亲编号为(i/2)下取整,空间紧密
2、二叉链表:适用于普通二叉树,每个结点除了数据外,还有分别指向左右孩子结点的指针,存储n个结点有n+1个空指针域,存储密度小于顺序存储,但是适用范围广,缺陷是正常遍历只能从双亲向孩子,退回来一般需要借助栈(或者用递归,其实也是栈)
3、三叉链表:同样适用于普通二叉树,结点除了数据外,还有左右孩子与双亲的指针,存储密度低于二叉链表,但是可以非常方便地在二叉树中遍历,不需要其他辅助工具
② 数据结构 c语言版二叉树(1) 建立一棵含有n个结点的二叉树,采用二叉链表存储;
#include<stdio.h>
#include<stdlib.h>
typedef struct node *tree_pointer;
struct node{
 char ch;
 tree_pointer left_child,right_child;
};
tree_pointer root=NULL;
tree_pointer create(tree_pointer ptr)
{ 
 char ch;
 scanf("%c",&ch);
 if(ch==' ')
  ptr=NULL;
 else{
  ptr=(tree_pointer)malloc(sizeof(node));
     ptr->ch=ch;
     ptr->left_child=create(ptr->left_child);
     ptr->right_child=create(ptr->right_child);
 }
 return ptr;
} 
void preorder(tree_pointer ptr)
{
 if(ptr){
  printf("%c",ptr->ch);
  preorder(ptr->left_child);
  preorder(ptr->right_child);
 }
}
void inorder(tree_pointer ptr)
{
 if(ptr){
  inorder(ptr->left_child);
  printf("%c",ptr->ch);
  inorder(ptr->right_child);
 }
}
void postorder(tree_pointer ptr)
{
 if(ptr){
  postorder(ptr->left_child);
  postorder(ptr->right_child);
  printf("%c",ptr->ch);
 }
}
void main()
{
 printf("构建一个二叉树(结点数为n):\n");
 root=create(root);
 printf("前序遍历二叉树:\n");
 preorder(root);
 printf("\n");
 printf("中序遍历二叉树:\n");
 inorder(root);
 printf("\n");
 printf("后序遍历二叉树:\n");
 postorder(root);
 printf("\n");
}
③ 用C语言建立一棵含有n个结点的二叉树,采用二叉链表存储,然后分别实现前序,中序,后序遍历该二叉树
#include <stdio.h>
#include <stdlib.h>
#define max 100
typedef struct node{  //二叉树结构
	char data;
	struct node *lc,*rc;  //左右子树
}bt,*list;
/*
二叉树
     A
	/ \
   B   C
  / \   \
 D   E   F
/       / \
K	   G   H
input 
ABDK000E00C0FG00H00
ouput
  ABDKECFGH
  KDBEACGFH
  KDEBGHFCA
*/
int  creat(list*root){ //创建一棵二叉树,root使用的是二维指针
	char n;
	scanf(" %c",&n); //注%C前面加空格是为了起间隔作用 scanf不读入空格
	if (n=='0')  //0为间隔
	{
		*root=NULL; return 0;  //输入结束
	}	
	*root=(list)malloc(sizeof(bt));
	if (!*root) return 0;	      
	(*root)->data=n;
	creat(&(*root)->lc);
	creat(&(*root)->rc);
	return 1;
}
int pre(list root){ //先序遍历
	if (!root) return 0;	
	printf("%c",root->data);
	pre(root->lc);
	pre(root->rc);
	return 1;
}
int mid(list root){ //中序遍历
	if (!root)	return 0;
	mid(root->lc);
	printf("%c",root->data);
	mid(root->rc);
	return 1;
}
int	 bh(list root){ //后序遍历
	if (!root)  return 0;	    
	bh(root->lc);
	bh(root->rc);
	printf("%c",root->data);
	return 1;
}
int sum(list root,int *cnt){ //求结点的个数sum
	if(root){
		(*cnt)++;
		sum(root->lc,cnt);
		sum(root->rc,cnt);
		return 1;
	}
	return 0;
}
int sumleaf(list root,int *cnt){  //求叶子节点的个数
	if (root)
	{
		if ((!root->lc)&&(!root->rc))
		{  (*cnt)++; }		
		sumleaf(root->lc,cnt);
		sumleaf(root->rc,cnt);
		return 1;
	}
	return 0;
}
int deep(list root,int *cnt){ //求深度
    if (!root)
    {
		*cnt=0;	return 0;	
    }
	int m,n;
	n=m=*cnt;
	deep(root->lc,&m);
	deep(root->rc,&n);
	*cnt=m+1;
	if(m<n) *cnt=n+1;
	return 1;
}
int floor(list root){ //层次遍历
	  if(root)
	  { 
		  list s[max];	  int front,rear; //用队进行存储
	      front=-1;	  rear=0;  s[rear]=root; //初始化	  
		  while (rear!=front) //当队为空时结束
		  {
			  printf("%c",s[++front]->data);
              if (s[rear]->lc)
              {s[1+rear]=s[rear]->lc; rear++;  }  //将左子树存入队列中            
			  if (s[rear]->rc)
              {s[1+rear]=s[rear]->rc; rear++;  }  //将右子书存入队列中
		  }
		  return 1;
	  }
	  return 0;
}
int scop(list *r,list *p){ //树的复制
    if(*r){
     *p=(list)malloc(sizeof(bt));
	 if(*p){
		 (*p)->data=(*r)->data;
		 scop(&(*r)->lc,&(*p)->lc);
		 scop(&(*r)->rc,&(*p)->rc);
		 return 1;
	 }
	}
	*p=NULL;
	return 0;
}
int sepect(list root,list *p,char e){ //查找节点返回指针*p p为二级指针
	if(root){
		if (root->data==e)
		{ *p=root; return 1;
		}
		sepect(root->lc,p,e);
		sepect(root->rc,p,e);
	}
	return 0;
}
void main(){
	list b,s,m;	
	int n,t=1;  
	char ch='\0';  
	printf("***********Bitree************\n");
	while(t){      //循环操作
	printf("input a tree(int):\n"); 
	s=m=b=NULL; //二叉树的初始化
	creat(&b);
	//按三种遍历输出二叉树
	printf("\npre ");  pre(b);    
	printf("\nmid ");  mid(b);   
	printf("\nbh  ");  bh(b);    printf("\n");
	//求节点数目,叶子节点的个数,深度
	n=0;  sum(b,&n);     printf("sumdata:  %d\n",n);    
	n=0;  sumleaf(b,&n); printf("sumleaf:  %d\n",n); 
	n=0;  deep(b,&n);    printf("deep:     %d\n",n); 
	//二叉树的复制
	scop(&b,&s);  
	printf("\ns tree:\npre ");	
	pre(s);  printf("\nmid ");   
	mid(s);  printf("\nbh  ");   
	bh(s);   printf("\n");
	//查找节点
	printf("sepect a data:\n");
	scanf(" %c",&ch); //注%C前面加空格是为了起间隔作用 scanf不读入空格
	sepect(b,&m,ch); 
	if(m) 
		printf("sepect : %c \n",m->data);
	else 
		printf("Error,no this data: %c\n",ch);
	//继续则输入 1,退出输入 0
	printf("continue input 1,break input 0:\n");
	scanf("%d",&t);  
	}
}
④ 用C语言定义二叉树的二叉链表存储结构,完成二叉树的建立,先序中序后序遍历的操作,求所有叶子结点总数
#include<stdio.h>
#include<malloc.h>
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *lchild,*rchild;
}LNode,*TLNode;
void create(TLNode * Tree){ //创建
ElemType e;
scanf("%d",&e);
if(e==0)
*Tree=NULL;
else{
(*Tree)=(TLNode)malloc(sizeof(LNode));
(*Tree)->data=e;
printf("input %d lchild: ",e);
create(&(*Tree)->lchild);
printf("input %d rchild: ",e);
create(&(*Tree)->rchild);
}
}
void print1(TLNode Tree){ //先序遍历
if(Tree!=NULL){
printf("%d-",Tree->data);
print1(Tree->lchild);
print1(Tree->rchild);
}
}
void print2(TLNode Tree){ //中序遍历
if(Tree!=NULL){
print2(Tree->lchild);
printf("%d-",Tree->data);
print2(Tree->rchild);
}
}
void print3(TLNode Tree){ //后序遍历
if(Tree!=NULL){
print3(Tree->lchild);
print3(Tree->rchild);
printf("%d-",Tree->data);
}
}
int leaf=0; //求叶子节点数
int depth(TLNode Tree){ //深度
int s1,s2;
if(Tree==NULL)
return 0;
else{
s1=depth(Tree->lchild);
s2=depth(Tree->rchild);
if(s1==0 && s2==0) leaf++;
return (s1>s2?s1:s2)+1;
}
}
int Cnode(TLNode Tree){ //总结点
int s1,s2;
if(Tree==NULL)
return 0;
else{
s1=Cnode(Tree->lchild);
s2=Cnode(Tree->rchild);
return s1+s2+1;
}
}
void main(){
TLNode Tree;
printf("input 根节点: ");
create(&Tree);
printf("先序遍历:");
print1(Tree);
printf("中序遍历");
print2(Tree);
printf("后序遍历");
print3(Tree);
printf(" 深 度:%d ",depth(Tree));
printf("总结点数:%d ",Cnode(Tree));
printf("叶子结点数:%d ",leaf);
}

