二叉树基本操作经典实例

合集下载

C语言之二叉树各种操作

C语言之二叉树各种操作

用函数实现如下二叉排序树算法:(1)插入新结点(2)前序、中序、后序遍历二叉树(3)中序遍历的非递归算法(4)层次遍历二叉树(5)在二叉树中查找给定关键字(函数返回值为成功1,失败0)(6)交换各结点的左右子树(7)求二叉树的深度(8)叶子结点数Input第一行:准备建树的结点个数n第二行:输入n个整数,用空格分隔第三行:输入待查找的关键字第四行:输入待查找的关键字第五行:输入待插入的关键字Output第一行:二叉树的先序遍历序列第二行:二叉树的中序遍历序列第三行:二叉树的后序遍历序列第四行:查找结果第五行:查找结果第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列第九行:插入新结点后的二叉树的中序遍历序列(非递归算法)第十行:插入新结点后的二叉树的层次遍历序列第十一行~第十三行:第一次交换各结点的左右子树后的先、中、后序遍历序列第十四行~第十六行:第二次交换各结点的左右子树后的先、中、后序遍历序列第十七行:二叉树的深度第十八行:叶子结点数7↙40 20 60 18 50 56 90↙18↙35↙30↙Sample Output40 20 18 60 50 56 9018 20 40 50 56 60 9018 20 56 50 90 60 40140 20 18 30 60 50 56 9018 20 30 40 50 56 60 9018 30 20 56 50 90 60 4018 20 30 40 50 56 60 9040 20 60 18 30 50 90 5640 60 90 50 56 20 30 1890 60 56 50 40 30 20 1890 56 50 60 30 18 20 4040 20 18 30 60 50 56 9018 20 30 40 50 56 60 9018 30 20 56 50 90 60 4044#include "stdio.h"#include "malloc.h"#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define MAXQSIZE 100typedef int Status;#define STACK_INIT_SIZE 10#define STACKINCREMENT 2typedef struct BiTNode{int data;struct BiTNode *lchild,*rchild;//左右孩子指针} BiTNode,*BiTree;typedef BiTree SElemType;typedef BiTree QElemType;typedef struct QNode{QElemType num;struct QNode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front;QueuePtr rear;}LinkQueue;struct SqStack{SElemType *base; // 在栈构造之前和销毁之后,base的值为NULLSElemType *top; // 栈顶指针int stacksize; // 当前已分配的存储空间,以元素为单位}; // 顺序栈Status InitStack(SqStack &S) // 构造一个空栈S{S.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!S.base){return ERROR;}S.top = S.base;S.stacksize=STACK_INIT_SIZE;return OK;}Status Push(SqStack &S,SElemType e) // 在栈S中插入元素e为新的栈顶元素{if(S.top-S.base>=S.stacksize){S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));if(!S.base){return ERROR;}S.top = S.base+S.stacksize;S.stacksize+= STACKINCREMENT;}*S.top++ = e;return OK;}Status Pop(SqStack &S,SElemType &e) // 若栈不空,则删除S的栈顶元素,用e返回//其值,并返// 回OK;否则返回ERROR{if(S.top==S.base){return ERROR;}e=* --S.top;return OK;}Status StackEmpty(SqStack S){ // 若栈S为空栈,则返回TRUE,否则返回FALSEif(S.base==S.top){return TRUE;}elsereturn FALSE;}// 队列操作Status InitQueue(LinkQueue &Q){Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));if(!Q.front){return ERROR;}Q.front->next=NULL;return OK;}Status EnQueue( LinkQueue &Q,QElemType child) {QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p){return ERROR;}p->num=child;p->next=NULL;Q.rear->next=p;Q.rear=p;return OK;}Status DeQueue(LinkQueue &Q, QElemType &child) {QueuePtr p;if(Q.front==Q.rear)return ERROR;p=Q.front->next;child=p->num;Q.front->next=p->next;if(Q.rear==p){Q.rear=Q.front;}free(p);return OK;}Status QueueEmpty(LinkQueue Q){if(Q.front==Q.rear){return TRUE;}elsereturn FALSE;}Status DestroyQueue(LinkQueue &Q){while(Q.front){Q.rear=Q.front->next;free(Q.front);Q.front=Q.rear;}return OK;}BiTree createTree(BiTree &T) //建立空二叉树{T = (BiTNode *)malloc(sizeof(BiTNode));T= NULL;return T;}BiTree insert(BiTree &T,int ch) //元素插入{if(T==NULL){T = (BiTNode *)malloc(sizeof(BiTNode));T->lchild=NULL;T->rchild=NULL;T->data=ch;}else if (ch>T->data)T->rchild = insert(T->rchild,ch);elseT->lchild = insert(T->lchild,ch);return T;} //insertStatus find(BiTree T,int ch) //查找的关键字{int z;if(T==NULL){z=0;return z;}else if(ch>T->data)find(T->rchild,ch);else if(ch<T->data)find(T->lchild,ch);else{z=1;return z;}}Status PrintElement( int e ) // 输出元素e的值{printf("%d ", e );return OK;}Status PreOrderTraverse( BiTree T, Status(*Visit)(int)) //前序遍历{if(T){if(Visit(T->data))if(PreOrderTraverse(T->lchild,Visit))if(PreOrderTraverse( T->rchild, Visit))return OK;return ERROR;}else{return OK;}} // PreOrderTraverseStatus InOrderTraverse( BiTree T, Status(*Visit)(int) ) //递归中序遍历{if(T){if(InOrderTraverse(T->lchild,Visit))if(Visit(T->data))if(InOrderTraverse( T->rchild, Visit))return OK;return ERROR;}else{return OK;}}Status PostOrderTraverse( BiTree T, Status(*Visit)(int) ) 后序遍历{if(T){ if(PostOrderTraverse(T->lchild,Visit))if(PostOrderTraverse( T->rchild, Visit))if(Visit(T->data))return OK;return ERROR;}else{return OK;}}Status InOrderTraverse2(BiTree T,Status(*Visit)(int)) //非递归中序遍历{SqStack s;BiTree p;InitStack(s);p=T;while(p||!StackEmpty(s)){if(p){Push(s,p);p=p->lchild;}else{Pop(s,p);if(!Visit(p->data))return ERROR;p=p->rchild;}}return OK;}//层次遍历Status LevelOrderTraverse(BiTree T, Status (*Visit)(int)){LinkQueue Q; // 保存当前节点的左右孩子的队列BiTree p;InitQueue(Q); // 初始化队列if (T == NULL) return ERROR; //树为空则返回p = T; // 临时保存树根T到指针p中Visit(p->data); // 访问根节点if (p->lchild) EnQueue(Q, p->lchild); // 若存在左孩子,左孩子进队列if (p->rchild) EnQueue(Q, p->rchild); // 若存在右孩子,右孩子进队列while (!QueueEmpty(Q)) { // 若队列不空,则层序遍历DeQueue(Q, p); // 出队列Visit(p->data); // 访问当前节点if (p->lchild) EnQueue(Q, p->lchild); // 若存在左孩子,左孩子进队列if (p->rchild) EnQueue(Q, p->rchild); // 若存在右孩子,右孩子进队列}DestroyQueue(Q); // 释放队列空间return OK;}//计算最大深度Status TreeDeepth(BiTree T){int hl,hr,max;if(T){hl=TreeDeepth(T->lchild);hr=TreeDeepth(T->rchild);max=hl>hr?hl:hr;return max+1;}elsereturn 0;}//计算叶子总数Status countLeaf(BiTree T){if(T==NULL){return 0;}if(T->lchild==NULL&&T->rchild==NULL)return 1;return countLeaf(T->lchild)+countLeaf(T->rchild);}Status ChangeChild(BiTree &T) //交换左右结点{QElemType temp;if(T==NULL)return ERROR;ChangeChild(T->lchild);ChangeChild(T->rchild);temp=NULL;temp=T->lchild;T->lchild=T->rchild;T->rchild=temp;return OK;}int main() //主函数{BiTree s;int i,n,ch;int find1,find2;int inserts;scanf("%d",&n);createTree(s);for(i=0;i<n;i++){scanf("%d",&ch);insert(s,ch);}scanf("%d",&find1);scanf("%d",&find2);scanf("%d",&inserts);PreOrderTraverse( s,PrintElement );printf("\n");InOrderTraverse( s,PrintElement );printf("\n");PostOrderTraverse( s,PrintElement );printf("\n");printf("%d\n",find( s,find1));printf("%d\n",find( s,find2));insert(s,inserts);PreOrderTraverse( s,PrintElement );printf("\n");InOrderTraverse( s,PrintElement );printf("\n");PostOrderTraverse( s,PrintElement );printf("\n");InOrderTraverse2(s,PrintElement);printf("\n");LevelOrderTraverse(s, PrintElement);printf("\n");ChangeChild(s);PreOrderTraverse( s,PrintElement );printf("\n");InOrderTraverse( s,PrintElement );printf("\n");PostOrderTraverse( s,PrintElement );printf("\n");ChangeChild(s);PreOrderTraverse( s,PrintElement );printf("\n");InOrderTraverse( s,PrintElement );printf("\n");PostOrderTraverse( s,PrintElement );printf("\n");printf("%d\n",TreeDeepth(s));printf("%d\n",countLeaf(s));return OK;//补充代码}//main。

二叉树的建立与基本操作

二叉树的建立与基本操作

二叉树的建立与基本操作二叉树是一种特殊的树形结构,它由节点(node)组成,每个节点最多有两个子节点。

二叉树的基本操作包括建立二叉树、遍历二叉树、查找二叉树节点、插入和删除节点等。

本文将详细介绍二叉树的建立和基本操作,并给出相应的代码示例。

一、建立二叉树建立二叉树有多种方法,包括使用数组、链表和前序、中序、后序遍历等。

下面以使用链表的方式来建立二叉树为例。

1.定义二叉树节点类首先,定义一个二叉树节点的类,包含节点值、左子节点和右子节点三个属性。

```pythonclass Node:def __init__(self, value):self.value = valueself.left = Noneself.right = None```2.建立二叉树使用递归的方法来建立二叉树,先构造根节点,然后递归地构造左子树和右子树。

```pythondef build_binary_tree(lst):if not lst: # 如果 lst 为空,则返回 Nonereturn Nonemid = len(lst) // 2 # 取 lst 的中间元素作为根节点的值root = Node(lst[mid])root.left = build_binary_tree(lst[:mid]) # 递归构造左子树root.right = build_binary_tree(lst[mid+1:]) # 递归构造右子树return root```下面是建立二叉树的示例代码:```pythonlst = [1, 2, 3, 4, 5, 6, 7]root = build_binary_tree(lst)```二、遍历二叉树遍历二叉树是指按照其中一规则访问二叉树的所有节点,常见的遍历方式有前序遍历、中序遍历和后序遍历。

1.前序遍历前序遍历是指先访问根节点,然后访问左子节点,最后访问右子节点。

```pythondef pre_order_traversal(root):if root:print(root.value) # 先访问根节点pre_order_traversal(root.left) # 递归访问左子树pre_order_traversal(root.right) # 递归访问右子树```2.中序遍历中序遍历是指先访问左子节点,然后访问根节点,最后访问右子节点。

二叉树遍历典型例题

二叉树遍历典型例题

二叉树遍历典型例题正文:二叉树的遍历是指按照某种顺序访问二叉树中的所有节点。

常见的二叉树遍历方式有三种:前序遍历、中序遍历和后序遍历。

下面将以一个典型的例题来介绍这三种遍历方式的应用。

假设有一个二叉树如下所示:```1/2 3/4 5 6```首先介绍前序遍历。

前序遍历的顺序是先访问根节点,然后分别遍历左子树和右子树。

对于上面的二叉树,前序遍历的结果是1, 2, 4, 3, 5, 6。

接下来是中序遍历。

中序遍历的顺序是先遍历左子树,然后访问根节点,最后遍历右子树。

对于上面的二叉树,中序遍历的结果是2, 4, 1, 5, 3, 6。

最后是后序遍历。

后序遍历的顺序是先遍历左子树,然后遍历右子树,最后访问根节点。

对于上面的二叉树,后序遍历的结果是4, 2, 5, 6, 3, 1。

以上就是三种常见的二叉树遍历方式。

在实际应用中,二叉树的遍历经常用于查找、删除、插入等操作。

例如,在前序遍历中,可以用来复制一棵二叉树;在中序遍历中,可以用来对树进行排序;在后序遍历中,可以用来释放二叉树的内存等。

除了以上介绍的三种遍历方式,还存在一种更特殊的遍历方式,即层序遍历。

层序遍历是逐层访问二叉树节点的方式,从上到下、从左到右。

对于上面的二叉树,层序遍历的结果是1, 2, 3, 4, 5, 6。

在实际应用中,根据具体的问题要求,选择合适的遍历方式能够更加高效地解决问题。

因此,对于二叉树的遍历问题,我们需要熟练掌握各种遍历方式的特点和应用场景,以便于在实际问题中灵活运用。

二叉树基本操作经典实例

二叉树基本操作经典实例

二叉树基本操作经典实例二叉树是一种常见的数据结构,它由节点和指向左右子节点的指针组成。

二叉树的基本操作包括插入节点、删除节点、查找节点和遍历节点等。

在实际应用中,我们经常需要对二叉树进行基本操作,下面将介绍一些经典的例子。

一、插入节点插入节点是指向二叉树中添加一个新的节点。

在二叉树中插入节点的基本操作可以使用递归或者迭代的方法来实现。

下面是一个使用递归方法的示例代码:```public class TreeNodeint val;TreeNode left;TreeNode right;TreeNode(int x) { val = x; }public TreeNode insertNode(TreeNode root, int val)if (root == null)return new TreeNode(val);}if (val < root.val)root.left = insertNode(root.left, val);} else if (val > root.val)root.right = insertNode(root.right, val);}return root;```在上述代码中,通过递归的方式判断要插入的值和当前节点的大小关系,并将值插入到左子树或者右子树中,最后返回根节点。

二、删除节点删除节点是从二叉树中移除一个节点。

删除节点的基本操作可以分为三种情况:删除叶子节点、删除只有一个子节点的节点和删除有两个子节点的节点。

(1)删除叶子节点:如果要删除的节点是叶子节点,直接将该节点的父节点的指针指向空即可。

(2)删除只有一个子节点的节点:如果要删除的节点只有一个子节点,将该节点的子节点连接到该节点的父节点即可。

(3)删除有两个子节点的节点:如果要删除的节点有两个子节点,可以使用该节点右子树中的最小节点或者左子树中的最大节点来替代。

下面是一个使用递归方法的示例代码:```public TreeNode deleteNode(TreeNode root, int key) if (root == null)return root;}if (key < root.val)root.left = deleteNode(root.left, key);} else if (key > root.val)root.right = deleteNode(root.right, key);} elseif (root.left == null)return root.right;} else if (root.right == null)return root.left;}TreeNode minNode = findMin(root.right);root.val = minNode.val;root.right = deleteNode(root.right, minNode.val); }return root;private TreeNode findMin(TreeNode node)while (node.left != null)node = node.left;}return node;```在上述代码中,通过递归的方式判断要删除的值和当前节点的大小关系,并根据不同情况进行处理。

二叉树及二叉树的基本操作(基础篇)

二叉树及二叉树的基本操作(基础篇)

⼆叉树及⼆叉树的基本操作(基础篇)⼀、相关概念树是n( n>=0)个有限个数据的元素集合,它的数据的存储结构形状像⼀颗倒过来的树。

根在上,叶在下:如图所⽰1.⼀个独⽴的节点也可看作⼀棵树,它既为根节点,⼜为叶⼦节点;2.⼀个节点也没有称作空树;3.这是⼀颗典型的树,根节点为A;4.⼀个节点只有唯⼀⽗节点。

节点:结点包含数据和指向其它节点的指针。

根节点:树第⼀个结点称为根节点。

结点的度:结点拥有的⼦节点个数。

叶节点:没有⼦节点的节点(度为0)。

⽗⼦节点:⼀个节点father指向另⼀个节点child,则child为孩⼦节点, father为⽗亲节点。

兄弟节点:具有相同⽗节点的节点互为兄弟节点。

节点的祖先:从根节点开始到该节点所经的所有节点都可以称为该节点的祖先。

⼦孙:以某节点为根的⼦树中任⼀节点都称为该节点的⼦孙。

树的⾼度:树中距离根节点最远节点的路径长度。

如图⽰:5.树的存储结构1 struct TreeNode2 {3 DataType data; //节点值4 TreeNode* _firistchild; //第⼀个孩⼦5 TreeMode* _nextchild; //第⼆个孩⼦6 ...7 };有时候根据需要还会加⼊⽗节点,结构如下:1 struct TreeNode2 {3 DataType data; //节点值4 TreeNode* _parent;5 TreeNode* _firistchild; //第⼀个孩⼦6 TreeMode* _nextchild; //第⼆个孩⼦7 ...8 };⼆、⼆叉树1.⼆叉树:⼆叉树是⼀棵特殊的树,⼆叉树每个节点最多有两个孩⼦结点,分别称为左孩⼦和右孩⼦。

如图:2.存储结构1 template <class T>2 struct TreeNode //定义⼆叉树结点3 {5 TreeNode<T>* _left; //指向左⼦树的指针6 TreeNode<T>* _right; //指向右⼦树的指针7 T _data; //节点数据8 TreeNode(const T& n)9 :_left(NULL)10 ,_right(NULL)11 ,_data(n)12 {}13 };有时候根据需要还会加⼊⽗节点,结构如下:1 template <class T>2 struct TreeNode //定义⼆叉树结点3 {4 TreeNode<T>* _parent; //指向⽗节点的指针5 TreeNode<T>* _left; //指向左⼦树的指针6 TreeNode<T>* _right; //指向右⼦树的指针7 T _data; //节点数据8 TreeNode(const T& n)9 :_left(NULL)10 ,_right(NULL)11 ,_data(n)12 {}13 };3.特殊的⼆叉树满⼆叉树:⾼度为N的满⼆叉树有2^N - 1个节点的⼆叉树。

c语言二叉树的基本操作

c语言二叉树的基本操作

c语言二叉树的基本操作一、概念二叉树是一种数据结构,它由节点组成,每个节点都有0个或2个子节点,左子节点的关键字小于或等于该节点的关键字,右子节点的关键字大于该节点的关键字。

二、基本操作1、创建二叉树(1)结构体定义typedef struct node{int data; // 数据struct node *left; // 左子节点struct node *right; // 右子节点}Node, *pNode;(2)创建节点return p;}// 创建根节点*pTree = create_node(arr[0]);// 寻找合适的位置插入节点while (p != NULL){q = p;if (arr[i] < p->data)p = p->left;elsep = p->right;}2、遍历二叉树遍历二叉树有三种方法,分别是前序遍历、中序遍历和后序遍历。

(1)前序遍历void pre_order(pNode pTree){if (pTree != NULL){printf("%d ", pTree->data);pre_order(pTree->left);pre_order(pTree->right);}}3、查找节点找到关键字为data的节点,返回指向该节点的指针。

pNode search_node(pNode pTree, int data){if (pTree == NULL)return NULL;4、计算深度计算二叉树的深度,即为根节点到叶子节点的最长路径所包含的节点个数。

return left_depth > right_depth ? left_depth + 1 : right_depth + 1; }5、计算叶子节点数return leaf_count(pTree->left) + leaf_count(pTree->right);}6、删除节点删除节点分为两种情况:(1)被删除节点为叶子节点直接将其父节点指向该节点的指针设置为NULL即可。

二叉树的现实中典型例子

二叉树的现实中典型例子

二叉树的现实中典型例子二叉树是一种常用的数据结构,它具有广泛的应用。

下面列举了十个二叉树在现实中的典型例子。

一、文件系统文件系统是计算机中常见的二叉树应用之一。

文件系统中的目录和文件可以组织成一棵树,每个目录称为一个节点,而文件则是叶子节点。

通过树的结构,我们可以方便地对文件和目录进行管理和查找。

二、组织架构企业或组织的组织架构通常可以用二叉树来表示。

每个部门可以看作是一个节点,而员工则是叶子节点。

通过组织架构树,我们可以清晰地了解到企业或组织内部的管理层级关系。

三、家谱家谱是一个家族的血缘关系的记录,一般可以用二叉树来表示。

每个人可以看作是一个节点,而父子关系则是节点之间的连接。

通过家谱树,我们可以追溯家族的历史和血缘关系。

四、编译器编译器是将高级语言转换为机器语言的程序。

在编译过程中,编译器通常会使用语法分析树来表示源代码的结构。

语法分析树是一种特殊的二叉树,它将源代码表示为一个树状结构,方便进行语法分析和编译优化。

五、数据库索引数据库中的索引是一种用于提高数据查询效率的数据结构。

常见的索引结构包括B树和B+树,它们都是二叉树的变种。

通过索引树,数据库可以快速地定位到需要查询的数据,提高数据库的检索性能。

六、表达式求值在数学计算中,表达式求值是一项重要的任务。

通过使用二叉树,我们可以方便地表示和计算表达式。

二叉树的叶子节点可以是操作数,而内部节点可以是运算符。

通过遍历二叉树,我们可以按照正确的顺序对表达式进行求值。

七、电路设计在电路设计中,二叉树也有广泛的应用。

例如,我们可以使用二叉树来表示逻辑电路的结构,每个门电路可以看作是一个节点,而连接线则是节点之间的连接。

通过电路设计树,我们可以方便地进行电路的布线和优化。

八、图像处理图像处理是一项常见的计算机技术,而二叉树在图像处理中也有重要的应用。

例如,我们可以使用二叉树来表示图像的像素信息,每个像素可以看作是一个节点,而像素之间的关系则是节点之间的连接。

二叉树的几个经典例题

二叉树的几个经典例题

⼆叉树的⼏个经典例题⼆叉树遍历1题⽬描述编⼀个程序,读⼊⽤户输⼊的⼀串先序遍历字符串,根据此字符串建⽴⼀个⼆叉树(以指针⽅式存储)。

例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表⽰的是空格,空格字符代表空树。

建⽴起此⼆叉树以后,再对⼆叉树进⾏中序遍历,输出遍历结果。

输⼊描述:输⼊包括1⾏字符串,长度不超过100。

输出描述:可能有多组测试数据,对于每组数据,输出将输⼊字符串建⽴⼆叉树后中序遍历的序列,每个字符后⾯都有⼀个空格。

每个输出结果占⼀⾏。

输⼊abc##de#g##f###输出c b e gd f a思路:递归建树。

每次都获取输⼊字符串的当前元素,根据题⽬要求(先序、中序、后序等+其他限制条件)建树。

再根据题⽬要求输出即可。

1 #include<bits/stdc++.h>2using namespace std;3struct node{4char data;5 node *lchild,*rchild;6 node(char c):data(c),lchild(NULL),rchild(NULL){}7 };8string s;9int loc;10 node* create(){11char c=s[loc++];//获取每⼀个字符串元素12if(c=='#') return NULL;13 node *t=new node(c);//创建新节点14 t->lchild=create();15 t->rchild=create();16return t;17 }18void inorder(node *t){//递归中序19if(t){20 inorder(t->lchild);21 cout<<t->data<<'';22 inorder(t->rchild);23 }24 }25int main(){26while(cin>>s){27 loc=0;28 node *t=create();//先序遍历建树29 inorder(t);//中序遍历并输出30 cout<<endl;31 }32return0;33 }⼆叉树遍历2题⽬描述⼆叉树的前序、中序、后序遍历的定义:前序遍历:对任⼀⼦树,先访问跟,然后遍历其左⼦树,最后遍历其右⼦树;中序遍历:对任⼀⼦树,先遍历其左⼦树,然后访问根,最后遍历其右⼦树;后序遍历:对任⼀⼦树,先遍历其左⼦树,然后遍历其右⼦树,最后访问根。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本程序由SOGOF完成该完整程序主要是递归函数的使用及模板的使用,完成了对二叉树基本的链表操作,主要有二叉树的建立,前序、中序、后序遍历,求树的高度,每层结点数(包含树的最大宽度),左右结点对换,二叉树的内存释放,求解树的叶子数。

#include<iostream>using namespace std;#define FLAG'#'typedef char Record;template<typename Entry>struct Binary_Node{Entry data;Binary_Node<Entry>*left;Binary_Node<Entry>*right;Binary_Node();Binary_Node(const Entry& x);};template<typename Entry>Binary_Node<Entry>::Binary_Node(){left=NULL;right=NULL;}template<typename Entry>Binary_Node<Entry>::Binary_Node(const Entry &x){data=x;left=NULL;right=NULL;}template<class T>class Binary_tree{public:bool empty()const;Binary_tree();Binary_tree(Binary_tree<T>&org);void create_tree(Binary_Node<T>*&tree);//建立二叉树void recursive_copy(Binary_Node<T>*&tree,Binary_Node<T>*&cur);void pre_traverse(Binary_Node<T> *tree);//前序void mid_traverse(Binary_Node<T> *tree);//中序void post_traverse(Binary_Node<T> *tree);//后序遍历void count_node(Binary_Node<T> *tree,int &count);//计算结点数void count_leaves(Binary_Node<T> *tree,int &count);//计算叶子数int tree_height(Binary_Node<T> *tree);//树的高度void Ltree_To_Rtree(Binary_Node<T>*tree);//左右树互换void count_width(Binary_Node<T> *tree,int *count_width,int count);//计算树的最大宽度int get_count()const;//得到树的结点数Binary_Node<T>*get_root()const;void destroy_tree(Binary_Node<T> *tree);//删除数Binary_tree<T>&operator=(Binary_tree&org);protected:T*pre_visit;T*mid_visit;Binary_Node<T>*root;int node_numb;};template<class T>Binary_tree<T>::Binary_tree(){root=NULL;node_numb=0;}template<class T>voidBinary_tree<T>::recursive_copy(Binary_Node<T>*&tree,Binary_Node<T>*&cur) {if(tree==NULL){return;}else{cur=new Binary_Node<T>(tree->data);node_numb++;recursive_copy(tree->left,cur->left);recursive_copy(tree->right,cur->right);}}template<class T>Binary_tree<T>::Binary_tree( Binary_tree<T>&org)recursive_copy(org.root,root);}template<class T>Binary_tree<T>& Binary_tree<T>::operator =(Binary_tree<T>&org) {recursive_copy(org.root,root);return *this;}template<class T>bool Binary_tree<T>::empty() const{return root==NULL;}template<class T>int Binary_tree<T>::get_count()const{return node_numb;}template<class T>void Binary_tree<T>::create_tree(Binary_Node<T>*&tree){T val;cout<<"请输入数据,若空以#输入: ";cin>>val;tree=new Binary_Node<T>(val);if(val==FLAG){tree=NULL;return;}else{node_numb++;if(root==NULL)root=tree;create_tree(tree->left);create_tree(tree->right);}template<class T>Binary_Node<T>* Binary_tree<T>::get_root() const{return root;}template<class T>void Binary_tree<T>::count_node(Binary_Node<T> *tree,int& count){if(tree){count++;count_node(tree->left,count);count_node(tree->right,count);}}template<class T>void Binary_tree<T>::count_leaves(Binary_Node<T> *tree,int& count){if(tree){ if((tree->left==NULL)&&(tree->right==NULL))count++;count_leaves(tree->left,count);count_leaves(tree->right,count);}}template<class T>void Binary_tree<T>::count_width(Binary_Node<T> *tree,int *count_mid,int count) {if(tree){if(tree!=root)count++;count_width(tree->left,count_mid,count);count_width(tree->right,count_mid,count);count_mid[count]++;}}template<class T>int Binary_tree<T>::tree_height(Binary_Node<T> *tree){int count_left=0, count_right=0;if(tree==NULL)return 0;else{count_left=tree_height(tree->left);count_right=tree_height(tree->right);return(count_left>count_right)?(count_left+1):(count_right+1);}}template<class T>void Binary_tree<T>::Ltree_To_Rtree(Binary_Node<T>*tree){if(tree){Ltree_To_Rtree(tree->left);Ltree_To_Rtree(tree->right);if(tree->left!=NULL||tree->right!=NULL){Binary_Node<T>*temp=tree->left;tree->left=tree->right;tree->right=temp;}}}template<class T>void Binary_tree<T>::destroy_tree(Binary_Node<T> *tree){if(tree){Binary_Node<T> *parent=tree;destroy_tree(tree->left);destroy_tree(tree->right);if(parent==root){delete root;root=NULL;parent=NULL;node_numb--;}else{delete parent;parent=NULL;node_numb--;}}}template<class T>void Binary_tree<T>::pre_traverse(Binary_Node<T> *tree) {if(root==NULL){cout<<"树为空,不能遍历"<<endl;return;}if(tree){cout<<" "<<tree->data;pre_traverse(tree->left);pre_traverse(tree->right);}}template<class T>void Binary_tree<T>::mid_traverse(Binary_Node<T> *tree) {if(root==NULL){cout<<"树为空,不能遍历"<<endl;return;}if(tree){mid_traverse(tree->left);cout<<" "<<tree->data;mid_traverse(tree->right);}}template<class T>void Binary_tree<T>::post_traverse(Binary_Node<T> *tree) {if(root==NULL){cout<<"树为空,不能遍历"<<endl;return;}if(tree){post_traverse(tree->left);post_traverse(tree->right);cout<<" "<<tree->data;}}void main(){int m=0,leaves=0,Tree_height;Binary_tree<Record>Tree;Binary_Node<Record>*pp;Tree.create_tree(pp);Binary_tree<Record>Tree1(Tree);cout<<"前序遍历结果为:";Tree.pre_traverse(Tree.get_root());cout<<endl<<"中序遍历结果为:";Tree.mid_traverse(Tree.get_root());cout<<endl<<"后序遍历结果为:";Tree.post_traverse(Tree.get_root());cout<<endl;Tree.count_node(Tree.get_root(),m);cout<<"结点个数为:"<<m<<endl;Tree.count_leaves(Tree.get_root(),leaves);cout<<"叶子个数为:"<<leaves<<endl;Tree_height=Tree.tree_height(Tree.get_root());cout<<"树高度为:"<<Tree_height<<endl;m=0;int *count_wid=new int[Tree_height];for(int i=0;i<Tree_height;i++)count_wid[i]=0;Tree.count_width(Tree.get_root(),count_wid,m);int Max=count_wid[0];m=0;for(int i=0;i<Tree_height;i++){cout<<"在第"<<i<<"层,共有结点"<<count_wid[i]<<"个"<<endl;if(Max<count_wid[i]){Max=count_wid[i];m=i;}}cout<<"在第"<<m<<"层结点最多,共有结点"<<Max<<"个"<<endl;Tree.Ltree_To_Rtree(Tree.get_root());Tree.destroy_tree(Tree.get_root());delete []count_wid;}树如下:(a)(b) (c)(d) (e) (f) (g)输入:输出:。

相关文档
最新文档