树和二叉树:二叉树的遍历

树和二叉树:二叉树的遍历

二叉树遍历的概念

二叉树的遍历是指按照一定次序访问树中所有节点,并且每个节点仅被访问一次的过程

遍历是二叉树最基本的运算,是二叉树中其他运算的基础

二叉树的组成:
树和二叉树:二叉树的遍历_第1张图片
树和二叉树:二叉树的遍历_第2张图片
1.先序遍历过程

先序遍历NLR二叉树的过程是:

  • 访问根节点;
  • 先序遍历左子树;
  • 先序遍历右子树;

二叉树先序遍历演示
树和二叉树:二叉树的遍历_第3张图片
先序遍历序列:

A B D G C E F (遍历完毕)

先序序列的第一个节点是根节点

2.中序遍历过程

中序遍历LNR二叉树的过程是:

  • 中序遍历左子树;
  • 访问根节点;
  • 中序遍历右子树;

二叉树中序遍历演示
树和二叉树:二叉树的遍历_第4张图片
中序遍历序列:

D G B A E C F (遍历完毕)

中序序列的根节点左边是左子树的节点,右边是右子树的节点

3.后序遍历过程

后序遍历LRN二叉树的过程是:

  • 后序遍历左子树;
  • 后序遍历右子树;
  • 访问根节点;

二叉树后序遍历演示
树和二叉树:二叉树的遍历_第5张图片
后序遍历序列:

G D B E F C A (遍历完毕)

后序序列的最后一个节点是根节点

例题:以若一棵二叉树的先序序列和后序序列正好相反。该二叉树的形态是什么?
树和二叉树:二叉树的遍历_第6张图片

二叉树遍历递归算法

由二叉树的三种遍历过程直接得到3种递归算法

先序遍历的递归算法:

void PreOrder(BTNode *b) {
	if(b!=NULL) {
		printf("%c",b->data); //访问根节点
		PreOrder(b->lchild);
		PreOrder(b->rchild);
	}
}

上诉访问是直接输出节点值。实际上,访问节点可以对该节点进行各种操作,如计数,删除节点等

中序遍历的递归算法:

void InOrder(BTNode *b) {
	if(b!=NULL) {
		InOrder(b->lchild);
		printf("%c",b->data); //访问根节点
		InOrder(b->rchild);
	}
}

后序遍历的递归算法:

void PostOrder(BTNode *b) {
	if(b!=NULL) {
		PostOrder(b->lchild);
		PostOrder(b->rchild);
		printf("%c",b->data); //访问根节点
	}
}

层次遍历算法

层次遍历过程:

对于一棵二叉树,从根节点开始,按从上到下,从左到右的顺序访问每一个节点,每一个节点仅仅访问一次

算法设计思路: 使用一个队列

  1. 将根节点进队;
  2. 队不空时循环: 从队列中出列一个节点*p,访问它;
    (1)若它有左孩子节点,将左孩子节点进队
    (2)若它有右孩子节点,将右孩子节点进队

对应算法如下:

void LevelOrder(BTNode *b) {
	BTNode *p;
	BTNode *qu[MaxSize]; //定义环形队列,存放节点指针
	int front,rear; //定义队头和队尾指针
	front=rear=0; //置队列为空队列
	rear++;
	qu[rear]=b; //根节点指针进入队列
	while(front!=rear) { //队列不为空循环
		front=(front+1)%MaxSize;
		p=qu[front]; //队头出队列
		printf("%c",p->data); //访问节点
		if(p->lchild!=NULL) { //有左孩子时将其进队
			rear=(rear+1)%MaxSize;
			qu[rear]=p->lchild;
		}
		if(p->rchild!=NULL) { //有右孩子时将其进队
			rear=(rear+1)%MaxSize;
			qu[rear]=p->rchild;
		}
	}
}

算法的时间复杂度为O(n)

你可能感兴趣的:(算法与数据结构,二叉树,队列,算法,指针,数据结构)