iOS 数据结构之二叉树遍历

385 阅读3分钟

目录

  1. 二叉树基本知识

  2. 二叉树遍历

  3. 二叉树深度优先遍历DFS递归算法

  4. 二叉树深度优先遍历DFS非递归算法

  5. 二叉树广度优先遍历BFS改良版

  6. 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);
}