zoukankan      html  css  js  c++  java
  • 数据结构——树的相关算法实现

    二叉树的基本算法

    包括二叉树的遍历(先、中、后),二叉树的层次,二叉树的深度,二叉树的叶子节点数计算。相关算法思想可以看书,这里只是给出相关算法实现。

    代码实现

    #include <stdio.h>
    #include <stdlib.h>
    #define MAXSIZE 30
    
    typedef char ElemType;
    
    typedef struct TNode {
    	char data;
    	TNode * lchild; 
    	TNode * rchild;
    }TNode, *BiTree;
    
    
    int IsEmpty_BiTree(BiTree *T) {
    	if(*T == NULL)
    	return 1;//如果树为空一直进入死循环,直到输入数据为止 
    	else
    	return 0;
    }
    
    void Create_BiTree(BiTree *T){
        char ch;
        ch = getchar();
        //当输入的是"#"时,认为该子树为空
        if(ch == '#')
            *T = NULL;
        //创建树结点
        else{
            *T = (BiTree)malloc(sizeof(struct TNode));
            (*T)->data = ch; //生成树结点
            //生成左子树
            Create_BiTree(&(*T)->lchild);
            //生成右子树
            Create_BiTree(&(*T)->rchild);
        }
    }
    
    void TraverseBiTree(BiTree T) {	//先序遍历 
    	if(T == NULL)//指针为空,说明节点不存在 
    	return; 
    	else {
    		printf("%c ",T->data);
    		TraverseBiTree(T->lchild);
    		TraverseBiTree(T->rchild);
    	}
    	
    }
    
    void InOrderBiTree(BiTree T) {		//中序遍历 
    	if(NULL == T)
    	return;
    	else {
    		InOrderBiTree(T->lchild);
    		printf("%c ",T->data);
    		InOrderBiTree(T->rchild);	
    	}
    }
    
    void PostOrderBiTree(BiTree T) {
    	if(NULL == T)
    	return;
    	else {
    		InOrderBiTree(T->lchild);
    		InOrderBiTree(T->rchild);
    		printf("%c ",T->data);
    	}
    	
    } 
    
    int TreeDeep(BiTree T) {
    	int deep = 0;
    	if(T)
    	{
    		int leftdeep = TreeDeep(T->lchild);
    		int rightdeep = TreeDeep(T->rchild);
    		deep = leftdeep+1 > rightdeep+1 ? leftdeep+1 : rightdeep+1; 
    	}
    	return deep;
    }
    //树的叶子结点为 
    int Leafcount(BiTree T, int &num) {//一般涉及到变化的都会取地址 
    	if(T)
    	{
    		if(T->lchild ==NULL && T->rchild==NULL)	
    		{
    			num++;
    			printf("%c ",T->data);
    		}			
    		Leafcount(T->lchild,num);
    		Leafcount(T->rchild,num);
    
    	}
    	return num;
    }
    
    //树的层次显示 (利用队列,先进先出的原则可以完美实现) 
    void LevelOrder_BiTree(BiTree T){
        //用一个队列保存结点信息,这里的队列采用的是顺序队列中的数组实现
        int front = 0;
        int rear = 0;
        BiTree BiQueue[MAXSIZE];
        BiTree tempNode;
        if(!IsEmpty_BiTree(&T)){
            BiQueue[rear++] = T;
             
            while(front != rear){// 
                //取出队头元素,并使队头指针向后移动一位 
                tempNode = BiQueue[front++];
                //判断左右子树是否为空,若不为空,则加入队列 
                if(!IsEmpty_BiTree(&(tempNode->lchild)))
                    BiQueue[rear++] = tempNode->lchild;
                 
                if(!IsEmpty_BiTree(&(tempNode->rchild)))
                    BiQueue[rear++] = tempNode->rchild;
                 
                 printf("%c ",tempNode->data);
            }
        }
    }
    
    int main(void)
    {
    	BiTree T;
    	BiTree *p = (BiTree*)malloc(sizeof(BiTree));
    	int deepth,num=0 ;
    	Create_BiTree(&T);//一般涉及到变化的都会取地址 
    	printf("先序遍历二叉树:
    ");
    	TraverseBiTree(T);
    	printf("
    ");
    	printf("中序遍历二叉树:
    ");
    	InOrderBiTree(T);
    	printf("
    ");
    	printf("后序遍历二叉树:
    ");
    	PostOrderBiTree(T);
    	printf("
    层次遍历结果:");
        LevelOrder_BiTree(T);
    	printf("
    ");
    	deepth=TreeDeep(T);
    	printf("树的深度为:%d",deepth);
    	printf("
    ");
    	printf("树的叶子结点为:");
    	Leafcount(T,num);
    	printf("
    树的叶子结点个数为:%d",num);
    	return 0;
    }
    
    

    运行演示

    线索二叉树的中序遍历

    #include<iostream>
    #include <stdlib.h>
    using namespace std;
    
    typedef struct BiThrNode
    {
        char data;
    	struct BiThrNode *lchild,*rchild;      /*左右孩子指针*/
    	int LTag,RTag;             			    /*左右标志*/
    }BiThrNode,*BiThrTree;
    
    BiThrTree pre;
    
    
    
    void CreateBiTree(BiThrTree *T){
        char ch;
        ch = getchar();
        //当输入的是"#"时,认为该子树为空
        if(ch == '#')
            *T = NULL;
        //创建树结点
        else{
            *T = (BiThrTree)malloc(sizeof(struct BiThrNode));
            (*T)->data = ch; //生成树结点
            //生成左子树
            CreateBiTree(&(*T)->lchild);
            //生成右子树
            CreateBiTree(&(*T)->rchild);
        }
    }
    
    /*以结点p为根的子树中序线索化*/
    void InThreading(BiThrTree p)
    {
    	/*pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索*/
    	if(p)
    	{
    		InThreading(p->lchild);            /*左子树递归线索化*/
    		if(!(p->lchild) )                      /*p的左孩子为空*/
    		{                  
    			p->LTag=1;                     /*给p加上左线索*/
    			p->lchild=pre;                 /*p的左孩子指针指向pre(前驱)*/
    		}
    		else
    		{
    			p->LTag=0;
    		}
    		if(!(pre->rchild) )                  /*pre的右孩子为空*/
    		{
    			pre->RTag=1;                  /*给pre加上右线索*/
    			pre->rchild=p;                /*pre的右孩子指针指向p(后继)*/
    		}
    		else
    		{
    			pre->RTag=0;
    		}
    		pre=p;                            /*保持pre指向p的前驱*/
    		InThreading(p->rchild);           /*右子树递归线索化*/
    	}
    }
    /*带头结点的中序线索化*/
    void InOrderThreading(BiThrTree &Thrt,BiThrTree T)
    {
    	/*中序遍历二叉树T,并将其中序线索化,Thrt指向头结点*/
    	Thrt=new BiThrNode;  		/*建头结头*/
    	Thrt->LTag=0;               /*头结点有左孩子,若树非空,则其左孩子为树根*/       
    	Thrt->RTag=1;               /*头结点的右孩子指针为右线索*/
    	Thrt->rchild=Thrt;          /*初始化时右指针指向自己*/
    	if(!T) Thrt->lchild=Thrt;   /*若树为空,则左指针也指向自己*/
    	else
    	{
    		Thrt->lchild=T; pre=Thrt; /*头结点的左孩子指向根,pre初值指向头结点*/
    		InThreading(T);          /*调用上述算法,对以T为根的二叉树进行中序线索化*/
    		pre->rchild=Thrt;        /*算法结束后,pre为最右结点,pre的右线索指向头结点*/
    		pre->RTag=1;
    		Thrt->rchild=pre;        /*头结点的右线索指向pre*/
    	} 
    }  
    /*遍历中序线索二叉树*/
    void InOrderTraverse_Thr(BiThrTree T)
    {
    	/*T指向头结点,头结点的左链lchild指向根结点*/
    	/*中序遍历二叉线索树T的非递归算法,对每个数据元素直接输出*/
    	BiThrTree p=T->lchild;    /*p指向根结点*/        
    	while(p!=T)
    	{
            while(p->LTag == 0)      /*沿左孩子向下*/
    		{
    		     p=p->lchild;
    		}
    		cout<<p->data<<" ";           /*访问其左子树为空的结点*/
    		while(p->RTag == 1 && p->rchild!=T)  /*沿右线索访问后继结点*/
    		{
    		    p=p->rchild;
    			cout<<p->data<<" ";
    		}
    		p=p->rchild;
    	}
    	cout<<p->data;
    }
    int main()
    {
    	BiThrTree T;
    	BiThrTree Thrt;
    	cout<<"Input the Threaded BinaryTree 's node:"<<endl;
    	CreateBiTree(&T);
    	InOrderThreading(Thrt,T); /*带头结点的中序线索化*/
    	cout<<"InOrderTraverse_Thr:"<<endl;
    	InOrderTraverse_Thr(T);   /*遍历中序线索二叉树*/
    	return 0;
    }
    

    运行演示

    二叉树结构图

    参考文献

    • 数据结构-用C语言描述(第二版)[耿国华]
  • 相关阅读:
    待完成
    [NOI2006]神奇口袋
    [UVA 10529]Dumb Bones
    概率与期望习题总结
    [SHOI2012]随机树
    [luogu3412]仓鼠找sugar II
    [CF908D]New Year and Arbitrary Arrangement
    [清华集训]小 Y 和恐怖的奴隶主
    [SDOI2015]序列统计
    [luogu3600]随机数生成器
  • 原文地址:https://www.cnblogs.com/yjlaugus/p/8999244.html
Copyright © 2011-2022 走看看