链式二叉树
//链式二叉树: #include<stdio.h> #include<malloc.h> #include<stdlib.h> typedef struct btree { struct btree * pLBtree; char data; struct btree * pRBtree; }Btree,* pBtree; pBtree create_Btree(void); void traverse_Btree(pBtree); int main(void) { pBtree pT=create_Btree(); puts("后序遍历为:"); traverse_Btree(pT); return 0; } pBtree create_Btree() { pBtree pT=(pBtree)malloc(sizeof(Btree)); pBtree pA=(pBtree)malloc(sizeof(Btree)); pBtree pB=(pBtree)malloc(sizeof(Btree)); pBtree pC=(pBtree)malloc(sizeof(Btree)); pBtree pD=(pBtree)malloc(sizeof(Btree)); pBtree pE=(pBtree)malloc(sizeof(Btree)); pBtree pF=(pBtree)malloc(sizeof(Btree)); pBtree pG=(pBtree)malloc(sizeof(Btree)); if( !(pA||pB||pC||pD||pE||pF||pG) ) { puts("动态内存分配失败!"); exit(-1); } pT=pA; pA->data='A'; pB->data='B'; pC->data='C'; pD->data='D'; pE->data='E'; pF->data='F'; pG->data='G'; pA->pLBtree=pB; pB->pRBtree=pC; pB->pLBtree=NULL; pC->pLBtree=pC->pRBtree=NULL; pA->pRBtree=pD; pD->pLBtree=pE; pD->pRBtree=NULL; pE->pLBtree=pF; pE->pRBtree=pG; pF->pLBtree=pF->pRBtree=NULL; pG->pLBtree=pG->pRBtree=NULL; return pT; } void traverse_Btree(pBtree pT) { if(pT->pLBtree!=NULL) { traverse_Btree(pT->pLBtree); } if(pT->pRBtree!=NULL) { traverse_Btree(pT->pRBtree); } if(pT!=NULL) { putchar(pT->data); putchar('\n'); } return; } /* 树的基本概念: 先复习一下: 逻辑结构:逻辑结构就是人为的一种结构 线性结构:通过一条线能够串起来的结构 数组 链表 栈和队列就是一种存储结构,可以算特殊的线性的结构,是数组和链表的一种应用 非线性结构: 树 图 物理结构:物理结构呢就是把逻辑结构,在内存当中实现存储 1、什么叫树:树是一种非线性数据结构。 1:专业的定义:有且只有一个根节点,每个节点都有一个父节点,或者有n个不相交的子节点 2:通俗的来说:树是由节点(结构体)和互不相交的边(指针)组成的。只有一个根节点,可以有多个子节点。 2、树的专业术语:节点 根节点 子节点 叶子 子孙节点 左孩子 右孩子 堂兄弟 兄弟 父节点 深度(树的层级数) 左节点 右节点 左子树 右子树 3、树的分类:一般树 有一个根节点,下面由任意个子节点组成的树叫一般树。 二叉树 一般二叉树:一个节点最多只能有两个子节点组成 满二叉树:一个节点由两个子节点组成 完全二叉树:就是删除满二叉树最低层级的右边开始删除,这样的树叫完全二叉树 森林 由n个不相交的树组成,叫做森林。n>1 叶子节点:叶子节点就是没有子节点的节点 非终端节点:也就是非叶子节点,有子节点的节点。 4、树的存储:就是把非线性的存储在线性的内存当中 一般树存储: 一般树转换为二叉树:父节点指向左节点,然后指向下一个兄弟。这样就把树转换成了二叉树 二叉树存储: 静态二叉树: 链式二叉树: 就是把一般二叉树树转换成满二叉树:通过补节点的方法 完全二叉树的存在就是为了存储。 二叉树的算法和数据结构比较成熟,所以满二叉树和完全二叉树的存在就是为了解决树的存储问题 森林存储: 把森林转换成一般二叉树——》完全二叉树:这样进行存储的。 森林的第一个树看成根节点,其余的树看成是兄弟 根节点的左指针域指向左孩子,由指针域指向下一个兄弟。 节点:左指针域,中间是数据域,右边是右指针域 5、树的表示方法: 双亲表示法:能够很好的知道父节点是谁。数组:地址编号【数据域】【父节点(地址编号)】父节点不存在的为空 孩子表示法:能够很快的知道子节点有哪些。数组:地址编号 【数据域】->子节点(地址编号)->子节点...不存在的为^ 双亲孩子表示法:能够知道父节点是哪个和子节点有哪些:地址编号 【数据域】[父节点(地址编号)]->子节点->子节点 6、树的遍历:注:所有的遍历都是以根为中心的。为基准的。 先序遍历:先遍历根节点,再先序遍历左子树,在先序遍历右子树。也就是:根 左 右 中序遍历:先中序遍历左子树,在遍历根节点,最后中序遍历右子树 左 根 中 后序遍历:先后序遍历左子树,在后序遍历右子树,在遍历根节点 左 右 根 注:任何一个遍历方法都还原不了原始二叉树,只有先序和中序,或者中序和后序才能够还原原始二叉树 先序和后序无法还原二叉树。 已知先序和中序求后序?已知中序和后序求先序? */