C 二叉树 1

二叉链表:

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

//1
typedef struct BiTNode
{
    int        data;
    struct BiTNode *lchild, *rchild;
}BiTNode;

typedef struct BiTNode * BiTree;

//2
//第二种表示方法 三叉链表
//三叉链表
typedef struct TriTNode
{
    int data;
    //左右孩子指针
    struct TriTNode *lchild, *rchild;
    struct TriTNode *parent;
}TriTNode, *TriTree;

//双亲链表
#define MAX_TREE_SIZE 100
typedef struct BPTNode
{
    int data;
    int parentPosition; //指向双亲的指针 //数组下标
    char LRTag; //左右孩子标志域
}BPTNode;

typedef struct BPTree
{
    BPTNode nodes[100]; //因为节点之间是分散的,需要把节点存储到数组中
    int num_node;  //节点数目
    int root; //根结点的位置 //注意此域存储的是父亲节点在数组的下标
}BPTree;

//用这个数据结构能表达出一颗树。。。能,怎么表达?不能why

void main()
{
    BPTree myTree; //

    myTree.root = 0; //数组的0号位置 是根结点
    myTree.nodes[0].data = ‘A‘;

    //B
    myTree.nodes[1].data = ‘B‘;
    myTree.nodes[1].parentPosition = 0;
    myTree.nodes[1].LRTag = 1;

    //C
    myTree.nodes[2].data = ‘C‘;
    myTree.nodes[2].parentPosition = 0;
    myTree.nodes[2].LRTag = 2;

    system("pause");
}

void main11()
{
    BiTNode  nodeA, nodeB, nodeC, nodeD, nodeE;

    nodeA.lchild = NULL;
    nodeA.rchild = NULL;
    nodeA.data = 0;
    memset(&nodeA, 0, sizeof(BiTNode));
    memset(&nodeB, 0, sizeof(BiTNode));
    memset(&nodeC, 0, sizeof(BiTNode));
    memset(&nodeD, 0, sizeof(BiTNode));
    memset(&nodeE, 0, sizeof(BiTNode));

    nodeA.data = 1;
    nodeA.lchild = &nodeB;
    nodeA.rchild = &nodeC;
    nodeB.lchild = &nodeD;
    nodeC.lchild = &nodeE;

    printf("hello...\n");
    system("pause");
    return ;
}

中序非递归:

#include <iostream>
using namespace std;

#include "stack"

//1
typedef struct BiTNode
{
    int        data;
    struct BiTNode *lchild, *rchild;
}BiTNode;

typedef struct BiTNode * BiTree;

//递归 中序遍历
void InOrder(BiTNode *T)
{
    if (T == NULL)
    {
        return ;
    }

    if (T->lchild != NULL)
    {
        InOrder(T->lchild);
    }

    printf("%d ", T->data); //

    if (T->rchild != NULL)
    {
        InOrder(T->rchild);
    }
}

BiTNode *  GoFarLeft(BiTNode *T, stack<BiTNode *> &s)
{
    if (T ==NULL)
    {
        return NULL;
    }
    while (T->lchild != NULL) //一直往左走 ,找到中序遍历的起点
    {
        s.push(T);
        T = T->lchild; //让指针下移
    }
    return T; //
}

void MyInOrder(BiTNode *T)
{
    stack<BiTNode *> s; //
    BiTNode *t = GoFarLeft(T, s); //一直往左走 找到中序遍历的起点

    while (t != NULL)
    {
        printf("%d ", t->data);

        //若结点 有右子树,重复步骤1
        if (t->rchild != NULL)
        {
            t = GoFarLeft(t->rchild, s);
        }
        //若结点 没有右子树 看栈是否为空
        else if ( !s.empty() )
        {
            t = s.top(); //把栈顶弹出
            s.pop();
        }
        else
        {
            t = NULL;
        }
    }
}

void main()
{
    BiTNode  nodeA, nodeB, nodeC, nodeD, nodeE;

    nodeA.lchild = NULL;
    nodeA.rchild = NULL;
    nodeA.data = 0;
    memset(&nodeA, 0, sizeof(BiTNode));
    memset(&nodeB, 0, sizeof(BiTNode));
    memset(&nodeC, 0, sizeof(BiTNode));
    memset(&nodeD, 0, sizeof(BiTNode));
    memset(&nodeE, 0, sizeof(BiTNode));

    nodeA.data = 1;
    nodeB.data = 2;
    nodeC.data = 3;
    nodeD.data = 4;
    nodeE.data = 5;

    nodeA.lchild = &nodeB;
    nodeA.rchild = &nodeC;
    nodeB.lchild = &nodeD;
    nodeC.lchild = &nodeE;

    printf("\n中序遍历递归算法");
    InOrder(&nodeA);

    printf("\n中序遍历非递归算法");
    MyInOrder(&nodeA);

    cout<<"hello..."<<endl;
    system("pause");
    return ;
}

数的操作:

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

//1
typedef struct BiTNode
{
    int        data;
    struct BiTNode *lchild, *rchild;
}BiTNode;

typedef struct BiTNode * BiTree;

//先序遍历
void preOrder(BiTNode *T)
{
    if (T == NULL)
    {
        return ;
    }
    printf("%d ", T->data); //

    if (T->lchild != NULL)
    {
        preOrder(T->lchild);
    }

    if (T->rchild != NULL)
    {
        preOrder(T->rchild);
    }
}

void InOrder(BiTNode *T)
{
    if (T == NULL)
    {
        return ;
    }

    if (T->lchild != NULL)
    {
        InOrder(T->lchild);
    }

    printf("%d ", T->data); //

    if (T->rchild != NULL)
    {
        InOrder(T->rchild);
    }
}

void PostOrder(BiTNode *T)
{
    if (T == NULL)
    {
        return ;
    }

    if (T->lchild != NULL)
    {
        PostOrder(T->lchild);
    }

    if (T->rchild != NULL)
    {
        PostOrder(T->rchild);
    }

    printf("%d ", T->data); //
}

/*
        1
    2        3
4        5
*/

//求树的叶子结点的个数

int  sum = 0;
void coutLeafNum(BiTNode *T)
{
    if (T == NULL)
    {
        return ;
    }
    if (T->lchild == NULL && T->rchild ==NULL)
    {
        sum ++;
    }
    coutLeafNum(T->lchild); //求左子树的叶子结点个数

    coutLeafNum(T->rchild); //求右子树 叶子结点个数
}

//1 递归函数遇上全局变量 ===>函数参数
//2 //遍历的本质 强化
    //访问树的路径是相同的,是不过是计算叶子结点的时机不同....

void coutLeafNum2(BiTNode *T, int *sum)
{
    if (T == NULL)
    {
        return ;
    }
    if (T->lchild == NULL && T->rchild ==NULL)
    {
        //*sum++;
        //*sum = *sum +1;
        (*sum )++ ;  //++后置 ++   先*p 然后sum++
                    //1   p++

                    //1 是让实参++ 而不是让地址++
    }

    coutLeafNum2(T->lchild, sum); //求左子树的叶子结点个数

    coutLeafNum2(T->rchild, sum); //求右子树 叶子结点个数
}

void coutLeafNum3(BiTNode *T, int *sum)
{
    if (T == NULL)
    {
        return ;
    }

    coutLeafNum3(T->lchild, sum); //求左子树的叶子结点个数

    coutLeafNum3(T->rchild, sum); //求右子树 叶子结点个数

    if (T->lchild == NULL && T->rchild ==NULL)
    {
        (*sum )++ ;   //计算叶子结点
    }
}

//求树的高度
int Depth(BiTNode *T)
{
    int  depthval = 0;
    int  depthLeft = 0, depthRight = 0;

    if (T == NULL)
    {
        return 0;
    }

    depthLeft =  Depth(T->lchild); //求左子树的高度
    depthRight = Depth(T->rchild); //求右子树的高度

    //1 + 谁大要谁
    depthval = 1 + ( (depthLeft>depthRight) ? depthLeft :depthRight );
    return depthval;
}

//copy二叉树
BiTNode* CopyTree(BiTNode *T)
{
    BiTNode *newlptr = NULL;
    BiTNode *newRptr = NULL;
    BiTNode *newNode = NULL;

    if (T == NULL)
    {
        return NULL;
    }

    newlptr = CopyTree(T->lchild);
    newRptr = CopyTree(T->rchild);

    //new结点
    newNode = (BiTNode *)malloc(sizeof(BiTNode)) ; //
    if (newNode == NULL)
    {
        return NULL;
    }

    newNode->data = T->data; //从旧树中copy数据
    newNode->lchild = newlptr; //新的左子树
    newNode->rchild = newRptr; //新的右子树
    return newNode;
}

void main()
{
    BiTNode  nodeA, nodeB, nodeC, nodeD, nodeE;

    nodeA.lchild = NULL;
    nodeA.rchild = NULL;
    nodeA.data = 0;
    memset(&nodeA, 0, sizeof(BiTNode));
    memset(&nodeB, 0, sizeof(BiTNode));
    memset(&nodeC, 0, sizeof(BiTNode));
    memset(&nodeD, 0, sizeof(BiTNode));
    memset(&nodeE, 0, sizeof(BiTNode));

    nodeA.data = 1;
    nodeB.data = 2;
    nodeC.data = 3;
    nodeD.data = 4;
    nodeE.data = 5;

    nodeA.lchild = &nodeB;
    nodeA.rchild = &nodeC;
    nodeB.lchild = &nodeD;
    nodeC.lchild = &nodeE;

    //拷贝二叉树
    {
        BiTNode *newTree = NULL;
        newTree = CopyTree(&nodeA);
        printf("\n中序遍历新树:");
        InOrder(newTree);
    }

    {
        //求树的高度
        int depth = Depth(&nodeA);
        printf("depth:%d \n", depth);

    }

    //计算树的叶子结点
    {
        int mysum = 0;
        coutLeafNum(&nodeA);
        printf("sum:%d \n", sum);

        coutLeafNum2(&nodeA, &mysum);
        printf("mysum:%d \n", mysum);

        mysum = 0;
        coutLeafNum3(&nodeA, &mysum);
        printf("mysum:%d \n", mysum);

    }

    //printf("\n先序遍历树: ");
    //preOrder(&nodeA);

    printf("\n中序遍历树: ");
    InOrder(&nodeA);

    //printf("\n后序遍历树: ");
    //PostOrder(&nodeA);

    system("pause");
}
时间: 2024-08-28 17:41:18

C 二叉树 1的相关文章

C#实现二叉树的遍历

C#实现二叉树的前序.中序.后序遍历. public class BinaryTreeNode     {         int value;         BinaryTreeNode left;         BinaryTreeNode right;         /// <summary>         /// 前序遍历         /// </summary>         /// <param name="tree">&l

【树4】二叉树的遍历

简介 遍历二叉树就是按照某种顺序,将树中的结点都枚举一遍,且每个结点仅仅访问一次.因为树不是线性的结构,遍历不像线性表那样简单,因此他的遍历需要特点的算法来完成. 从某种角度讲,对二叉树的遍历就是将树形结构转换为线性结构的操作. 二叉树的遍历方法主要有如下几种: 先序遍历:先访问root结点,再先序遍历左子树,再先序遍历右子树. 中序遍历:先中序遍历左子树,再访问root结点,再中序遍历右子树. 后序遍历:先后序遍历左子树,再后序遍历右子树,再访问root结点. 层遍历:从上到下,从左到右,一层

按之字形顺序打印二叉树

题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } }; */ class Solution { public: vector<vect

【数据算法】Java实现二叉树存储以及遍历

二叉树在java中我们使用数组的形式保存原数据,这个数组作为二叉树的数据来源,后续对数组中的数据进行节点化操作. 步骤就是原数据:数组 节点化数据:定义 Node节点对象 存储节点对象:通过LinkedList保存Node节点对象 在操作过程中我们需要将当前结点和前一节点.后一节点进行关系绑定 package tree; import java.util.LinkedList; import java.util.List; /** * 功能:把一个数组的值存入二叉树中,然后进行3种方式的遍历 *

二叉树的后序遍历(暴力版) 小白菜oj 1034

给出二叉树的前序遍历和中序遍历,求二叉树的后序遍历-- 作为一个搜索蒟蒻,我真的没有办法很和谐的A掉,但估计过几天就会写有关这个题的和谐的解法--但只是估计-- 下面讲述我的超暴力解法-- 首先,先由前序遍历得到一个父亲节点,然后再由中序遍历得到这个父亲节点的左子树和右子树中的元素(中序遍历中,该点的左边的所有点,都在它的左子树,右边的都在它的右子树,子树中的根节点是在这些节点的前序遍历中排名最靠前的),然后递归建树,之后在递归求后序遍历即可. 但这个方法有两个比较--&¥--&的问题:1

二叉树的序列化和反序列化

http://blog.csdn.net/qq_27703417/article/details/70958692 先序遍历二叉树,如果遇到空节点,就在str的末尾加上"#!","#"表示这个节点为空,节点值不存在,当然你也可以用其他的特殊字符,"!"表示一个值的结束.如果遇到不为空的节点,假设节点值为3,就在str的末尾加上"3!".现在请你实现树的先序序列化. 先序遍历 import java.util.*; //使用递归

【二叉树】 二叉树基础

在计算机科学中,二叉树是每个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree).二叉树常被用于实现二叉查找树和二叉堆. 二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒.二叉树的第i层至多有个结点:深度为k的二叉树至多有个结点:对任何一棵二叉树T,如果其终端结点数为,度为2的结点数为,则. 树和二叉树的三个主要差别: 树的结点个数至少为1,而二叉树的

二叉树的深度

输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 思路:使用递归的方法分别计算左右子树的深度 public class Solution { public int TreeDepth(TreeNode pRoot){ return pRoot == null? 0 : Math.max(TreeDepth(pRoot.left),TreeDepth(pRoot.right)) + 1;     } }

226反转二叉树 Invert Binary Tree

Invert a binary tree. 4 / 2 7 / \ / 1 3 6 9 to 4 / 7 2 / \ / 9 6 3 1 Trivia:This problem was inspired by this original tweet by Max Howell: Google: 90% of our engineers use the software you wrote (Homebrew), but you can't invert a binary tree on a wh

树、二叉树、森林的转换

树转换为二叉树 (1)加线.在所有兄弟结点之间加一条连线. (2)去线.树中的每个结点,只保留它与第一个孩子结点的连线,删除它与其它孩子结点之间的连线. (3)层次调整.以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明.(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子) 森林转换为二叉树 (1)把每棵树转换为二叉树. (2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来. 二叉树转换为树 是树转换为二