二叉树基本操作(上)

时间:2021-04-07 17:30:31

一、二叉树基本操作
1、二叉树的创建(二叉链)
a[] = {1,2,3,’#’,’#’,4,5,’#’,’#’,6,’#’,’#’,7,8,’#’,9,’#’,’#’,’#’};(‘#’代表NULL)。
二叉树基本操作(上)
2、二叉树的遍历
(1)迭代法遍历(①前序遍历②中序遍历③后序遍历)
(2)递归法遍历(①前序遍历②中序遍历③后序遍历)
(3)层序遍历。
前序遍历也叫先根遍历:访问顺序:根–>左子树–>右子树。
中序遍历也叫中根遍历:访问顺序:左子树–>根–>右子树。
后续遍历也叫后根遍历: 访问顺序:左子树–>右子树–>根。
层序遍历:访问顺序:从根节点到叶子节点(同一层中先左子树再右子树)。
二、函数代码及测试结果
1、二叉树的创建

BTNode* BuyTreeNode(DataType x) //创建树的节点
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
assert(node);
node->left = NULL;
node->right = NULL;
node->data = x;

return node;
}

BTNode* CreateBTree(DataType *a,size_t *index,DataType invalid) //创建一棵二叉树
{
BTNode *root = NULL;
if (a[*index] != invalid) //序列值不为非法值就创建左右子树
{
root = BuyTreeNode(a[*index]); //创建节点
++(*index);
root->left = CreateBTree(a,index,invalid);
++(*index);
root->right = CreateBTree(a,index,invalid);
}
return root; //返回根节点地址
}

2、二叉树的遍历
(1)迭代法(栈和队列相关知识栈和队列基本知识
①前序遍历

void BTreePrevOrder(BTNode *root) //迭代法前序遍历
{
Stack s;
BTNode *top = NULL;
BTNode *tmp = root;
StackInit(&s);
while (StackEmpty(&s) != 0 || NULL != tmp)
{
while (NULL != tmp) //遍历左子树
{
if (NULL != tmp)
{
printf("%d ",tmp->data);
StackPush(&s,tmp); //左子树不为空则入栈
tmp = tmp->left;
}
}

top = StackTop(&s); //左子树为空,取栈顶
StackPop(&s);

tmp = top->right; //访问右子树
}
}

②中序遍历


void BTreeInOrder(BTNode *root) //中序遍历
{
Stack s;
BTNode *top = NULL;
BTNode *tmp = root;
StackInit(&s);
while (StackEmpty(&s) != 0 || NULL != tmp)
{
while (NULL != tmp) //遍历左子树
{
if (NULL != tmp)
{
StackPush(&s,tmp); //左子树不为空则入栈
tmp = tmp->left;
}
}

top = StackTop(&s); //左子树为空,取栈顶
printf("%d ",top->data);
StackPop(&s);

tmp = top->right; //访问右子树
}
}

③后序遍历


void BTreeBackOrder(BTNode *root) //后序遍历
{
Stack s;
BTNode *top = NULL;
BTNode *prev = NULL;
BTNode *tmp = root;
StackInit(&s);
while (StackEmpty(&s) != 0 || NULL != tmp)
{
while (NULL != tmp) //遍历左子树
{
if (NULL != tmp)
{
StackPush(&s,tmp); //左子树不为空则入栈
tmp = tmp->left;
}
}

top = StackTop(&s); //左子树为空,取栈顶
if (NULL == top->right || top->right == prev)
{
printf("%d ",top->data);
prev = top;
StackPop(&s);
}
else
tmp = top->right; //访问右子树
}
}

(2)递归法
①前序遍历

void BTreePrevOrderR(BTNode *root)  //前序遍历
{
if (NULL == root) //递归结束条件
{
return;
}
printf("%d ",root->data); //根
BTreePrevOrderR(root->left); //左
BTreePrevOrderR(root->right); //右
}

②中序遍历


void BTreeInOrderR(BTNode *root) //中序遍历
{
if (NULL == root) //递归结束条件
{
return;
}
BTreeInOrderR(root->left); //左
printf("%d ",root->data); //根
BTreeInOrderR(root->right); //右
}

③后续遍历


void BTreeBackOrderR(BTNode *root) //后序遍历
{
if (NULL == root) //递归结束条件
{
return;
}
BTreeBackOrderR(root->left); //左
BTreeBackOrderR(root->right); //右
printf("%d ",root->data); //根
}

(3)层序遍历。(栈和队列相关知识栈和队列基本知识

void BTreeFloorOrder(BTNode *root)  //层序遍历
{
Queue q;
BTNode *tmp = root;
QueueInit(&q);
QueuePush(&q,tmp);
while (QueueEmpty(&q)) //取队头元素访问,并同时入队该元素的左右非空子树节点
{
BTNode *front = QueueFront(&q);
QueuePop(&q);
printf("%d ",front->data);
if (front->left)
{
QueuePush(&q,front->left);
}
if (front->right)
{
QueuePush(&q,front->right);
}
}
}

运算结果:
1,前序遍历
二叉树基本操作(上)
2、中序遍历
二叉树基本操作(上)
3、后序遍历
二叉树基本操作(上)
4、层序遍历
二叉树基本操作(上)

完整源代码请戳二叉树简单操作完整代码