您的位置:首页 > 理论基础 > 数据结构算法

重写数据结构--二叉树

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 二叉树