【考研必背】数据结构基本算法汇总 二叉树基础

二叉树基本算法

二叉树链式存储

typedef struct BiTNode{
     ElemType data;
     struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

二叉树的遍历

先序遍历
void preOrder(BiTree T){
     // 递归出口
     if(T == NULL) return;
     visit(T);
     preOrder(T->lchild);
     preOrder(T->rchild);
}
中序遍历
void inOrder(BiTree T){
     // 递归出口
     if(T == NULL) return;
     preOrder(T->lchild);
     visit(T);
     preOrder(T->rchild);
}
后序遍历
void inOrder(BiTree T){
     // 递归出口
     if(T == NULL) return;
     preOrder(T->lchild);
     preOrder(T->rchild);
     visit(T);
}
层序遍历
void levlOrder(BiTree T){
         InitQueue(q); // 初始化队列
         BiTree p; // 工作指针
         EnQueue(q,T); // 将树根入队
         while(p != NULL){
          DeQueue(q,p); // 出队访问
          visit(p); // 这里可以换成其他操作
          // 处理左右子树
          if(p->lchild != NULL) EnQueue(p->lchild);
          if(p->rchild != NULL) EnQueue(p->rchild);
     }
}
非递归先序遍历
void preOrder2(BiTree T){
    InitStack(S); 	// 初始化栈
    BiTree p = T;	//  工作指针p负责遍历
    while(p || ! IsEmpty(s)){	// 栈不空或者工作指针不空
        if(p){
            visit(p);	//	先序位置
            Push(S,p);	// 	访问左子树前先入栈
            p = p->lchild;	//	访问左子树
        } else {
            Pop(S,p); // 访问右子树前先出栈
            p = p->rchild;	//	访问右子树
        }
    }
}
非递归中序遍历
void inOrder2(BiTree T){
    InitStack(S); 	// 初始化栈
    BiTree p = T;	//  工作指针p负责遍历
    while(p || ! IsEmpty(s)){	// 栈不空或者工作指针不空
        if(p){
            Push(S,p);	// 	访问左子树前先入栈
            p = p->lchild;	//	访问左子树
        } else {
            Pop(S,p); // 访问右子树前先出栈
            visit(p);	//	中序位置
            p = p->rchild;	//	访问右子树
        }
    }
}

**助记: ** 非递归的先中遍历, 可以将 Push+p->lchildPop+p->rchild 看成原子操作

非递归后序遍历
void postOrder2(BiTree T){
    InitStack(S); 	// 初始化栈
    BiTree p = T;	//  工作指针p负责遍历
    r = NULL; // 	最近访问的结点
    while(p || ! IsEmpty(s)){	// 栈不空或者工作指针不空
        if(p){
            Push(S,p);	// 	访问左子树前先入栈
            p = p->lchild;	//	访问左子树
        } else {
            GetTop(S,p); // 取栈顶结点
        	if(p->rchild && p->rchild != r){ // 当前结点的右子结点存在且未被访问
                p = p->rchild; // 访问右子树 
            } 
            // 这个else 相当于递归版本里的后序位置
            else { // 右子结点不存在或已被访问
                Pop(S,p);
                visit(p); // 后序位置
                r = p; //  记录最近访问过的结点
                p = NULL;
            }
        }
    }
}

线索二叉树

typedef struct ThreadNode{
     ElemType data; // 数据元素
     struct ThreadNode *lchild,*rchild; // 左右孩子指针
     int ltag,rtag; // 左右线索标志
}

构造中序线索二叉树

void InThread(ThreadTree &p,ThreadTree &pre){
     if(p == NULL) return;
     InTread(p->lchild,pre); // 线索化左子树
     if(p->lchild == NULL){ // 左子树为空,建立前驱线索
          p->lchild = pre;
          p->ltag = 1;
     }
     if(pre != NULL && pre->rchild == NULL){
          pre->rchild = p; // 建立前驱节点的后继线索
          pre->tag = 1;
     }
     pre = p;
     InThread(p->rchild,pre); // 线索化右子树
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值