数据结构7(自用)

线性结构存储方式:连续存储/离散存储

逻辑结构:线性与非线性(树和图)

物理结构:

模块二--------------非线性结构(数和图)

树:定义:

      专业定义:有且只有一个称为根的节点,有若干个互不相交的子树,这些子树本身也是树

                      (就像一棵倒过来的树,一串葡萄)

      专业术语:节点、父节点、子节点、子孙、堂兄弟、深度(从根节点到最底层节点的层数,根                          节点是第一层)、叶子节点(没有子节点的节点)、非终端节点(非叶子节点)、                          度(子节点的个数)

      应用:

     树是数据库中数据组织一种重要形式

     操作系统子父进程的关系本身就是一棵树

     面向对象语言中类的继承关系

     赫夫曼树:一个事物有n种取值,且‘取每一种的概率不同,怎么编程解决

       分类:

               一般树:任意一个节点的子节点的个数都不受限制

               二叉树:任意一个节点的子节点的个数最多是两个,且子节点的位置不可以更改

                             分类:一般二叉树、满二叉树(在不增加层数的前提下,无法再多添加一个节                                            点的二叉树)、完全二叉树(如果只是删除了满二叉树最底层最右边连                                            续的若干个节点,这样形成的二叉树就是完全二叉树),

                                        满二叉树是完全二叉树的一个特例。

               森林:n个互不相交的树的集合

       存储:两种---数组(内部必须是完全二叉树)/链表,一下均是先转化为二叉树存储,而二叉                      树用数组/链式存储,连续存储就是完全二叉树存储。

                  二叉树的存储:

                                        连续存储[完全二叉树]:优点:查找某个节点的父节点和子节点(也包括                                                                                            判断有没有子节点)

                                                                              缺点:耗费内存空间过大

 问题:明明只需要保存红色的点,为什么要保存这棵树,因为别人不可以根据这些点推算出这个树,因为它本身不是线性结构,所以保存的时候哪个在前哪个在后本身就是个问题,

                                        链式存储:分三块:数据本身,左指针,右指针,但是空指针会浪费内                                                              存空间(n个节点只浪费n+1个空指针的空间,已经很小了)

                  一般树的存储:

                                         双亲表示法:求父节点方便                      

                                         孩子表示法: 求子节点方便                              

                                         双亲孩子表示法:求父节点和子节点都方便

                                         二叉树表示法:把一个普通树转化成二叉树,设法保证任意一个节点左                                                                     指针域指向它的第一个孩子,右指针域指向它的下一个                                                                     兄弟,一个普通树转化为二叉树一定没有右子树

                  森林的存储:把B当A的兄弟,G当B的兄弟

非线性要转成线性存储:

            先序: 

            中序;

            后序:

    二叉树操作:

           1、树的遍历:(单纯知道任意一个序列都无法把原始二叉树还原,but已知两种可以)

                先序遍历:先访问根节点,再先序访问左子树,再先序访问右子树

                                  

                中序遍历:中序遍历左子树,再访问根节点,再中序遍历右子树                                 

                后序遍历:后序遍历左子树,后序遍历右子树,再a访问根节点 

         2、已知两种遍历序列求原始二叉树

              通过先序和中序(中序和后续)可以还原出原始二叉树,but已知先序和后序无法还原

       应用:

       已知先序与中序求后序:eg:先序:ABCDEFGH;中序:BDCEAFHG ,求后序:

                                                     后续:DECBHGFA

                                              eg:先序:ABDGHCEFI;中序:GDHBAECIF,求后序

                                                      后续:GHDBEIFCA

       已知中序和后序求先序:eg:中序:BDCEAFHG;  后序:DECBHGFA;求先序

                                                      先序:ABCDEFGH 

        程序:

#include<stdio.h>

#include<malloc.h>

struct BTNode

{

  int data;

  struct BTNode * pLchild;  //p是指针,L是左,child是孩子

  struct BTNode * pRchild; 

} ;

struct BTNode * CreateBTree(void);

void   PreTraverseBTree(struct BTNode * pT)

 void   InTraverseBTree(struct BTNode * pT)

void   PostTraverseBTree(struct BTNode * pT)

int main(void)

{  

    struct  BTNode * pT = CreateBTree();

    PreTraverseBTree(pT);

    InTraverseBTree(pT);

    PostTraverseBTree(pT);

    return 0;

}   

void   PreTraverseBTree(struct BTNode * pT)

{

if(pT != NULL)

{

printf("%c\n",pT->data);

if(NULL != pT->pLchild);

{

 PreTraverseBTree(pT->pLchild);

}

if(NULL != pT->pRchild);

{

PreTraverseBTree(pT->pRchild);

}

}

 //先访问根节点,再先序访问左子树,再先序访问右子树

}

void   InTraverseBTree(struct BTNode * pT)

{

if(pT != NULL)

{

if(NULL != pT->pLchild);

{

 InTraverseBTree(pT->pLchild);

}

printf("%c\n",pT->data);

if(NULL != pT->pRchild);

{

InTraverseBTree(pT->pRchild);

}

}

 //先访问根节点,再先序访问左子树,再先序访问右子树

}

void   PostTraverseBTree(struct BTNode * pT)

{

if(pT != NULL)

{

if(NULL != pT->pLchild);

{

 PostTraverseBTree(pT->pLchild);

}

if(NULL != pT->pRchild);

{

PostTraverseBTree(pT->pRchild);

}

printf("%c\n",pT->data);

}

 //先访问根节点,再先序访问左子树,再先序访问右子树

}

struct BTNode * CreateBTree()

{

 struct BTNode * pA = (struct BTNode *)malloc(sizeof(struct BTNode));

struct BTNode * pB = (struct BTNode *)malloc(sizeof(struct BTNode));

struct BTNode * pC = (struct BTNode *)malloc(sizeof(struct BTNode));

struct BTNode * pD = (struct BTNode *)malloc(sizeof(struct BTNode));

struct BTNode * pE = (struct BTNode *)malloc(sizeof(struct BTNode));

pA->data = 'A';

pB->data = 'B';

pC->data = 'C';

pD->data = 'D';

pE->data = 'E';

pA->pLchild = pB;

pA->pLchild = pC;

pB->pLchild = pB->pRchild = NULL;

pC->pLchild = pD;

pC->pLchild = NULL;

pD->pLchild = NULL;

pD->pLchild = pE;

pE->pLchild = pE->pRchild = NULL;

return pA;

}                                               

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值