树-二叉树-线索二叉树

树:

n个结点的有限集,n=0时为空树,在任意一棵非空树中:1.有且仅有一个特定的称为根的结点;2.n>1时,其余节点可分为m个互不相交的有限集,每个集合本身又是一棵树-称为根的子树

#根唯一--子集互相不相交

结点的度:结点拥有的子树数目

树的度:取各结点的最大值

度为0称为叶节点--度不为0称为分支结点或非终端结点

树中最大层次称为树的深度或高度//第一层、第二层...

#双亲、兄弟、堂兄弟

有序树:从左到右有次序

森林:m棵互不相交的树


树的存储结构:

双亲表示法:以双亲为索引的关键字的一种存储方式--除了自身数据还存有指向双亲的指针(下标)

孩子表示法:(多重链表):

1.根据树的度申请足够的空间存放子树指针的结点--资源浪费

2.在结点元素后面加上一个度的数据,申请定量的空间--但初始化+维护难度巨大-时间浪费

3.数组+链表--数组中存放第一个孩子的地址,然后一个单链表所有的孩子连起来

//双亲孩子表示法

#define max_tree_size 100

typedef char elemtype


typedef struct CTNode

{

int child;  //孩子结点下标

struct CTNode *next  //指向下一个孩子的指针

} *childptr ;


//表头结构

typedef struct

{

elemtype data;  //存放在树中结点的数据

int parent;  //存放双亲的下标

childptr firstchile;  //指向第一个孩子的指针

} ctbox;


//树结构

typedef struct

{

  ctbox nodes(max_tree_size);  //结点数组

  int r,n;

}

二叉树:

是n个结点的有限集合,该集合为空集,或是有一个根节点+两棵互不相交分别称为根节点的左子树和右子树的二叉树组成。

#最多有两个子树,可以有一个或是没有

#左子树和右子树有次序,即使只有一棵树,也要区分左右

五种基本形态:1.空二叉树、2.只有一个根节点、3.只有左子树、4.只有右子树、5.全都有

特殊二叉树:1.斜树-往一边斜、2.满二叉树-所有分支节点都有左右子树+所有叶子在同一层、3.完全二叉树--序号从左到右,从上往下和满二叉树的序号位置完全一样(完全二叉树可以少一部份最右下层的叶子)、


二叉树的性质:

1.第i层至多有2^(i-1)个结点

2.深度为k的二叉树至多有2^k-1个结点

3.对于任何一棵二叉树T,如果其终端结点数为n0,杜威2的结点数位n2,则n0=n2+1

4.具有n结点的完全二叉树的深度位[log2(n)]+1  //取整

.....


二叉树的存储结构:

顺序存储结构:由于严格要求定义,可以在数组上直接表现逻辑结构(不存在的点用一个符号代替)

链式存储结构:(一般也用这种方式存储)//数据左右各一个指针--二叉链表

typedef struct binode

{

elemtype data

struct bitnode *lchild *rchild

} bitnode *bitree


二叉树的遍历:

遍历是指从根结点出发按照某种次序依次访问所有结点,使得每个结点被访问一次

遍历方式:

1.前序遍历:空,否则根节点-前序遍历左子树-前序遍历右子树

2.中序遍历:空,否则中序遍历左子树-根结点-中序遍历右子树(降到同一直线从左往右)

3.后序遍历:空,否则从左到右先叶子后结点-最后根结点

4.层序遍历:按层


建立二叉树:

//前序遍历-建立二叉树

#include

#include


typedef char elemtype;


typedef struct bitnode

{

char data;

struct bitnode *lchild ,*rchild;

}bitnode,*bitree;

//创建二叉树,约定前序遍历

createbitree(bitree *T)

{

  char c;

  scanf("%c",&c);

  if(' '==c)

  {

  *T=NULL;

}

else

{

  *T=(bitnode *)malloc(sizeof(bitnode));

  (*T)->data=c;

  createbitree(&(*T)->lchild);

  createbitree(&(*T)->rchild);

}

}

//访问二叉树结点的具体操作

visit(char c,int level)

{

printf("%c位于第%d层\n",c,level);

}


//遍历二叉树

preordertraverse(bitree T,int level)

{

if( T )

{

visit(T->data,level);  //1

preordertraverse(T->lchild,level+1);  //2

preordertraverse(T->rchild,level+1);  //3

//前序遍历 123,后序遍历231,中序遍历213

}

}


int main()

{

int level=1;

bitree T=NULL;

createbitree(&T);

preordertraverse(T,level);

return 0;

}


线索二叉树:

选择中序遍历,每隔一个会有造成浪费的结点,利用这些空间放前驱和后继

将定义好的结构进行扩容:lchild .ltag .data .rtag .rchild

Tag为0时,指向左孩子,1时指向前驱

程序中存在修改过程--

//中序遍历-建立线索二叉树

#include

#include


typedef char elemtype;

//link(0)--指向左右孩子的指针//thread(1)指向前驱后继的线索

typedef enum {link , thread} pointernag;


typedef struct bitnode

{

pointernag ltag;

pointernag rtag;  

char data;

struct bitnode *lchild ,*rchild;

}bitnode,*bitree;


//全局变量- 始终指向刚刚访问过的结点

bitree  pre;

//创建二叉树,按照前序遍历

createbitree(bitree *T)

{

  char c;

  scanf("%c",&c);

  if(' '==c)

  {

  *T=NULL;

}

else

{

  *T=(bitnode *)malloc(sizeof(bitnode));

  (*T)->data=c;

  //多出来的那部分

  (*T)->ltag=link;

  (*T)->rtag=link;   

  createbitree(&(*T)->lchild);

  createbitree(&(*T)->rchild);

}

}

//访问二叉树结点的具体操作

visit(char c,int level)

{

printf("%c位于第%d层\n",c,level);

}


//遍历二叉树--中序

preordertraverse(bitree T,int level)

{

if( T )

{

preordertraverse(T->lchild,level+1);  

if( !T->lchild)  //如果该节点没有左孩子,设置ltag为thread并把lchild指向前驱

{

T->ltag = thread;

T->lchild=pre;

}

if( !pre->rchild )

{

pre->rtag =thread;

pre->rchild =T;

}

pre =T;

preordertraverse(T->rchild,level+1);  

}

}

inorderthreading(bitree *p ,bitree T)

{

*p = (bitree)malloc(sizeof(bitnode));

(*p)->ltag=link;

(*p)->rtag=thread;

(*p)->rchild=*p;

if(!T)

{

(*p)->lchild=*p;

}

else

{

(*p)->lchild=T;

pre=*p;

preordertraverse(T,1);

pre->rchild=*p;

pre->rtag =thread;

(*p)->rchild=pre;

}

}

visit2(char c)

{

printf("%c\n",c);

}


//中序遍历二叉树,非递归

void inordertraverse(bitree T)

{

bitree p;

p=T->lchild ;

while (p!=T)

{

while(p->ltag ==link)

{

p=p->lchild;

}

visit2(p->data);

while(p->rtag ==thread && p->rchild !=T)

{

p=p->rchild ;

visit2(p->data );

}

p=p->rchild ;

}


 }



int main()

{

int level=1;

bitree T=NULL, p=NULL;

createbitree(&T);

inorderthreading( &p,T );

printf("输出结果为:\n");

inordertraverse(p);

return 0;

}

你可能感兴趣的:(树-二叉树-线索二叉树)