重写数据结构--二叉树
2016-08-12 14:48
169 查看
二叉树
过了太久猛一遇到还真不知道写些什么好,只记得建树,三种遍历方式,插入结点删除结点好像就变得很麻烦,但是还是要啃一下。先实现三种遍历方式,练一下手。
前序遍历:
很简单的递归的使用,没什么难的吧,直接上代码:
void frontTraversal (BinaryTreeNode* root) { if (root == NULL) { return; } else { cout << root->value << ' '; frontTraversal(root->pLeft); frontTraversal(root->pRight); } }
中序遍历:
void InOrderTraversal (BinaryTreeNode* root) { if (root == NULL) { return; } else { InOrderTraversal(root->pLeft); cout << root->value << ' '; InOrderTraversal(root->pRight); } }
后序遍历:
void PostOrderTraversal (BinaryTreeNode* root) { if (root == NULL) { return; } else { PostOrderTraversal(root->pLeft); PostOrderTraversal(root->pRight); cout << root->value << ' '; } }
建树的话,根据前序遍历和中序遍历可以建树
理一下思路:
思想是递归,先创建一个根节点来存前序的第一个元素,然后找到中序中前序第一个元素的位置k,然后中序里 0 ~ k-1是左子树,k - 1到结束是右子树
那么我们就知道了相对于根节点的左子树和右子树的元素的个数,然后再在前序里面进行拆分:第0个元素为根节点,从第1(index为1)个元素开始的k个元素是左子树,剩下的是右子树,然后分别对左右子树进行创建。
终止条件:
可以定义一个cnt,参数表里传入它的引用,每次创建节点就加1,每次进入函数判断一下cnt是否等于前序数组的长度,如果等于,则退出;
不过网上盛传的版本是另外一种:
传入的参数是前序和中序数组的首地址,和从首地址开始的长度,当指针为空或者长度为0时终止。
BinaryTreeNode* buildByPreAndIn(int* pre_order, int* in_order, int num) { if (pre_order == NULL || in_order == NULL || num <= 0) return NULL; BinaryTreeNode* root = new BinaryTreeNode; root->value = *pre_order; root->pLeft = root->pRight = NULL; int rootPositionInOrder = -1; for (int i = 0; i < num; i++) { if (in_order[i] == root->value) { rootPositionInOrder = i; break; } } int num_Left = rootPositionInOrder; int num_Right = num - num_Left - 1; int* pre_order_left = pre_order + 1; int* in_order_left = in_order; root->pLeft = buildByPreAndIn(pre_order_left, in_order_left, num_Left); int* pre_order_right = pre_order + num_Left + 1; int* in_order_right = in_order + num_Left + 1; root->pRight = buildByPreAndIn(pre_order_right, in_order_right, num_Right); return root; }
如果知道后序和中序,思路是一样的,直接贴代码:
BinaryTreeNode* buildByPostAndIn(int* post_order, int* in_order, int num) { if (post_order == NULL || in_order == NULL || num <= 0) return NULL; BinaryTreeNode* root = new BinaryTreeNode; root->value = post_order[num - 1]; root->pLeft = root->pRight = NULL; int rootPositionInOrder = -1; for (int i = 0; i < num; i++) { if (in_order[i] == root->value) { rootPositionInOrder = i; break; } } int num_Left = rootPositionInOrder; int num_Right = num - num_Left - 1; int* post_order_left = post_order; int* in_order_left = in_order; root->pLeft = buildByPostAndIn(post_order_left, in_order_left, num_Left); int* post_order_right = post_order + num_Left; int* in_order_right = in_order + num_Left + 1; root->pRight = buildByPostAndIn(post_order_right, in_order_right, num_Right); return root; }
求二叉树节点的个数:
递归就好
int getNumOfElements(BinaryTreeNode* root) { if (root == NULL) { return 0; } else { return getNumOfElements(root->pLeft) + getNumOfElements(root->pRight) + 1; } }
求二叉树的深度:
int getDepth(BinaryTreeNode* root) { if (root == NULL) { return 0; } else { return max(getDepth(root->pLeft), getDepth(pRight)) + 1; } }
求叶子节点的个数:
我自己想的是找出所有的节点的个数,然后再找出所有非叶子节点的个数然后减一下,但是看了网上的版本,这个显然更好:
int getNumOfLeaf(BinaryTreeNode* root) { if (root == NULL) { return 0; } if (root->pLeft == root->pRight == NULL) { return 1; } return getNumOfLeaf(root->pLeft) + getNumOfLeaf(root->pRight); }
基础的大概就是这些。
推荐一篇博文讲到的更详细:
http://blog.csdn.net/luckyxiaoqiang/article/details/7518888/#topic7
相关文章推荐
- 数据结构复习(重写某些重要数据结构API) ------------二叉树
- 数据结构上机测试4.1:二叉树的遍历与应用1
- 基本数据结构:二叉树(binary tree)
- 数据结构-树-二叉树-定义,遍历
- 【数据结构】中二叉树的遍历方式
- 【数据结构_树_Tree_0973】利用二叉树计算叶结点个数
- 【数据结构_树_Tree_0982】利用二叉树储存普通树的度
- 重温数据结构:二叉树的常见方法及三种遍历方式 Java 实现
- javascript数据结构系列(六)-树和二叉树(1)
- 数据结构学习笔记7——二叉树介绍
- 关于java数据结构hashSet与TreeSet重写方法的格式
- 数据结构练习题---先序遍历二叉树
- 【数据结构】二叉树的学习
- 数据结构复习:几种排序算法的C++实现和二叉树的相关算法实现
- 数据结构-二叉树基础题目小结(遍历,求节点数目等等)
- 【郝斌数据结构自学笔记】66-69_森林的存储_二叉树的先序遍历_二叉树的中序遍历【中间访问根节点】_二叉树的后序遍历【最后访问根节点】
- java--数据结构--二叉树根节点到指定节点的路径
- Android版数据结构与算法(六):树与二叉树
- 数据结构(JAVA)---二叉树的简单实现及排序
- 数据结构--二叉树