一:定义:
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;
}
树的单项右旋
树的单项左旋
树的双向先右后左旋:
树的双向先左后又旋: