zoukankan      html  css  js  c++  java
  • 树和二叉树1——链式二叉树基础

    本文代码基于【数据结构】【严蔚敏】【清华大学】
    包含了大多数二叉树的基本操作

    1.准备部分的代码:
    用c++其实就是用了个max()函数

    #include <stdio.h>
    #include <stdlib.h>//malloc和exit函数所需头文件 
    #include <iostream>
    using namespace std;
    #define MaxSize 	100
    typedef char ElemType;
    

    当然也可以改成C,记得加上一个自定义max函数

    #include <stdio.h>
    #include <stdlib.h>//malloc和exit函数所需头文件 
    #define MaxSize 	100
    typedef char ElemType;
    
    int max(int a,int b)
    {
    	return a>b?a:b;
     } 
    

    2.构造二叉树结点
    包括数据域和左右孩子指针

    typedef struct BiTNode {
        ElemType    data;
        struct BiTNode	*lchild, *rchild; 	// 左右孩子指针
    } BiTNode, *BiTree;
    

    3.先序输入二叉树中结点的值
    一些必要的注解:
    ①TheBinaryTree为结构体指针,指向结构体
    BiTree TheBinaryTree=BiTNode *TheBinaryTree
    ②T为TheBinaryTree的引用,是结构体指针
    BiTree &T= BiTNode *&T
    ③BT是结构指针TheBinaryTree的指针,BT指向结构体指针
    BiTNode **BT=BiTree *BT
    所有有两种 CreateBiTree写法:

     
    void CreateBiTree(BiTNode* &T)//BiTree &T== BiTNode* &T
    {
        //  按先序次序输入二叉树中结点的值
        //  构造二叉链表表示的二叉树T。
        ElemType	ch;
    
        static	int	i = 0;
        char	pch[] = "ABC$$DE$G$$F$$$";				    // 欲产生的 先序序列。图6.8(b)
        ch = pch[i++];
    
        if(ch == '$') 										// 空树
            T = NULL;
        else {
            T = (BiTree)malloc(sizeof(BiTNode));
            if(!T)											// 检测是否申请结点成功
                exit(-1);
            T->data = ch; 									// 生成根结点
            CreateBiTree(T->lchild); 						// 构造左子树
            CreateBiTree(T->rchild); 						// 构造右子树
        }
    }
    
    void CreateBiTree_Pointer(BiTNode **BT)//BiTree *BT BT此时为指针的指针, BiTNode* *BT==BiTree *BT 
    {
        //  按先序次序输入二叉树中结点的值
        //  构造二叉链表表示的二叉树BT。
        ElemType	ch;
        static	int	i = 0;
        char	pch[] = "AB D  C  ";								// 欲产生的二叉树 先序序列
        ch = pch[i++];
        //scanf("%c",&ch);
        if(ch == ' ') 												// 空树
            *BT = NULL;
        else {
            *BT = (BiTree)malloc(sizeof(BiTNode));
            if(!*BT)												// 检测是否申请结点成功
                exit(-1);
            (*BT)->data = ch; 										// 生成根结点
            CreateBiTree_Pointer(&(*BT)->lchild); 						// 构造左子树
            CreateBiTree_Pointer(&(*BT)->rchild); 						// 构造右子树
        }
    }
    

    4.三种遍历(递归)

    // 中序遍历
    void InOrderTraversal(BiTree BT)
    {
        if(BT) {
            InOrderTraversal(BT->lchild);
            printf("%c ", BT->data);
            InOrderTraversal(BT->rchild);
        }
    }
    
    //先序遍历
    void PreOrderTraversal(BiTree BT)
    {
        if(BT) {
            printf("%c ", BT->data);
            PreOrderTraversal(BT->lchild);
            PreOrderTraversal(BT->rchild);
        }
    }
    
    // 后序遍历
    void PostOrderTraversal(BiTree BT)
    {
        if(BT) {
            PostOrderTraversal(BT->lchild);
            PostOrderTraversal(BT->rchild);
            printf("%c ", BT->data);
        }
    }
    

    5.中序遍历非递归遍历算法(关于其他遍历算法之后还会写文章提到)

    // 中序遍历非递归遍历算法
    //利用压栈 
    void InOrderTraversal_NoRecursion(BiTNode *T)
    {
        BiTNode	*Stack[MaxSize];//BiTree Stack[MaxSize]
        int	top = -1;
    
        while(T || (top != -1)) {
            while(T) {												// 一直向左并将沿途结点压入堆栈
                Stack[++top] = T;
                T = T->lchild;
            }
    
            if(top != -1) {
                T = Stack[top--]; 						// 结点弹出堆栈
                printf("%c ", T->data); 				//(访问)打印结点
                T = T->rchild; 							// 转向右子树
            }
        }
    }
    

    6.输出叶子结点值

    // 输出二叉树中的叶子结点。
    void PreOrderPrintLeaves(BiTree BT)
    {
        if(BT) {
            if(BT->lchild == NULL && BT->rchild == NULL)
                printf("%c ", BT->data);
            PreOrderPrintLeaves(BT->lchild);
            PreOrderPrintLeaves(BT->rchild);
        }
    }
    

    7.输出深度

    // 求二叉树的深度
    int Binary_tree_Deepness(BiTNode *T)
    {
        if(T == NULL)
            return 0;
        else
            if(T->lchild == NULL && T->rchild == NULL)
                return 1;
            else
                return 1 + max(Binary_tree_Deepness(T->lchild), Binary_tree_Deepness(T->rchild));
    }
    //表示形式2
    int Binary_tree_Deepness_Post(BiTNode *T)
    {
        int h1, h2;
        if(T == NULL)
            return 0;
        h1 = Binary_tree_Deepness_Post(T->lchild);
        h2 = Binary_tree_Deepness_Post(T->rchild);
        if(T->lchild == NULL && T->rchild == NULL)
            return 1;
        else
            return 1 + max(h1, h2);
    }
    

    8.求度为 2 的结点数

    //求二叉树的度为 2 的结点数算法
    int BT_CountDegree2(BiTNode *T)
    {
        int n1, n2; 
        if (T == NULL)
            return 0;
        else {
            n1 = BT_CountDegree2(T->lchild);
            n2 = BT_CountDegree2(T->rchild);
            if (T->lchild != NULL && T->rchild != NULL)
                return 1 + n1 + n2;
            else
                return n1 + n2;
        }
    }
    

    9.构造和销毁
    PS:完整代码中没用到构造和销毁,Init某种意义上可有可无,destroy最好还是加一下

    Status InitBiTree(BiTree &T)
    {
        // 操作结果: 构造空二叉树T
        T = NULL;
        return OK;
    }
    
    
    void DestroyBiTree(BiTree &T)
    {
        // 初始条件: 二叉树T存在。操作结果: 销毁二叉树T
        if(T) {	// 非空树
            if(T->lchild) 							// 有左孩子
                DestroyBiTree(T->lchild); 			// 销毁左孩子子树
            if(T->rchild) 							// 有右孩子
                DestroyBiTree(T->rchild); 			// 销毁右孩子子树
            free(T); 								// 释放根结点
            T = NULL; 								// 空指针赋0
        }
    }
    

    10.主函数

    int	main()
    {
        BiTree	TheBinaryTree;//BiTNode *TheBinaryTree
    
        printf("
    建立二叉树,请输入结点值系列:
    ");
        CreateBiTree(TheBinaryTree);//TheBinaryTree为结构体指针 
    
        printf("
    先序遍历序列:
    ");
        PreOrderTraversal(TheBinaryTree);
    
        printf("
    中序遍历序列:
    ");
        InOrderTraversal(TheBinaryTree);
        printf("
    中序遍历序列 - 中序遍历非递归算法:
    ");
        InOrderTraversal_NoRecursion(TheBinaryTree);
    
        printf("
    后序遍历序列:
    ");
        PostOrderTraversal(TheBinaryTree);
    
        printf("
    二叉树的深度为:
    ");
        //printf("%d",Binary_tree_Deepness_Post(TheBinaryTree));
        printf("%d", Binary_tree_Deepness(TheBinaryTree));
    
        printf("
    叶子结点为:
    ");
        PreOrderPrintLeaves(TheBinaryTree);
        
        printf("
    度为2的结点个数为:
    ");
        printf("%d", BT_CountDegree2(TheBinaryTree));
    
        return 1;
    }
    

    便于复制完整源代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    
    #define MaxSize 	100
    typedef char ElemType;
    
    typedef struct BiTNode {
        ElemType    data;
        struct BiTNode	*lchild, *rchild; 				// 左右孩子指针
    } BiTNode, *BiTree;
    
    //TheBinaryTree为结构体指针,指向结构体
    //BiTree  TheBinaryTree==BiTNode *TheBinaryTree
    //BiTree &T== BiTNode* &T    T为TheBinaryTree的引用,是结构体指针
    //BiTNode **BT==BiTree *BT    BT是结构指针TheBinaryTree的指针, BT指向结构体指针 
    void CreateBiTree(BiTNode* &T)//BiTree &T== BiTNode* &T
    {
        //  按先序次序输入二叉树中结点的值
        //  构造二叉链表表示的二叉树T。
        ElemType	ch;
    
        static	int	i = 0;
        char	pch[] = "ABC$$DE$G$$F$$$";				// 欲产生的 先序序列。图6.8(b)
        ch = pch[i++];
    
        if(ch == '$') 										// 空树
            T = NULL;
        else {
            T = (BiTree)malloc(sizeof(BiTNode));
            if(!T)											// 检测是否申请结点成功
                exit(-1);
            T->data = ch; 									// 生成根结点
            CreateBiTree(T->lchild); 						// 构造左子树
            CreateBiTree(T->rchild); 						// 构造右子树
        }
    }
    
    void CreateBiTree_Pointer(BiTNode **BT)//BiTree *BT BT此时为指针的指针, BiTNode* *BT==BiTree *BT 
    {
        //  按先序次序输入二叉树中结点的值
        //  构造二叉链表表示的二叉树BT。
        ElemType	ch;
        static	int	i = 0;
        char	pch[] = "AB D  C  ";								// 欲产生的二叉树 先序序列
        ch = pch[i++];
        //scanf("%c",&ch);
        if(ch == ' ') 												// 空树
            *BT = NULL;
        else {
            *BT = (BiTree)malloc(sizeof(BiTNode));
            if(!*BT)												// 检测是否申请结点成功
                exit(-1);
            (*BT)->data = ch; 										// 生成根结点
            CreateBiTree_Pointer(&(*BT)->lchild); 						// 构造左子树
            CreateBiTree_Pointer(&(*BT)->rchild); 						// 构造右子树
        }
    }
    
    // 中序遍历
    void InOrderTraversal(BiTree BT)
    {
        if(BT) {
            InOrderTraversal(BT->lchild);
            printf("%c ", BT->data);
            InOrderTraversal(BT->rchild);
        }
    }
    
    //先序遍历
    void PreOrderTraversal(BiTree BT)
    {
        if(BT) {
            printf("%c ", BT->data);
            PreOrderTraversal(BT->lchild);
            PreOrderTraversal(BT->rchild);
        }
    }
    
    // 后序遍历
    void PostOrderTraversal(BiTree BT)
    {
        if(BT) {
            PostOrderTraversal(BT->lchild);
            PostOrderTraversal(BT->rchild);
            printf("%c ", BT->data);
        }
    }
    
    // 中序遍历非递归遍历算法
    //利用压栈 
    void InOrderTraversal_NoRecursion(BiTNode *T)
    {
        BiTNode	*Stack[MaxSize];//BiTree Stack[MaxSize]
        int	top = -1;
    
        while(T || (top != -1)) {
            while(T) {												// 一直向左并将沿途结点压入堆栈
                Stack[++top] = T;
                T = T->lchild;
            }
    
            if(top != -1) {
                T = Stack[top--]; 						// 结点弹出堆栈
                printf("%c ", T->data); 				//(访问)打印结点
                T = T->rchild; 							// 转向右子树
            }
        }
    }
    
    // 输出二叉树中的叶子结点。
    void PreOrderPrintLeaves(BiTree BT)
    {
        if(BT) {
            if(BT->lchild == NULL && BT->rchild == NULL)
                printf("%c ", BT->data);
            PreOrderPrintLeaves(BT->lchild);
            PreOrderPrintLeaves(BT->rchild);
        }
    }
    
    // 求二叉树的深度
    int Binary_tree_Deepness(BiTNode *T)
    {
        if(T == NULL)
            return 0;
        else
            if(T->lchild == NULL && T->rchild == NULL)
                return 1;
            else
                return 1 + max(Binary_tree_Deepness(T->lchild), Binary_tree_Deepness(T->rchild));
    }
    
    int Binary_tree_Deepness_Post(BiTNode *T)
    {
        int h1, h2;
    
        if(T == NULL)
            return 0;
    
        h1 = Binary_tree_Deepness_Post(T->lchild);
        h2 = Binary_tree_Deepness_Post(T->rchild);
        if(T->lchild == NULL && T->rchild == NULL)
            return 1;
        else
            return 1 + max(h1, h2);
    }
    
    //求二叉树的度为 2 的结点数算法
    int BT_CountDegree2(BiTNode *T)
    {
        int n1, n2; 
        if (T == NULL)
            return 0;
        else {
            n1 = BT_CountDegree2(T->lchild);
            n2 = BT_CountDegree2(T->rchild);
            if (T->lchild != NULL && T->rchild != NULL)
                return 1 + n1 + n2;
            else
                return n1 + n2;
        }
    }
    
    int	main()
    {
        BiTree	TheBinaryTree;//BiTNode *TheBinaryTree
    
        printf("
    建立二叉树,请输入结点值系列:
    ");
        CreateBiTree(TheBinaryTree);//TheBinaryTree为结构体指针 
    
        printf("
    先序遍历序列:
    ");
        PreOrderTraversal(TheBinaryTree);
    
        printf("
    中序遍历序列:
    ");
        InOrderTraversal(TheBinaryTree);
        printf("
    中序遍历序列 - 中序遍历非递归算法:
    ");
        InOrderTraversal_NoRecursion(TheBinaryTree);
    
        printf("
    后序遍历序列:
    ");
        PostOrderTraversal(TheBinaryTree);
    
        printf("
    二叉树的深度为:
    ");
        //printf("%d",Binary_tree_Deepness_Post(TheBinaryTree));
        printf("%d", Binary_tree_Deepness(TheBinaryTree));
    
        printf("
    叶子结点为:
    ");
        PreOrderPrintLeaves(TheBinaryTree);
        
        printf("
    度为2的结点个数为:
    ");
        printf("%d", BT_CountDegree2(TheBinaryTree));
    
        return 1;
    }
    
  • 相关阅读:
    linux 安装ssh以及ssh用法与免密登录
    linux下安装Tomcat和java jdk
    光盘文件的挂载和yum源配置
    linux常用命令
    使用样式更改多个控件的外观
    silverlight 控件初始化和布局
    XML的读写
    dataset对XML的操作。writexml() and readxml。dataset.AcceptChanges()。dataset.DIspose()。释放资源
    C# 结构体 struct
    C#操作XML小结(转)
  • 原文地址:https://www.cnblogs.com/vivid-victory/p/10090458.html
Copyright © 2011-2022 走看看