G
N
I
D
A
O
L

【数据结构-树】二叉树的基本操作

1 链式存储的二叉树

1.1 定义

typedef struct BiTNode{
    int data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
} *BiTNode, BiTree;

1.2 先序遍历

void PreOrder (BiTree T){
    if (T != NULL){
        访问 T 结点;
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}

1.3 中序遍历

void InOrder (BiTree T){
    if (T != NULL){
        InOrder(T->lchild);
        访问 T 结点;
        InOrder(T->rchild);
    }
}

1.4 后序遍历

void PostOrder (BiTree T){
    if (T != NULL){
        PostOrder(T->lchild);
        PostOrder(T->rchild);
        访问 T 结点;
    }
}

1.5 层次遍历

void LevelOrder (BiTree T){
    Queue Q; // 辅助队列
    BiTree *TNode;
    
    InitQueue(Q);
    EnQueue(Q, T); // 根节点入队
    
    while (!Empty(Q)){
        DeQueue(Q, TNode); // 队头结点出队
        访问 TNode 结点;
        if (TNode->lchild != NULL)
            EnQueue(Q, TNode->lchild); // 左孩子入队
        if (TNode->rchild != NULL)
            EnQueue(Q, TNode->rchild); // 右孩子入队
    }
}

1.6 二叉树的高度

int TreeDepth (BiTree T){
    if (T == NULL)
        return 0;
    
    int lchild = TreeDepth(T->lchild);
    int rchild = TreeDepth(T->rchild);
    return max(lchild, rchild) + 1;
}

1.7 二叉树的宽度

int maxWidth = -1;
int count[MAX_NUM] = {0}; // 记录每层的结点数

// i:二叉树的第几层
void TreeWidth (BiTree T, int i){
    if (T == NULL)
        return 0;
    
    count[i]++;
    maxWidth = max(count[i], maxWidth);
    TreeWidth(T->lchild, i + 1);
    TreeWidth(T->rchild, i + 1);
}

1.8 统计度为 1 的结点个数

int count = 0;

void Degree1 (BiTree T){
    if (T != NULL){
        Degree1(T->lchild);
        Degree1(T->rchild);
        if (((T->lchild == NULL) && (T->rchild != NULL)) || ((T->lchild != NULL) && (T->rchild == NULL)))
            count++;   
    }
} 

1.9 统计度为 2 的结点个数

int count = 0;

void Degree2 (BiTree T){
    if (T != NULL){
        Degree2(T->lchild);
        Degree2(T->rchild);
        if ((T->lchild != NULL) && (T->rchild != NULL))
            count++;   
    }
} 

1.10 统计度为 0 的结点个数

int count = 0;

void Degree0 (BiTree T){
    if (T != NULL){
        Degree0(T->lchild);
        Degree0(T->rchild);
        if ((T->lchild == NULL) && (T->rchild == NULL))
            count++;   
    }
} 

1.11 计算指定结点 *p 所在层次

int GetLevel (BiTree T, BiTNode *p){
	if (T == NULL) // 如果根节点为空,则所在层次为 0
		return 0;
	if (T == p) // 如果根节点即为 p,则所在层次为 1
		return 1;	
		
	int depl = GetLevel(T->lchild, p); // 获取结点 p 在左子树中的高度
	int depr = GetLevel(T->rchild, p); // 获取结点 p 在右子树中的高度
	if (depl || depr) // 若 depl 和 depr 中有一个不为 0,则取其中的最大值 + 1 即为 p 所在层次
	{
		if (depl > depr)
			return 1 + depl;
		else
			return 1 + depr;
	}
	return 0;
}

1.12 删去所有叶结点

void DelLeafNode (BiTree T){
    BiTNode *p = T;
    if (((p->lchild == NULL) && (p->rchild == NULL)) || (p == NULL)){ // 只有根结点或空树
        return;
    }
    else if ((p->lchild->lchild == NULL) && (p->lchild->rchild == NULL)){
        free(p->lchild);
        p->lchild = NULL;
    }
    else if ((p->rchild->lchild == NULL) && (p->rchild->rchild == NULL)){
        free(p->rchild);
        p->rchild = NULL;
    }
    DelLeafNode(p->lchild);
    DelLeafNode(p->rchild);
}

1.13 交换每个结点的两个子女

void SwapNodeChild (BiTree T){
    if (T->lchild != NULL)
        SwapNodeChild(T->lchild);
    if (T->rchild != NULL)
        SwapNodeChild(T->rchild);

    Swap(T->lchild, T->rchild);
}

1.14 计算各结点中最大元素的值

int GetMaxNode (BiTree T){
    if (T == NULL) // 如果根结点为空,则最大元素之为 0
        return 0;

    int maxl = GetMaxNode(T->lchild); // 获取根结点左子树的最大元素值
    int maxr = GetMaxNode(T->rchild); // 获取根结点右子树的最大元素值

    int maxlr = (maxl > maxr) ? (maxl) : (maxr);  // 取左、右子树最大元素值中的最大值
    int maxNode = (maxlr > T->data) ? (maxlr) : (T->data); // 取左、右子树最大元素值中的最大值与根结点中的最大值
    
    return maxNode;
}

1.15 以先序次序输出所有结点的数据值及结点所在的层次

void PrintByPreOrder (BiTree T, int level){
    if(T != NULL){
        输出 level 和 T->data;
        PrintByPreOrder(T->lchild, level + 1);
        PrintByPreOrder(T->rchild, level + 1);
    }
}

2 顺序存储的二叉树

2.1 树的结点从数组下标 1 开始存储

2.1.1 定义

#define MAX 50

typedef struct{
    int data;
    bool empty; // 记录结点是否为空
} TreeNode;

TreeNode T[MAX+1];
  • 初始化:
void InitTree (TreeNode &T){
    int i;
    for (i = 1; i <= MAX+1; i++)
        T[i].empty = true;
}

2.1.2 先序遍历

void PreOrder (TreeNode &T, int i){
    if (!T[i].empty){
        访问 T[i].data;
        
        if (2*i <= MAX)
            PreOrder(T, 2*i);
            
        if (2*i+1 <= MAX)
            PreOrder(T, 2*i+1);
    }
}

2.1.3 中序遍历

void InOrder (TreeNode &T, int i){
    if (!T[i].empty){
        if (2*i <= MAX)
            InOrder(T, 2*i);
            
        访问 T[i].data;
        
        if (2*i+1 <= MAX)
            InOrder(T, 2*i+1);
    }
}

2.1.4 后序遍历

void PostOrder (TreeNode &T, int i){
    if (!T[i].empty){
        if (2*i <= MAX)
            PostOrder(T, 2*i);
            
        if (2*i+1 <= MAX)
            PostOrder(T, 2*i+1);
            
        访问 T[i].data;
    }
}

2.1.5 层次遍历

void LevelOrder (TreeNode &T){
    int i;
    for (i = 1; i <= MAX; i++){
        if (!T[i].empty)
            访问 T[i].data;
    }
}

2.1.6 结点 i 的父结点

int FindFather (int i){
    return i / 2;
}

2.1.7 结点 i 的左孩子

int FindLeftChild (int i){
    return 2 * i;
}

2.1.8 结点 i 的右孩子

int FindRightChild (int i){
    return 2 * i + 1;
}

2.1.9 结点 i 的层数

int FindFloor (int i){
    return log(2, i) + 1; // log 以 2 为底的对数函数
}

2.2 树的结点从数组下标 0 开始存储

2.2.1 定义

#define MAX 50

typedef struct{
    int data;
    bool empty; // 记录结点是否为空
} TreeNode;

TreeNode T[MAX];
  • 初始化:
void InitTree (TreeNode &T){
    int i;
    for (i = 0; i < MAX; i++)
        T[i].empty = true;
}

2.2.2 先序遍历

void PreOrder (TreeNode &T, int i){
    if (!T[i].empty){
        访问 T[i].data;
        
        if (2*i+1 < MAX)
            PreOrder(T, 2*i+1);
            
        if (2*i+2 < MAX)
            PreOrder(T, 2*i+2);
    }
}

2.2.3 中序遍历

void InOrder (TreeNode &T, int i){
    if (!T[i].empty){
        if (2*i+1 < MAX)
            InOrder(T, 2*i+1);
            
        访问 T[i].data;
        
        if (2*i+2 < MAX)
            InOrder(T, 2*i+2);
    }
}

2.2.4 后序遍历

void PostOrder (TreeNode &T, int i){
    if (!T[i].empty){
        if (2*i+1 < MAX)
            PostOrder(T, 2*i+1);
            
        if (2*i+2 < MAX)
            PostOrder(T, 2*i+2);
            
        访问 T[i].data;
    }
}

2.2.5 层次遍历

void LevelOrder (TreeNode &T){
    int i;
    for (i = 0; i < MAX; i++){
        if (!T[i].empty)
            访问 T[i].data;
    }
}

2.2.6 结点 i 的父结点

int FindFather (int i){
    return (i - 1) / 2;
}

2.2.7 结点 i 的左孩子

int FindLeftChild (int i){
    return 2 * i + 1;
}

2.2.8 结点 i 的右孩子

int FindRightChild (int i){
    return 2 * i + 2;
}

2.2.9 结点 i 的层数

int FindFloor (int i){
    return log(2, i-1) + 1; // log 以 2 为底的对数函数
}
posted @ 2022-10-27 22:26  漫舞八月(Mount256)  阅读(61)  评论(0编辑  收藏  举报