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语言描述(第二版)[耿国华]
  • 相关阅读:
    Code Forces 650 C Table Compression(并查集)
    Code Forces 645B Mischievous Mess Makers
    POJ 3735 Training little cats(矩阵快速幂)
    POJ 3233 Matrix Power Series(矩阵快速幂)
    PAT 1026 Table Tennis (30)
    ZOJ 3609 Modular Inverse
    Java实现 LeetCode 746 使用最小花费爬楼梯(递推)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
  • 原文地址:https://www.cnblogs.com/yjlaugus/p/8999244.html
Copyright © 2011-2022 走看看