树(数据结构)

一:定义:

1)有且只有一个称为根的节点;

2)有若干个互不相交的子树,这些子树本身也是一颗树;

通俗一点讲,树由节点和边组成,每个节点只有一个父节点,但是可以有多个子节点,但有一个节点除外,

这个节点没有父节点,此节点称为根节点。

 

专业术语:

节点:

父节点:

子节点:

子孙节点:

堂兄弟:

深度:从根节点到最底层节点的层数(根节点为第一层,其子节点为第二层……)

叶子节点:没有子节点的节点(度为0),非0为终端节点

度:拥有的子树的个数

 

树的分类:

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

2)二叉树:子节点的个数最多两个,并且,其子树有左右之分,其次序不能任意颠倒;

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

 

二叉树又分为:

1)一般二叉树;

2)满二叉树;除了叶子节点外,每一个节点都有左右子树

3)完全二叉树:如果只删除了满二叉树最底层最右边的连续若干个节点,这样形成的二叉树就是

完全二叉树。

 

二叉树的存储形式

1)顺序存储:把一颗普通的二叉树,填补成一颗完全二叉树,然后按照从上至下,从左至右,1-n的编号进行

存储,可能会浪费一些空间。

#define MAX_TREE_SIZE 100

char tree[MAX_TREE_SIZE]

2)链式存储结构:

struct bitnode

{

int data;

struct bitnode *lchild,*rchild;

}

 

 

树的遍历:

1)先序;根->左->右

2)中序;左->根->右

3) 后序;左->右->根

 

二叉排序树

或者是一颗空树,或者是具有下列顺序的二叉树:

1)若他的左子树不为空,则左子树上面所有的节点都小于他的根节点,

2)若他的右子树不为空,则右子树上面所有的节点都大于他的根节点;

3)左右子树又分别是二叉排序树;

 

 

平衡二叉树:

它或者是一颗空树,或者是具有以下性质的树:

1)他的左子树和右子树又是一颗平衡二叉树

2) 左子树和右子树的深度之差不超过1(-1,0,1);

 

若将二叉树上的节点的平衡因子BF(Balance factor)定义为该节点的左子树减去他的右子树的深度,

则平衡二叉树的所有节点的平衡因子的绝对值不大于1,如果BF的绝对值大于1,则该二叉树就是不平衡的。

单右旋 SingleRotateWithRight(SRWR)

单左旋 SingleRotateWithLeft(SRWL)

双向先左后右旋转 DoubleRotateLeftRight(DRLR)

双向先右后左旋转 DoubleRotateRightLeft(DRRL)

 

树的创建与遍历:

#include<stdio.h>

#include<stdlib.h>

typedef int ElmentType;

typedef struct bitnode

{

ElmentType data;

struct bitnode *left;

struct bitnode *right;

}BitNode;

 

BitNode * InitTree(void)

{

BitNode * root = NULL;

BitNode *p = NULL;

ElmentType x;

while(1)

{

scanf("%d",&x);

if(x == 0)

break;

 

p = (BitNode *)malloc(sizeof(BitNode));

p->data = x;

p->left = p->right = NULL;

 

if(root == NULL)

{

root = p;

}

else

{

BitNode *r = root;

while(1)

{

if(r->data == x)

{

free(p);

p = NULL;

break;

}

else if(r->data > x)

{

if(r->left == NULL)

{

r->left = p;

break;

}

else

{

r = r->left;

}

}

else

{

if(r->right == NULL)

{

r->right = p;

break;

}

else

{

r = r->right;

}

}

}

}

}

return root;

}

 

void mid_order(BitNode *root)

{

if(root == NULL)

return ;

mid_order(root->left);

printf("%d\t",root->data);

mid_order(root->right);

//中序遍历

/*printf("%d\t",root->data);

mid_order(root->left);

mid_order(root->right);//先序遍历*/

 

/*mid_order(root->left);

mid_order(root->right);

printf("%d\t",root->data);后序遍历*/

 

 

 

}

int main(int argc,char *argv[])

{

BitNode *root = InitTree();

mid_order(root);

printf("\n");

return 0;

}

 

 

 

 

 

 

 

 

 

树的删点图

树的删点

#include<stdio.h>

#include<stdlib.h>

typedef int ElmentType;

typedef struct bitnode

{

ElmentType data;

struct bitnode *left;

struct bitnode *right;

}BitNode;

 

BitNode * InitTree(void)

{

BitNode * root = NULL;

BitNode *p = NULL;

ElmentType x;

while(1)

{

scanf("%d",&x);

if(x == 0)

break;

 

p = (BitNode *)malloc(sizeof(BitNode));

p->data = x;

p->left = p->right = NULL;

 

if(root == NULL)

{

root = p;

}

else

{

BitNode *r = root;

while(1)

{

if(r->data == x)

{

free(p);

p = NULL;

break;

}

else if(r->data > x)

{

if(r->left == NULL)

{

r->left = p;

break;

}

else

{

r = r->left;

}

}

else

{

if(r->right == NULL)

{

r->right = p;

break;

}

else

{

r = r->right;

}

}

}

}

}

return root;

}

 

void mid_order(BitNode *root)

{

if(root == NULL)

return ;

mid_order(root->left);

printf("%d\t",root->data);

mid_order(root->right);

}

BitNode *Delete_num(BitNode *root,ElmentType num)//树的点的删除函数,对应上面图的三 种情况。

{

BitNode *r = root;

BitNode *pre = NULL;

while(r)

{

if(r->data == num)

{

break;

}

else if(r->data < num)

{

pre = r;

r = r->right;

}

else

{

pre = r;

r = r->left;

}

}

if(r == NULL)

return root;

if(r->left == NULL && r->right == NULL)

{

if(r == root)

{

free(r);

root = r = NULL;

}

else

{

if(pre->left == r)

{

pre->left = NULL;

free(r);

r = NULL;

}

else

{

pre->right = NULL;

free(r);

r = NULL;

}

}

}

else if(r->left == NULL || r->right == NULL)

{

if(r == root)

{

if(r->left != NULL)

{

root = r->left;

r->left = NULL;

free(r);

r = NULL;

}

else

{

root = r->right;

r->right = NULL;

free(r);

r = NULL;

}

}

else

{

if(pre->left == r)

{

if(r->left != NULL)

{

pre->left = r->left;

r->left = NULL;

}

else

{

pre->left = r->right;

r->right = NULL;

}

}

else

{

if(r->left)

{

pre->right = r->left;

r->left = NULL;

}

else

{

pre->right = r->right;

r->right = NULL;

}

}

free(r);

r = NULL;

}

}

else

一:定义:

1)有且只有一个称为根的节点;

2)有若干个互不相交的子树,这些子树本身也是一颗树;

通俗一点讲,树由节点和边组成,每个节点只有一个父节点,但是可以有多个子节点,但有一个节点除外,

这个节点没有父节点,此节点称为根节点。

 

专业术语:

节点:

父节点:

子节点:

子孙节点:

堂兄弟:

深度:从根节点到最底层节点的层数(根节点为第一层,其子节点为第二层……)

叶子节点:没有子节点的节点(度为0),非0为终端节点

度:拥有的子树的个数

 

树的分类:

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

2)二叉树:子节点的个数最多两个,并且,其子树有左右之分,其次序不能任意颠倒;

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

 

二叉树又分为:

1)一般二叉树;

2)满二叉树;除了叶子节点外,每一个节点都有左右子树

3)完全二叉树:如果只删除了满二叉树最底层最右边的连续若干个节点,这样形成的二叉树就是

完全二叉树。

 

二叉树的存储形式

1)顺序存储:把一颗普通的二叉树,填补成一颗完全二叉树,然后按照从上至下,从左至右,1-n的编号进行

存储,可能会浪费一些空间。

#define MAX_TREE_SIZE 100

char tree[MAX_TREE_SIZE]

2)链式存储结构:

struct bitnode

{

int data;

struct bitnode *lchild,*rchild;

}

 

 

树的遍历:

1)先序;根->左->右

2)中序;左->根->右

3) 后序;左->右->根

 

二叉排序树

或者是一颗空树,或者是具有下列顺序的二叉树:

1)若他的左子树不为空,则左子树上面所有的节点都小于他的根节点,

2)若他的右子树不为空,则右子树上面所有的节点都大于他的根节点;

3)左右子树又分别是二叉排序树;

 

 

平衡二叉树:

它或者是一颗空树,或者是具有以下性质的树:

1)他的左子树和右子树又是一颗平衡二叉树

2) 左子树和右子树的深度之差不超过1(-1,0,1);

 

若将二叉树上的节点的平衡因子BF(Balance factor)定义为该节点的左子树减去他的右子树的深度,

则平衡二叉树的所有节点的平衡因子的绝对值不大于1,如果BF的绝对值大于1,则该二叉树就是不平衡的。

单右旋 SingleRotateWithRight(SRWR)

单左旋 SingleRotateWithLeft(SRWL)

双向先左后右旋转 DoubleRotateLeftRight(DRLR)

双向先右后左旋转 DoubleRotateRightLeft(DRRL)

 

树的创建与遍历:

#include<stdio.h>

#include<stdlib.h>

typedef int ElmentType;

typedef struct bitnode

{

ElmentType data;

struct bitnode *left;

struct bitnode *right;

}BitNode;

 

BitNode * InitTree(void)

{

BitNode * root = NULL;

BitNode *p = NULL;

ElmentType x;

while(1)

{

scanf("%d",&x);

if(x == 0)

break;

 

p = (BitNode *)malloc(sizeof(BitNode));

p->data = x;

p->left = p->right = NULL;

 

if(root == NULL)

{

root = p;

}

else

{

BitNode *r = root;

while(1)

{

if(r->data == x)

{

free(p);

p = NULL;

break;

}

else if(r->data > x)

{

if(r->left == NULL)

{

r->left = p;

break;

}

else

{

r = r->left;

}

}

else

{

if(r->right == NULL)

{

r->right = p;

break;

}

else

{

r = r->right;

}

}

}

}

}

return root;

}

 

void mid_order(BitNode *root)

{

if(root == NULL)

return ;

mid_order(root->left);

printf("%d\t",root->data);

mid_order(root->right);

//中序遍历

/*printf("%d\t",root->data);

mid_order(root->left);

mid_order(root->right);//先序遍历*/

 

/*mid_order(root->left);

mid_order(root->right);

printf("%d\t",root->data);后序遍历*/

 

 

 

}

int main(int argc,char *argv[])

{

BitNode *root = InitTree();

mid_order(root);

printf("\n");

return 0;

}

 

 

 

 

 

 

 

 

 

树的删点图

树的删点

#include<stdio.h>

#include<stdlib.h>

typedef int ElmentType;

typedef struct bitnode

{

ElmentType data;

struct bitnode *left;

struct bitnode *right;

}BitNode;

 

BitNode * InitTree(void)

{

BitNode * root = NULL;

BitNode *p = NULL;

ElmentType x;

while(1)

{

scanf("%d",&x);

if(x == 0)

break;

 

p = (BitNode *)malloc(sizeof(BitNode));

p->data = x;

p->left = p->right = NULL;

 

if(root == NULL)

{

root = p;

}

else

{

BitNode *r = root;

while(1)

{

if(r->data == x)

{

free(p);

p = NULL;

break;

}

else if(r->data > x)

{

if(r->left == NULL)

{

r->left = p;

break;

}

else

{

r = r->left;

}

}

else

{

if(r->right == NULL)

{

r->right = p;

break;

}

else

{

r = r->right;

}

}

}

}

}

return root;

}

 

void mid_order(BitNode *root)

{

if(root == NULL)

return ;

mid_order(root->left);

printf("%d\t",root->data);

mid_order(root->right);

}

BitNode *Delete_num(BitNode *root,ElmentType num)//树的点的删除函数,对应上面图的三 种情况。

{

BitNode *r = root;

BitNode *pre = NULL;

while(r)

{

if(r->data == num)

{

break;

}

else if(r->data < num)

{

pre = r;

r = r->right;

}

else

{

pre = r;

r = r->left;

}

}

if(r == NULL)

return root;

if(r->left == NULL && r->right == NULL)

{

if(r == root)

{

free(r);

root = r = NULL;

}

else

{

if(pre->left == r)

{

pre->left = NULL;

free(r);

r = NULL;

}

else

{

pre->right = NULL;

free(r);

r = NULL;

}

}

}

else if(r->left == NULL || r->right == NULL)

{

if(r == root)

{

if(r->left != NULL)

{

root = r->left;

r->left = NULL;

free(r);

r = NULL;

}

else

{

root = r->right;

r->right = NULL;

free(r);

r = NULL;

}

}

else

{

if(pre->left == r)

{

if(r->left != NULL)

{

pre->left = r->left;

r->left = NULL;

}

else

{

pre->left = r->right;

r->right = NULL;

}

}

else

{

if(r->left)

{

pre->right = r->left;

r->left = NULL;

}

else

{

pre->right = r->right;

r->right = NULL;

}

}

free(r);

r = NULL;

}

}

else

{

BitNode *p = r;

BitNode *s = p->left;

while(s->right)

{

p = s;

s = s->right;

}

r->data = s->data;

if(p != r)

{

p->right = s->left;

}

else

{

p->left = s->left;

}

s->left = NULL;

free(s);

s = NULL;

}

return root;

 

}

int main(int argc,char *argv[])

{

BitNode *root = InitTree();

mid_order(root);

printf("\n");

 

ElmentType x;

scanf("%d",&x);

root = Delete_num(root,x);

mid_order(root);

printf("\n");

 

return 0;

}

 

 

 

 

 

树的层次输出

//打印结果如上图

#include<stdio.h>

#include<stdlib.h>

typedef struct bitnode

{

int data;

struct bitnode *left;

struct bitnode *right;

}BITNODE;

typedef struct node

{

BITNODE *jiedian;

struct node *next;

}NODE;

typedef struct list

{

NODE *first;

NODE *last;

int count;

}LIST;

LIST *chuangjian()

{

LIST *l=(LIST *)malloc(sizeof(LIST));

l->first=NULL;

l->last=NULL;

l->count=0;

return l;

}

BITNODE *jianshu()

{

BITNODE *root=NULL;

BITNODE *p=NULL;

int x;

while(1)

{

scanf("%d",&x);

if(x==0)

break;

p=(BITNODE *)malloc(sizeof(BITNODE));

p->data=x;

p->left=p->right=NULL;

if(root==NULL)

{

root=p;

}

else

{

BITNODE *r=root;

while(1)

{

if(r->data==x)

{

free(p);

p=NULL;

break;

}

else if(r->data>x)

{

if(r->left==NULL)

{

r->left=p;

break;

}

else

{

r=r->left;

 

}

 

}

else

{

if(r->right==NULL)

{

 

r->right=p;

break;

}

else

{

r=r->right;

}

 

}

 

 

 

}

 

}

 

}

return root;

}

void rudui(LIST *l,BITNODE *jd)

{

if(l==NULL)

return ;

NODE *p=(NODE *)malloc(sizeof(NODE));

p->jiedian=jd;

p->next=NULL;

if(l->first==NULL)

{

l->first=l->last=p;

}

else

{

l->last->next=p;

l->last=p;

}

l->count++;

}

NODE *chudui(LIST *l)

{

if(l==NULL)

return NULL;

NODE *p=l->first;

if(l->first==l->last)

{

l->first=l->last=NULL;

 

}

else

{

l->first=l->first->next;

p->next=NULL;

}

l->count--;

return p;

}

void chengcishu(LIST *l,BITNODE *root)

{

int x,k=1;

BITNODE *r=NULL;

rudui(l,root);

while(l->count>0)

{

NODE *p=chudui(l);

if(x==p->jiedian->data)

{

printf("\n");

k=1;

}

printf("%d",p->jiedian->data);

if(p->jiedian->left!=NULL)

{

r=p->jiedian->left;

if(k>0)

{

x=r->data;

k=0;

 

}

rudui(l,r);

}

if(p->jiedian->right!=NULL)

{

r=p->jiedian->right;

if(k>0)

{

x=r->data;

k=0;

 

}

rudui(l,r);

}

}

}

 

int main ()

{

LIST *l=chuangjian();

BITNODE *root=jianshu();

chengcishu(l,root);

printf("\n");

return 0;

}

树的单项右旋

树的单项左旋

树的双向先右后左旋:

树的双向先左后又旋:

{

BitNode *p = r;

BitNode *s = p->left;

while(s->right)

{

p = s;

s = s->right;

}

r->data = s->data;

if(p != r)

{

p->right = s->left;

}

else

{

p->left = s->left;

}

s->left = NULL;

free(s);

s = NULL;

}

return root;

 

}

int main(int argc,char *argv[])

{

BitNode *root = InitTree();

mid_order(root);

printf("\n");

 

ElmentType x;

scanf("%d",&x);

root = Delete_num(root,x);

mid_order(root);

printf("\n");

 

return 0;

}

 

 

 

 

 

树的层次输出

//打印结果如上图

#include<stdio.h>

#include<stdlib.h>

typedef struct bitnode

{

int data;

struct bitnode *left;

struct bitnode *right;

}BITNODE;

typedef struct node

{

BITNODE *jiedian;

struct node *next;

}NODE;

typedef struct list

{

NODE *first;

NODE *last;

int count;

}LIST;

LIST *chuangjian()

{

LIST *l=(LIST *)malloc(sizeof(LIST));

l->first=NULL;

l->last=NULL;

l->count=0;

return l;

}

BITNODE *jianshu()

{

BITNODE *root=NULL;

BITNODE *p=NULL;

int x;

while(1)

{

scanf("%d",&x);

if(x==0)

break;

p=(BITNODE *)malloc(sizeof(BITNODE));

p->data=x;

p->left=p->right=NULL;

if(root==NULL)

{

root=p;

}

else

{

BITNODE *r=root;

while(1)

{

if(r->data==x)

{

free(p);

p=NULL;

break;

}

else if(r->data>x)

{

if(r->left==NULL)

{

r->left=p;

break;

}

else

{

r=r->left;

 

}

 

}

else

{

if(r->right==NULL)

{

 

r->right=p;

break;

}

else

{

r=r->right;

}

 

}

 

 

 

}

 

}

 

}

return root;

}

void rudui(LIST *l,BITNODE *jd)

{

if(l==NULL)

return ;

NODE *p=(NODE *)malloc(sizeof(NODE));

p->jiedian=jd;

p->next=NULL;

if(l->first==NULL)

{

l->first=l->last=p;

}

else

{

l->last->next=p;

l->last=p;

}

l->count++;

}

NODE *chudui(LIST *l)

{

if(l==NULL)

return NULL;

NODE *p=l->first;

if(l->first==l->last)

{

l->first=l->last=NULL;

 

}

else

{

l->first=l->first->next;

p->next=NULL;

}

l->count--;

return p;

}

void chengcishu(LIST *l,BITNODE *root)

{

int x,k=1;

BITNODE *r=NULL;

rudui(l,root);

while(l->count>0)

{

NODE *p=chudui(l);

if(x==p->jiedian->data)

{

printf("\n");

k=1;

}

printf("%d",p->jiedian->data);

if(p->jiedian->left!=NULL)

{

r=p->jiedian->left;

if(k>0)

{

x=r->data;

k=0;

 

}

rudui(l,r);

}

if(p->jiedian->right!=NULL)

{

r=p->jiedian->right;

if(k>0)

{

x=r->data;

k=0;

 

}

rudui(l,r);

}

}

}

 

int main ()

{

LIST *l=chuangjian();

BITNODE *root=jianshu();

chengcishu(l,root);

printf("\n");

return 0;

}

树的单项右旋

树的单项左旋

树的双向先右后左旋:

树的双向先左后又旋:

猜你喜欢

转载自blog.csdn.net/weixin_41723504/article/details/81587411