漫画算法-学习笔记(10)

漫画算法-小灰的算法之旅(10)

二叉树的广度优先遍历

如果说深度优先遍历是在一个方向上“一头扎到底”那么广度优先遍历则恰恰相反;先在各个方向上各走一步,再在各个方向上走出第二步、第三步…直到各个方向全部走完。

二叉树的层序遍历

层序遍历:就是二叉树按照从根节点到叶子节点的层次关系,一层一层横向遍历各个节点。

思路:采用**队列(FIFO)**来作为辅助结构,先将根节点放入到队列中,然后不断遍历队列。首先拿出根节点,根节点的左子树、右子树不为空,就将它们入队列;然后在依次遍历队列,将节点出队列,如果节点的左子树、右子树不为空,则将它们入队列;重复遍历队列,直到队列为空为准。

上图就是一个二叉树的层序遍历,每个节点左侧的序号代表该节点的输出顺序。可是,二叉树同一层次的节点之间是没有直接关联的,如何体现这种层序遍历呢?这里同样需要借助一个数据结构来辅助工作,这个数据结构就是队列

二叉树的层序遍历步骤如下:

  1. 根节点1进入队列
  2. 根节点1出队列,输出节点1,并得到节点1的左孩子节点2,右孩子节点3,让节点2,节点3入队列。
  3. 节点2出队列,输出节点2,并得到节点2的左孩子节点4,右孩子节点5.让节点4和节点5入队列。
  4. 节点3出队列,输出节点3,并得到节点3点的右孩子节点6,让节点6入队列。
  5. 节点4出队列,输出节点4,由于节点4没有孩子节点,所以没有新节点入队列。
  6. 节点5出队列,输出节点5,由于节点5也没有孩子节点,所以没有新节点入队列。
  7. 节点6出队列,输出节点6,由于节点6也没有孩子节点,所以没有新节点入队列。

至此,所有的节点都遍历输出完毕。

代码实现


/**
* 二叉树的层序遍历
* param root 二叉树根节点
*
*/
public static void levelOrderTraveral(TreeNode root){
  Queue<TreeNode> queue=new LinkedList<TreeNode>();
  queue.offer(root);
  while(!queue.isEmpty()){ // 如果队列不为空
    TreeNode node=queue.poll(); //出队列
    System.out.println(node.data);
    if(node.leftChild !=null){ 
      queue.offer(node.leftChild);// 如果节点左子树不为空,入队列
    }
    if(node.rightChild !=null){
      queue.offer(node.rightChild);//如果节点右子树不为空,出队列
    }
  }
}

golang实现

// 二叉树的层序遍历   先将根节点入队列,遍历队列,判断节点是否存在根节点
func levelOrderTraveral(root *TreeNode) {
	ret :=[][]interface{}{} //二维数组记录层序以及每层都节点数量
	if root ==nil {
		return
	}
	queue :=[]*TreeNode{root}
	for i:=0;len(queue)>0;i++ { // 遍历层序
		ret =append(ret,[]interface{}{})
		temp :=[]*TreeNode{}
		for j :=0;j<len(queue);j++ { //遍历每层都节点数量
			node :=queue[j]
			log.Println(node.Value)
			ret[i]=append(ret[i],node.Value)
			if node.LeftChild!=nil{
				temp=append(temp,node.LeftChild)
			}
			if node.RightChild!=nil {
				temp=append(temp,node.RightChild)
			}
		}
		queue=temp
	}
	log.Println("ret:",ret)
}

type TreeNode struct {
	Value      interface{}
	LeftChild  *TreeNode
	RightChild *TreeNode
}
func (node *TreeNode) setValue(v interface{})  {
	if node ==nil {
		log.Println("setting value  to nil node")
		return
	}
	node.Value=v
}

func NewNode(v interface{}) *TreeNode {
	return &TreeNode{
		Value:      v,
	}

}
func main(){
  	// 构造二叉树
	root := NewNode(3)
	root.LeftChild=&TreeNode{}
	root.LeftChild.setValue(2)
	root.LeftChild.LeftChild=NewNode(9)
	root.LeftChild.RightChild=NewNode(10)
	root.RightChild=NewNode(8)
	root.RightChild.RightChild=NewNode(4)
	log.Println("层序遍历")
	levelOrderTraveral(root)
}

时间复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值