目录
-
二叉树基本知识
-
二叉树遍历
-
二叉树深度优先遍历DFS递归算法
-
二叉树深度优先遍历DFS非递归算法
-
二叉树广度优先遍历BFS改良版
-
OC实现
一、二叉树基本知识
1.树的定义
树是一种数据结构,它是由N(N >= 1)个有限结点组成一个具有层次关系的集合。 特点:
- 每个结点有0个或者多个子结点
- 没有父结点的结点称为根结点
- 每一个非根结点有且只有一个父结点
- 除了根结点外,每个子结点可以分为多个不相交的子树
2.树基本术语
结点n的高度: n结点到叶子结点所有路径上包含结点个数的最大值。叶子结点的高度为1,往上依次递增。
结点的深度: 从根结点到结点n唯一路径的长,根结点的深度为1(有的书上此基数为0,两种记法都没有错)
层数: 根结点为第一层,往下依次递增。
结点的度: 结点拥有的子树个数,度为0的结点称为叶子结点。
叶子: 度为零的结点。
树的度: 树中结点的最大的度。
树的高度: 树中结点的最大层次(在基数为1时,树的深度 = 树的高度 = 最大层数)。
3.二叉查找树
二叉查找树:
- 若左子树不空,则左子树上所有结点的值均小于它根结点的值。
- 若右子树不空,则右子树上所有结点的值均大于它根结点的值。
- 左、右子树也分别为二叉查找树。
- 没有键值相等的结点
二、二叉树遍历
二叉树题目的核心点都在遍历,因而只有撑握了遍历相关的知识点,才能在之后刷LeetCode的过程中更方便轻松的刷题
第一点:深度优先遍历(DFS)
深度优先遍历之递归算法模板:
前序遍历
function dfs(root) {
if (满足特定条件){
// 返回结果 or 退出搜索空间
}
// 主要逻辑
dfs(root.left)
dfs(root.right)
}
中序遍历
function dfs(root) {
if (满足特定条件){
// 返回结果 or 退出搜索空间
}
dfs(root.left)
// 主要逻辑
dfs(root.right)
}
后序遍历
function dfs(root) {
if (满足特定条件){
// 返回结果 or 退出搜索空间
}
dfs(root.left)
dfs(root.right)
// 主要逻辑
}
先序遍历非递归算法模板:
- (void)PreOrderNode:(BinaryNode*)root {
NSMutableArray *array = [[NSMutableArray alloc]init];
Stack *stacks = [[Stack alloc]init];
[stacks push:root];
while (![stacks isEmpty]) {
root = [stacks popObj];
[array addObject:root.value];
if (root.rightNode) {
[stacks push:root.rightNode];
}
if (root.leftNode) {
[stacks push:root.leftNode];
}
}
NSLog(@"打印%@",array);
}
中序遍历非递归算法模板:
- (void)secondeNodeTree:(BinaryNode*)root {
NSMutableArray *arr = [[NSMutableArray alloc]init];
if (!root) {
return;
}
Stack *stack1 = [Stack new];
while (![stack1 isEmpty]||root) {
if (root) {
[stack1 push:root];
root = root.leftNode;
} else {
root = [stack1 popObj];
[arr addObject:root.value];
root = root.rightNode;
}
}
NSLog(@"打印%@",arr);
}
后序遍历非递归算法模板(双栈法):
// 非迭代法后序遍历(双栈法)
- (void)thirdNodeTree:(BinaryNode*)root {
NSMutableArray *array = [[NSMutableArray alloc]init];
Stack *stacks = [[Stack alloc]init];
Stack *tirdStack = [Stack new];
[stacks push:root];
while (![stacks isEmpty]) {
root = [stacks popObj];
[tirdStack push:root];
if (root.leftNode) {
[stacks push:root.leftNode];
}
if (root.rightNode) {
[stacks push:root.rightNode];
}
}
while (![tirdStack isEmpty]) {
BinaryNode *node = [tirdStack popObj];
[array addObject:node.value];
}
NSLog(@"打印%@",array);
}
后序遍历非递归算法模板(前节点法):
//前节点法后序遍历
- (void)afterNodeTree:(BinaryNode*)root {
NSMutableArray *array = [[NSMutableArray alloc]init];
if (!root) {
return;
}
Stack *st1 = [Stack new];
[st1 push:root];
BinaryNode *fatherNode = nil;
while (!st1.isEmpty) {
BinaryNode *currNode = [st1 topObj];
if (!fatherNode||fatherNode.leftNode==currNode||fatherNode.rightNode==currNode) {
if (currNode.leftNode) {
[st1 push:currNode.leftNode];
} else if (currNode.rightNode){
[st1 push:currNode.rightNode];
} else {
[array addObject:currNode.value];
[st1 popObj];
}
} else if (currNode.leftNode==fatherNode) {
if(currNode.rightNode){
[st1 push:currNode.rightNode];
} else {
[array addObject:currNode.value];
[st1 popObj];
}
} else if (currNode.rightNode==fatherNode) {
[array addObject:currNode.value];
[st1 popObj];
}
fatherNode = currNode;
}
NSLog(@"打印%@",array);
}
层序遍历
//层序遍历
- (void)levelTraversal:(BinaryNode*)root {
NSMutableArray *array = [[NSMutableArray alloc]init];
if (!root) {
return;
}
NSMutableArray *list = [[NSMutableArray alloc]init];
[list addObject:root];
while (list.count>0) {
BinaryNode *topNode = list.firstObject;
[array addObject:topNode.value];
[list removeObjectAtIndex:0];
if (topNode.leftNode) {
[list addObject:topNode.leftNode];
}
if (topNode.rightNode) {
[list addObject:topNode.rightNode];
}
}
NSLog(@"打印%@",array);
}