树
一、相关概念
根节点:A
叶节点:D、E、F、G、H、I
非终端节点:B、C、D
- 分支度:每个节点所拥有的子节点个数。
- 阶层:节点特性,将根节点之阶层设为1,其子节点为2,以此类推。
- 高度或者深度:一棵树中的最大阶层值。
- 祖先:由某节点到根节点路径上的所有节点。
- 树林: n n n ≥ \geq ≥ 0 0 0个树的集合称为树林,若将一树的根节点移去,所剩这恰是一树林,如图
二叉树
(1)种类
- 左歪斜树
- 右歪斜树
- 满二叉树
- 完全二叉树:若除掉最大阶层后为满二叉树且最大阶层均向左靠齐
(2)性质
- 在二叉树的第 i i i层上最多有 2 i − 1 2^{i-1} 2i−1个节点
- 深度为 k k k 的二叉树最多有 2 k − 1 2^{k-1} 2k−1个节点
- 二叉树终端节点个数为 n 0 n_{0} n0,度数为2的节点个数为 n 2 n_{2} n2,则 n 0 n_{0} n0 = = = n 2 n_{2} n2 + 1 +1 +1
树的遍历
- 前序:根左右
- 中序:左根右
- 后序:左右根
广义表生成树原理
例:
50
(
25
(
10
,
)
,
75
(
63
(
,
67
)
,
)
)
50(25(10,),75(63(,67),))
50(25(10,),75(63(,67),))
原则
- f l a g = flag= flag=左/右(记录当前应该插入左节点还是右节点)
- 遇到数字就建立节点n,如果栈非空将插入栈顶节点的flag边
- 遇到 ( ( ( 压栈 f l a g = flag= flag=左
- 遇到 , , , f l a g = flag= flag=右
- 遇到 ) ) ) 出栈
二、代码实现
插入
和根比较,比根大则插入左子树,否则插入右子树。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int val;
struct Node *left;
struct Node *right;
}Node;
typedef struct Tree{
Node *root;
int len;
}Tree;
Node *initNode(int val){
Node *n = (Node *)malloc(sizeof(Node));
n->val = val;
n->left = NULL;
n->right = NULL;
return n;
}
void freeNode(Node *n){
if(!n){
return ;
}
free(n);
return ;
}
Tree *initTree(){
Tree *t = (Tree*)malloc(sizeof(Tree));
t->root = NULL;
t->len = 0;
return t;
}
//插入
Node *insert(Node *root, int val){
if(!root){
Node *n = initNode(val);
return n;
}
if(val > root->val)
root->right = insert(root->right,val);
else
root->left = insert(root->left,val);
return root;
}
void *insertTree(Tree *t,int val){
if(!t)
return t;
t->root = insert(t->root,val);
t->len++;
}
//前序遍历
void preorderTrav(Node *root){
if(!root)
return ;
printf("%d,",root->val);
preorderTrav(root->left);
preorderTrav(root->right);
return ;
}
//中序
void inorderTrav(Node *root){
if(!root)
return ;
inorderTrav(root->left);
printf("%d",root->val);
inorderTrav(root->right);
return ;
}
//后序
void lateorderTrav(Node *root){
if(!root)
return ;
lateorderTrav(root->left);
lateorderTrav(root->right);
printf("%d",root->val);
return ;
}
void preorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
preorderTrav(t->root);
printf("}\n");
}
void inorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
inorderTrav(t->root);
printf("}\n");
}
void lateorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
lateorderTrav(t->root);
printf("}\n");
}
//释放
void freeAll(Node *root){
if(!root)
return ;
freeAll(root->left);
freeAll(root->right);
freeNode(root);
return ;
}
void freeTree(Tree *t){
if(!t)
return ;
freeAll(t->root);
free(t);
}
int main(){
return 0;
}
指针
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Node{
int val;
struct Node *left;
struct Node *right;
}Node;
typedef struct Tree{
Node *root;
int len;
}Tree;
//初始化
Node *initNode(int val){
Node *n = (Node *)malloc(sizeof(Node));
n->val = val;
n->left = NULL;
n->right = NULL;
return n;
}
Tree *initTree(){
Tree *t = (Tree*)malloc(sizeof(Tree));
t->root = NULL;
t->len = 0;
return t;
}
//释放
void freeNode(Node *n){
if(!n){
return ;
}
free(n);
return ;
}
//插入
void insert(Node **radd, int val){//改为void
if(!(*radd)){
*radd = initNode(val);
return ;
}
if(val > (*radd)->val)
insert(&((*radd)->right),val);
else
insert(&((*radd)->left),val);
}
void *insertTree(Tree *t,int val){
if(!t)
return t;
insert(&(t->root),val);
t->len++;
}
//前序遍历
void preorderTrav(Node *root){
if(!root)
return ;
printf("%d,",root->val);
preorderTrav(root->left);
preorderTrav(root->right);
return ;
}
//中序
void inorderTrav(Node *root){
if(!root)
return ;
inorderTrav(root->left);
printf("%d,",root->val);
inorderTrav(root->right);
return ;
}
//后序
void lateorderTrav(Node *root){
if(!root)
return ;
lateorderTrav(root->left);
lateorderTrav(root->right);
printf("%d,",root->val);
return ;
}
//输出封装
void preorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
preorderTrav(t->root);
printf("}\n");
}
void inorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
inorderTrav(t->root);
printf("}\n");
}
void lateorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
lateorderTrav(t->root);
printf("}\n");
}
//释放
void freeAll(Node *root){
if(!root)
return ;
freeAll(root->left);
freeAll(root->right);
freeNode(root);
return ;
}
void freeTree(Tree *t){
if(!t)
return ;
freeAll(t->root);
free(t);
}
int main(){
Tree *t = initTree();
srand(time(0));
int cnt = 20;
while(cnt--){
int val = rand() % 100;
insertTree(t,val);
}
preorderTree(t);
inorderTree(t);
lateorderTree(t);
return 0;
}
增加查找
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Node{
int val;
struct Node *left;
struct Node *right;
}Node;
typedef struct Tree{
Node *root;
int len;
}Tree;
//初始化
Node *initNode(int val){
Node *n = (Node *)malloc(sizeof(Node));
n->val = val;
n->left = NULL;
n->right = NULL;
return n;
}
Tree *initTree(){
Tree *t = (Tree*)malloc(sizeof(Tree));
t->root = NULL;
t->len = 0;
return t;
}
//释放
void freeNode(Node *n){
if(!n){
return ;
}
free(n);
return ;
}
//插入
void insert(Node **radd, int val){//改为void
if(!(*radd)){
*radd = initNode(val);
return ;
}
if(val > (*radd)->val)
insert(&((*radd)->right),val);
else
insert(&((*radd)->left),val);
}
void *insertTree(Tree *t,int val){
if(!t)
return t;
insert(&(t->root),val);
t->len++;
}
//前序遍历
void preorderTrav(Node *root){
if(!root)
return ;
printf("%d,",root->val);
preorderTrav(root->left);
preorderTrav(root->right);
return ;
}
//中序
void inorderTrav(Node *root){
if(!root)
return ;
inorderTrav(root->left);
printf("%d,",root->val);
inorderTrav(root->right);
return ;
}
//后序
void lateorderTrav(Node *root){
if(!root)
return ;
lateorderTrav(root->left);
lateorderTrav(root->right);
printf("%d,",root->val);
return ;
}
//输出封装
void preorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
preorderTrav(t->root);
printf("}\n");
}
void inorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
inorderTrav(t->root);
printf("}\n");
}
void lateorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
lateorderTrav(t->root);
printf("}\n");
}
//广义表
void outputTab(Node *n){
if(!n)
return ;
printf("%d",n->val);
if(!n->left && !n->right){
return ;
}
printf("(");
outputTab(n->left);
printf(",");
outputTab(n->right);
printf(")");
}
void outputTree(Tree *t){
if(!t)
return ;
printf("Table:[");
outputTab(t->root);
printf("]\n");
}
//释放
void freeAll(Node *root){
if(!root)
return ;
freeAll(root->left);
freeAll(root->right);
freeNode(root);
return ;
}
void freeTree(Tree *t){
if(!t)
return ;
freeAll(t->root);
free(t);
}
//查找
Node *findNode(Node *root, int val){
if(!root){
return NULL;
}
if(val==root->val){
return root;
}
if(val>root->val)
return findNode(root->right,val);
else
return findNode(root->left,val);
}
Node *findTree(Tree *t,int val){
if(!t)
return NULL;
return findNode(t->root,val);
}
int main(){
Tree *t = initTree();
srand(time(0));
int cnt = 10,want = 0;
while(cnt--){
int val = rand() % 100;
insertTree(t,val);
if(cnt==5)
want = val;
}
preorderTree(t);
inorderTree(t);
lateorderTree(t);
outputTree(t);
Node *find=findTree(t,want);
find?printf("find %d at %#x,val %d\n",want,find,find->val):printf("fail");
return 0;
}
广义表生成树
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct Node{
int val;
struct Node *left;
struct Node *right;
}Node;
typedef struct Tree{
Node *root;
int len;
}Tree;
//初始化
Node *initNode(int val){
Node *n = (Node *)malloc(sizeof(Node));
n->val = val;
n->left = NULL;
n->right = NULL;
return n;
}
Tree *initTree(){
Tree *t = (Tree*)malloc(sizeof(Tree));
t->root = NULL;
t->len = 0;
return t;
}
//释放
void freeNode(Node *n){
if(!n){
return ;
}
free(n);
return ;
}
//插入
void insert(Node **radd, int val){//改为void
if(!(*radd)){
*radd = initNode(val);
return ;
}
if(val > (*radd)->val)
insert(&((*radd)->right),val);
else
insert(&((*radd)->left),val);
}
void *insertTree(Tree *t,int val){
if(!t)
return t;
insert(&(t->root),val);
t->len++;
}
//前序遍历
void preorderTrav(Node *root){
if(!root)
return ;
printf("%d,",root->val);
preorderTrav(root->left);
preorderTrav(root->right);
return ;
}
//中序
void inorderTrav(Node *root){
if(!root)
return ;
inorderTrav(root->left);
printf("%d,",root->val);
inorderTrav(root->right);
return ;
}
//后序
void lateorderTrav(Node *root){
if(!root)
return ;
lateorderTrav(root->left);
lateorderTrav(root->right);
printf("%d,",root->val);
return ;
}
//输出封装
void preorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
preorderTrav(t->root);
printf("}\n");
}
void inorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
inorderTrav(t->root);
printf("}\n");
}
void lateorderTree(Tree *t){
if(!t)
return ;
printf("Pre:[");
lateorderTrav(t->root);
printf("]\n");
}
//广义表
void outputTab(Node *n){
if(!n)
return ;
printf("%d",n->val);
if(!n->left && !n->right){
return ;
}
printf("(");
outputTab(n->left);
printf(",");
outputTab(n->right);
printf(")");
}
void outputTree(Tree *t){
if(!t)
return ;
printf("Table:[");
outputTab(t->root);
printf("]\n");
}
//释放
void freeAll(Node *root){
if(!root)
return ;
freeAll(root->left);
freeAll(root->right);
freeNode(root);
return ;
}
void freeTree(Tree *t){
if(!t)
return ;
freeAll(t->root);
free(t);
}
//查找
Node *findNode(Node *root, int val){
if(!root){
return NULL;
}
if(val==root->val){
return root;
}
if(val>root->val)
return findNode(root->right,val);
else
return findNode(root->left,val);
}
Node *findTree(Tree *t,int val){
if(!t)
return NULL;
return findNode(t->root,val);
}
//实现栈 数据元素类型Node*
typedef struct Stack{
Node **data;//指针数组的地址
int size;
int top;
}Stack;
Stack *initStack(int n){
Stack *s = (Stack*)malloc(sizeof(Stack));
s->data = (Node**)malloc(sizeof(Node*)*n);
s->top = -1;
s->size= n;
return s;
}
void freeStack(Stack *s){
if(!s)
return ;
free(s->data);
free(s);
return ;
}
int push(Stack *s,Node *n){
if(!s)
return 0;
if(s->top==s->size-1)
return 0;
s->data[++s->top] = n;
return 1;
}
int isEmpty(Stack *s){
return !(s && s->top!=-1);
}
Node *pop(Stack *s){
return s->data[s->top--];
}
Node *buildTree(char *str){
Stack *s = initStack(strlen(str)/2);
Node *root,*n;
int flag = 0,num;
while(str[0]){
switch(str[0]){
case '(':
push(s,n);
flag = 0;
break;
case ',':
flag = 1;
break;
case ')':
root = pop(s);
break;
default:
if(str[0]<'0' || str[0]>'9')
break;
//str转为 数字
num = 0;
while(str[0]>='0' && str[0]<='9'){
num = num*10 + str[0] - '0';
str++;
}
str--;
n= initNode(num);
if(!isEmpty(s))
flag?(s->data[s->top]->right = n):(s->data[s->top]->left = n);
}
str++;
}
freeStack(s);
return root;
}
int main(){
Tree *t = initTree();
char str[100];
scanf("%s",str);
t->root = buildTree(str);
preorderTree(t);
outputTree(t);
freeTree(t);
return 0;
}
线索数
//线索树
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define CHILD 0
#define THEAD 1
typedef struct Node{
int val;
struct Node *left;
struct Node *right;
int ltag,rtag; //左标记,右标记;
}Node;
Node *initNode(int val){
Node *n = (Node*)malloc(sizeof(Node));
n->val = val;
n->left = NULL;
n->right = NULL;
n->ltag = CHILD;
n->rtag = CHILD;
return n;
}
void freeNode(Node *p){
if(!p)
return ;
free(p);
return ;
}
void insert(Node **radd, int val){//改为void
if(!(*radd)){
*radd = initNode(val);
return ;
}
if(val > (*radd)->val)
insert(&((*radd)->right),val);
else
insert(&((*radd)->left),val);
}
void freeAll(Node *n){
if(!n)
return ;
if(n->left == CHILD)
freeAll(n->left);
if(n->right == CHILD)
freeAll(n->right);
freeNode(n);
return ;
}
void inorderTrav(Node *root){
if(!root)
return ;
inorderTrav(root->left);
printf("%d ",root->val);
inorderTrav(root->right);
return ;
}
Node *pre = NULL;
void buildThread(Node *root){
if(!root)
return ;
//先构建左子树的线索
buildThread(root->left);
//再构建根的线索
//如果当前左指针为空,让左指针指向前驱
if(!root->left){
root->left = pre;
root->ltag = THEAD;
}
if(pre && !pre->right){
pre->right= root;
pre->rtag = THEAD;
}
pre = root;
//最后构建右子树的线索
buildThread(root->right);
return ;
}
//找到最左边节点
Node *getLeftMost(Node *p){
while(p && p->ltag == CHILD && p->left)
p = p->left;
return p;
}
void output(Node *root){
if(!root)
return ;
Node *p = getLeftMost(root);
while(p){
printf("%d ",p->val);
if(p->rtag == CHILD)
p = getLeftMost(p->right);
else
p = p->right;
}
return ;
}
int main(){
srand(time(0));
Node *root = NULL;
int cnt = 10;
while(cnt--){
int val = rand() %100;
insert(&root,val);
}
inorderTrav(root);
printf("\n");
buildThread(root);
output(root);
putchar(10);
freeAll(root);
return 0;
}