本文代码基于【数据结构】【严蔚敏】【清华大学】
包含了大多数二叉树的基本操做ios
1.准备部分的代码:
用c++其实就是用了个max()函数c++
#include <stdio.h> #include <stdlib.h>//malloc和exit函数所需头文件 #include <iostream> using namespace std; #define MaxSize 100 typedef char ElemType;
固然也能够改为C,记得加上一个自定义max函数web
#include <stdio.h> #include <stdlib.h>//malloc和exit函数所需头文件 #define MaxSize 100 typedef char ElemType;
int max(int a,int b) { return a>b?a:b; }
2.构造二叉树结点
包括数据域和左右孩子指针算法
typedef struct BiTNode { ElemType data; struct BiTNode *lchild, *rchild; // 左右孩子指针 } BiTNode, *BiTree;
3.先序输入二叉树中结点的值
一些必要的注解:
①TheBinaryTree为结构体指针,指向结构体
BiTree TheBinaryTree=BiTNode *TheBinaryTree
②T为TheBinaryTree的引用,是结构体指针
BiTree &T= BiTNode *&T
③BT是结构指针TheBinaryTree的指针,BT指向结构体指针
BiTNode **BT=BiTree *BT
全部有两种 CreateBiTree写法:数据结构
void CreateBiTree(BiTNode* &T)//BiTree &T== BiTNode* &T { // 按先序次序输入二叉树中结点的值 // 构造二叉链表表示的二叉树T。 ElemType ch; static int i = 0; char pch[] = "ABC$$DE$G$$F$$$"; // 欲产生的 先序序列。图6.8(b) ch = pch[i++]; if(ch == '$') // 空树 T = NULL; else { T = (BiTree)malloc(sizeof(BiTNode)); if(!T) // 检测是否申请结点成功 exit(-1); T->data = ch; // 生成根结点 CreateBiTree(T->lchild); // 构造左子树 CreateBiTree(T->rchild); // 构造右子树 } }
void CreateBiTree_Pointer(BiTNode **BT)//BiTree *BT BT此时为指针的指针, BiTNode* *BT==BiTree *BT { // 按先序次序输入二叉树中结点的值 // 构造二叉链表表示的二叉树BT。 ElemType ch; static int i = 0; char pch[] = "AB D C "; // 欲产生的二叉树 先序序列 ch = pch[i++]; //scanf("%c",&ch); if(ch == ' ') // 空树 *BT = NULL; else { *BT = (BiTree)malloc(sizeof(BiTNode)); if(!*BT) // 检测是否申请结点成功 exit(-1); (*BT)->data = ch; // 生成根结点 CreateBiTree_Pointer(&(*BT)->lchild); // 构造左子树 CreateBiTree_Pointer(&(*BT)->rchild); // 构造右子树 } }
4.三种遍历(递归)svg
// 中序遍历 void InOrderTraversal(BiTree BT) { if(BT) { InOrderTraversal(BT->lchild); printf("%c ", BT->data); InOrderTraversal(BT->rchild); } } //先序遍历 void PreOrderTraversal(BiTree BT) { if(BT) { printf("%c ", BT->data); PreOrderTraversal(BT->lchild); PreOrderTraversal(BT->rchild); } } // 后序遍历 void PostOrderTraversal(BiTree BT) { if(BT) { PostOrderTraversal(BT->lchild); PostOrderTraversal(BT->rchild); printf("%c ", BT->data); } }
5.中序遍历非递归遍历算法(关于其余遍历算法以后还会写文章提到)函数
// 中序遍历非递归遍历算法 //利用压栈 void InOrderTraversal_NoRecursion(BiTNode *T) { BiTNode *Stack[MaxSize];//BiTree Stack[MaxSize] int top = -1; while(T || (top != -1)) { while(T) { // 一直向左并将沿途结点压入堆栈 Stack[++top] = T; T = T->lchild; } if(top != -1) { T = Stack[top--]; // 结点弹出堆栈 printf("%c ", T->data); //(访问)打印结点 T = T->rchild; // 转向右子树 } } }
6.输出叶子结点值spa
// 输出二叉树中的叶子结点。 void PreOrderPrintLeaves(BiTree BT) { if(BT) { if(BT->lchild == NULL && BT->rchild == NULL) printf("%c ", BT->data); PreOrderPrintLeaves(BT->lchild); PreOrderPrintLeaves(BT->rchild); } }
7.输出深度指针
// 求二叉树的深度 int Binary_tree_Deepness(BiTNode *T) { if(T == NULL) return 0; else if(T->lchild == NULL && T->rchild == NULL) return 1; else return 1 + max(Binary_tree_Deepness(T->lchild), Binary_tree_Deepness(T->rchild)); } //表示形式2 int Binary_tree_Deepness_Post(BiTNode *T) { int h1, h2; if(T == NULL) return 0; h1 = Binary_tree_Deepness_Post(T->lchild); h2 = Binary_tree_Deepness_Post(T->rchild); if(T->lchild == NULL && T->rchild == NULL) return 1; else return 1 + max(h1, h2); }
8.求度为 2 的结点数code
//求二叉树的度为 2 的结点数算法 int BT_CountDegree2(BiTNode *T) { int n1, n2; if (T == NULL) return 0; else { n1 = BT_CountDegree2(T->lchild); n2 = BT_CountDegree2(T->rchild); if (T->lchild != NULL && T->rchild != NULL) return 1 + n1 + n2; else return n1 + n2; } }
9.构造和销毁
PS:完整代码中没用到构造和销毁,Init某种意义上无关紧要,destroy最好仍是加一下
Status InitBiTree(BiTree &T) { // 操做结果: 构造空二叉树T T = NULL; return OK; } void DestroyBiTree(BiTree &T) { // 初始条件: 二叉树T存在。操做结果: 销毁二叉树T if(T) { // 非空树 if(T->lchild) // 有左孩子 DestroyBiTree(T->lchild); // 销毁左孩子子树 if(T->rchild) // 有右孩子 DestroyBiTree(T->rchild); // 销毁右孩子子树 free(T); // 释放根结点 T = NULL; // 空指针赋0 } }
10.主函数
int main() { BiTree TheBinaryTree;//BiTNode *TheBinaryTree printf("\n创建二叉树,请输入结点值系列:\n"); CreateBiTree(TheBinaryTree);//TheBinaryTree为结构体指针 printf("\n先序遍历序列:\n"); PreOrderTraversal(TheBinaryTree); printf("\n中序遍历序列:\n"); InOrderTraversal(TheBinaryTree); printf("\n中序遍历序列 - 中序遍历非递归算法:\n"); InOrderTraversal_NoRecursion(TheBinaryTree); printf("\n后序遍历序列:\n"); PostOrderTraversal(TheBinaryTree); printf("\n二叉树的深度为:\n"); //printf("%d",Binary_tree_Deepness_Post(TheBinaryTree)); printf("%d", Binary_tree_Deepness(TheBinaryTree)); printf("\n叶子结点为:\n"); PreOrderPrintLeaves(TheBinaryTree); printf("\n度为2的结点个数为:\n"); printf("%d", BT_CountDegree2(TheBinaryTree)); return 1; }
便于复制完整源代码以下:
#include <stdio.h> #include <stdlib.h> #include <iostream> using namespace std; #define MaxSize 100 typedef char ElemType; typedef struct BiTNode { ElemType data; struct BiTNode *lchild, *rchild; // 左右孩子指针 } BiTNode, *BiTree; //TheBinaryTree为结构体指针,指向结构体 //BiTree TheBinaryTree==BiTNode *TheBinaryTree //BiTree &T== BiTNode* &T T为TheBinaryTree的引用,是结构体指针 //BiTNode **BT==BiTree *BT BT是结构指针TheBinaryTree的指针, BT指向结构体指针 void CreateBiTree(BiTNode* &T)//BiTree &T== BiTNode* &T { // 按先序次序输入二叉树中结点的值 // 构造二叉链表表示的二叉树T。 ElemType ch; static int i = 0; char pch[] = "ABC$$DE$G$$F$$$"; // 欲产生的 先序序列。图6.8(b) ch = pch[i++]; if(ch == '$') // 空树 T = NULL; else { T = (BiTree)malloc(sizeof(BiTNode)); if(!T) // 检测是否申请结点成功 exit(-1); T->data = ch; // 生成根结点 CreateBiTree(T->lchild); // 构造左子树 CreateBiTree(T->rchild); // 构造右子树 } } void CreateBiTree_Pointer(BiTNode **BT)//BiTree *BT BT此时为指针的指针, BiTNode* *BT==BiTree *BT { // 按先序次序输入二叉树中结点的值 // 构造二叉链表表示的二叉树BT。 ElemType ch; static int i = 0; char pch[] = "AB D C "; // 欲产生的二叉树 先序序列 ch = pch[i++]; //scanf("%c",&ch); if(ch == ' ') // 空树 *BT = NULL; else { *BT = (BiTree)malloc(sizeof(BiTNode)); if(!*BT) // 检测是否申请结点成功 exit(-1); (*BT)->data = ch; // 生成根结点 CreateBiTree_Pointer(&(*BT)->lchild); // 构造左子树 CreateBiTree_Pointer(&(*BT)->rchild); // 构造右子树 } } // 中序遍历 void InOrderTraversal(BiTree BT) { if(BT) { InOrderTraversal(BT->lchild); printf("%c ", BT->data); InOrderTraversal(BT->rchild); } } //先序遍历 void PreOrderTraversal(BiTree BT) { if(BT) { printf("%c ", BT->data); PreOrderTraversal(BT->lchild); PreOrderTraversal(BT->rchild); } } // 后序遍历 void PostOrderTraversal(BiTree BT) { if(BT) { PostOrderTraversal(BT->lchild); PostOrderTraversal(BT->rchild); printf("%c ", BT->data); } } // 中序遍历非递归遍历算法 //利用压栈 void InOrderTraversal_NoRecursion(BiTNode *T) { BiTNode *Stack[MaxSize];//BiTree Stack[MaxSize] int top = -1; while(T || (top != -1)) { while(T) { // 一直向左并将沿途结点压入堆栈 Stack[++top] = T; T = T->lchild; } if(top != -1) { T = Stack[top--]; // 结点弹出堆栈 printf("%c ", T->data); //(访问)打印结点 T = T->rchild; // 转向右子树 } } } // 输出二叉树中的叶子结点。 void PreOrderPrintLeaves(BiTree BT) { if(BT) { if(BT->lchild == NULL && BT->rchild == NULL) printf("%c ", BT->data); PreOrderPrintLeaves(BT->lchild); PreOrderPrintLeaves(BT->rchild); } } // 求二叉树的深度 int Binary_tree_Deepness(BiTNode *T) { if(T == NULL) return 0; else if(T->lchild == NULL && T->rchild == NULL) return 1; else return 1 + max(Binary_tree_Deepness(T->lchild), Binary_tree_Deepness(T->rchild)); } int Binary_tree_Deepness_Post(BiTNode *T) { int h1, h2; if(T == NULL) return 0; h1 = Binary_tree_Deepness_Post(T->lchild); h2 = Binary_tree_Deepness_Post(T->rchild); if(T->lchild == NULL && T->rchild == NULL) return 1; else return 1 + max(h1, h2); } //求二叉树的度为 2 的结点数算法 int BT_CountDegree2(BiTNode *T) { int n1, n2; if (T == NULL) return 0; else { n1 = BT_CountDegree2(T->lchild); n2 = BT_CountDegree2(T->rchild); if (T->lchild != NULL && T->rchild != NULL) return 1 + n1 + n2; else return n1 + n2; } } int main() { BiTree TheBinaryTree;//BiTNode *TheBinaryTree printf("\n创建二叉树,请输入结点值系列:\n"); CreateBiTree(TheBinaryTree);//TheBinaryTree为结构体指针 printf("\n先序遍历序列:\n"); PreOrderTraversal(TheBinaryTree); printf("\n中序遍历序列:\n"); InOrderTraversal(TheBinaryTree); printf("\n中序遍历序列 - 中序遍历非递归算法:\n"); InOrderTraversal_NoRecursion(TheBinaryTree); printf("\n后序遍历序列:\n"); PostOrderTraversal(TheBinaryTree); printf("\n二叉树的深度为:\n"); //printf("%d",Binary_tree_Deepness_Post(TheBinaryTree)); printf("%d", Binary_tree_Deepness(TheBinaryTree)); printf("\n叶子结点为:\n"); PreOrderPrintLeaves(TheBinaryTree); printf("\n度为2的结点个数为:\n"); printf("%d", BT_CountDegree2(TheBinaryTree)); return 1; }