• 数据结构:树的链式递归实现


    /************************************************************************
    树链式递归实现
    
    函数: 
    build
    
    getsum(获取树得节点个数) 
    getdep(获取树的深度 ) 
    getlson(查找某一个节点的左子树) 
    getrson(查找某一个节点的右子树) 
    getparent(查找某一个节点的父亲) 
    
    preprint(前序遍历) 
    inprint(中序遍历) 
    postprint(后序遍历) 
    
    ************************************************************************/
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h> 
    int max(int x,int y)
    {
    	if (x>y) return x;return y;
    }
    typedef struct binode
    {
    	char data;
    	struct binode *lson,*rson;
    } *bitree;
    
    //第一种build的方法,直接在函数内部初始化T 
    void build(bitree *T)//*T表示传递进来的这个指针,T表示二级指针。我们进行操作的是*T。 
    {
    	char ch;
    	scanf("%c",&ch);
    	if (ch=='^')
    	{
    		(*T)=NULL;//若该位置为None,将指针置为空,否则该指针因未初始化导致指向完全随机 
    		return;
    	}
    	*T=(bitree)malloc(sizeof(struct binode));//为指针分配空间。
    	//注意这里是分配指向大小为struct binode空间的指针,不是分配大小为sizeof(bitree)的空间  (bitree是一个指针)
    	(*T)->data=ch;
    	//printf("%c",(*T)->data);
    	bitree leftson,rightson;//新建两个指针 	
    	build(&leftson);
    	build(&rightson);
    	(*T)->lson=leftson;
    	(*T)->rson=rightson;//注意这里要先build再赋值
    }
    
    //第二种build的方法,传二级指针,然后通过返回bitree给T赋值 
    bitree build2(bitree *T)//*T表示传递进来的这个指针,T表示二级指针。我们进行操作的是*T
    {
    	char ch;
    	scanf("%c",&ch);
    	if (ch=='^')
    	{		
    		return(NULL);
    	}
    	*T=(bitree)malloc(sizeof(struct binode));//为指针分配空间,注意不是分配大小为sizeof(bitree)的空间 
    	(*T)->data=ch;
    	
    	(*T)->lson=build2(&((*T)->lson));
    	(*T)->rson=build2(&((*T)->rson));
    	return (*T);
    }
    
    //第三种build的方法,只需要传一级指针,然后通过返回bitree给T赋值。
    //因为T最后是在主程序里赋值,所以我们可以先假装在build3里修改地址,然后将修改后的结果返回,最后在主程序里更新。这样更简洁 
    bitree build3(bitree T)//T表示传递进来的这个指针
    {
    	char ch;
    	scanf("%c",&ch);
    	if (ch=='^')
    	{		
    		return(0);
    	}
    	//printf("%p
    ",T);
    	T=(bitree)malloc(sizeof(struct binode));//为指针分配指针空间 
    	//printf("%p
    ",T);
    	T->data=ch;	
    	T->lson=build3(T->lson);
    	T->rson=build3(T->rson);
    	return T;
    }
    
    //get property
    int getsum(bitree *T)
    {
    	if (!(*T)) return 0;
    	return 1+getsum(&(*T)->lson)+getsum(&(*T)->rson);
    }
    int getdep(bitree *T)
    {
    	if (!(*T)) return 0;
    	return 1+max(getdep(&(*T)->lson),getdep(&(*T)->rson));
    }
    void getparent(bitree *T,char target,char parent)
    {
    	if (!(*T)) return;
    	if ((*T)->data==target)
    	{
    		printf("%c",parent);
    		return;	
    	}
    	getparent(&(*T)->lson,target,(*T)->data);
    	getparent(&(*T)->rson,target,(*T)->data);
    }
    void getlson(bitree *T,char target)
    {
    	if (!(*T)) return;
    	if ((*T)->data==target)
    	{
    		if ((*T)->lson) printf("%c",((*T)->lson)->data);
    		return;	
    	}
    	getlson(&(*T)->lson,target);
    	getlson(&(*T)->rson,target);
    }
    void getrson(bitree *T,char target)
    {
    	if (!(*T)) return;
    	if ((*T)->data==target)
    	{
    		if ((*T)->rson) printf("%c",((*T)->rson)->data);
    		return;	
    	}
    	getrson(&(*T)->lson,target);
    	getrson(&(*T)->rson,target);
    }
    
    //traverse
    void preprint(bitree T)
    {
    	if (!(T)) return;	
    	printf("%c",T->data);
    	preprint(T->lson);
    	preprint(T->rson);
    }
    //第二种preprint,因为不用修改指针,其实可直接传该指针,这样更为简洁。traverse和getproperty都能改写 
    void preprint2(bitree *T)
    {
    	if ((*T)==NULL) return;
    	printf("%c",(*T)->data);
    	preprint2(&((*T)->lson));	
    	preprint2(&((*T)->rson));
    }
    
    void inprint(bitree *T)
    {
    	if (!(*T)) return;
    	inprint(&((*T)->lson));
    	printf("%c",(*T)->data);
    	inprint(&((*T)->rson));
    }
    void postprint(bitree *T)
    {
    	if (!(*T)) return;	
    	postprint(&((*T)->lson));
    	postprint(&((*T)->rson));
    	printf("%c",(*T)->data);
    }
    
    
    int main()
    {
    /*  input:  ABC^^D^^^
    *
    *      A
    *    B   ^
    *   C D
    *  ^^ ^^
    *
    */
    	bitree T;//新建一个指针 
    	build(&T);//传递这个指针的地址。如果这里写成build(T)然后在build程序直接调用T,则无法修改T的值(二级指针才能修改指针地址) 
    	//T=build2(&T);//另外的方式 
    	//T=build3(T);//另外的方式 
    	printf("pre-order traverse:
    ");
    	preprint(T);
    	printf("
    ");
    
    	printf("in-oder traverse:
    ");
    	inprint(&T);
    	printf("
    ");
    		
    	printf("post-order traverse:
    ");
    	postprint(&T);
    	printf("
    ");
    	
    	printf("depth of tree:
    ");
    	printf("%d",getdep(&T));
    	printf("
    ");
    	
    	printf("number of node:
    ");
    	printf("%d",getsum(&T));
    	printf("
    ");
    	
    	printf("get parent:
    ");
    	getparent(&T,'C','^');
    	printf("
    ");
    	
    	printf("get leftson:
    ");
    	getlson(&T,'A');
    	printf("
    ");
    	
    	//pretest pass
    }
    
  • 相关阅读:
    java 泛型 类型作为参量 Class<T> transform
    面向对象的类方法只具有命名空间的作用
    编程语言沉思录—编程语言的体系结构
    类型约束的作用
    函数重载、多态与型变
    函数类型与型变
    型变(逆变)函数
    scala 型变
    泛型编程的几个关键概念
    泛型是包含类型参数的抽象类型—类型构造器
  • 原文地址:https://www.cnblogs.com/reshuffle/p/12791063.html
Copyright © 2020-2023  润新知