【编程练习】复习一下树的遍历

深度有限遍历记录层数:增加一个level

//深度优先遍历
void depthFirstSearch(Tree root){
    stack<pair<int, Node *> > nodeStack;  //使用C++的STL标准模板库
    nodeStack.push(make_pair(0, root));
    Node *node;
    while(!nodeStack.empty()){
        node = nodeStack.top().second;
        int level = nodeStack.top().first;
        printf(format, node->data);  //遍历根结点
        nodeStack.pop();
        if(node->rchild){
            nodeStack.push(make_pair(level + 1, node->rchild));  //先将右子树压栈
        }
        if(node->lchild){
            nodeStack.push(make_pair(level + 1, node->lchild));  //再将左子树压栈
        }
    }
}
#include <iostream>
#include <stack>
#include <queue>
#include <locale.h>
using namespace std;
typedef struct BiTNode {//二叉树结点
    char data;                      //数据
    struct BiTNode *lchild,*rchild; //左右孩子指针
} BiTNode,*BiTree;
int CreateBiTree(BiTree &T) {//按先序序列创建二叉树
    char data;
    scanf("%c",&data);//按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
    if (data == '#') {
        T = NULL;
    } else {
        T = (BiTree)malloc(sizeof(BiTNode));
        T->data = data;         //生成根结点
        CreateBiTree(T->lchild);//构造左子树
        CreateBiTree(T->rchild);//构造右子树
    }
    return 0;
}
void Visit(BiTree T) {//输出
    if (T->data != '#') {
        printf("%c ",T->data);
    }
}
void PreOrder(BiTree T) {//先序遍历
    if (T != NULL) {
        Visit(T);               //访问根节点
        PreOrder(T->lchild);    //访问左子结点
        PreOrder(T->rchild);    //访问右子结点
    }
}
void InOrder(BiTree T) {//中序遍历
    if (T != NULL) {
        InOrder(T->lchild);     //访问左子结点
        Visit(T);               //访问根节点
        InOrder(T->rchild);     //访问右子结点
    }
}
void PostOrder(BiTree T) {//后序遍历
    if (T != NULL) {
        PostOrder(T->lchild);   //访问左子结点
        PostOrder(T->rchild);   //访问右子结点
        Visit(T);               //访问根节点
    }
}
void PreOrder2(BiTree T) {//先序遍历(非递归)
//访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
    stack<BiTree> stack;
    BiTree p = T;//p是遍历指针
    while (p || !stack.empty()) {   //栈不空或者p不空时循环
        if (p != NULL) {
            stack.push(p);          //存入栈中
            printf("%c ",p->data);  //访问根节点
            p = p->lchild;          //遍历左子树
        } else {
            p = stack.top();        //退栈
            stack.pop();
            p = p->rchild;          //访问右子树
        }
    }
}
void InOrder2(BiTree T) {//中序遍历(非递归)
//T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
//先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
    stack<BiTree> stack;
    BiTree p = T;//p是遍历指针
    while (p || !stack.empty()) {   //栈不空或者p不空时循环
        if (p != NULL) {
            stack.push(p);          //存入栈中
            p = p->lchild;          //遍历左子树
        } else {
            p = stack.top();        //退栈,访问根节点
            printf("%c ",p->data);
            stack.pop();
            p = p->rchild;          //访问右子树
        }
    }
}

typedef struct BiTNodePost{
    BiTree biTree;
    char tag;
} BiTNodePost,*BiTreePost;
void PostOrder2(BiTree T) {//后序遍历(非递归)
    stack<BiTreePost> stack;
    BiTree p = T;//p是遍历指针
    BiTreePost BT;
    while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环
        while (p != NULL) {//遍历左子树
            BT = (BiTreePost)malloc(sizeof(BiTNodePost));
            BT->biTree = p;
            BT->tag = 'L';//访问过左子树
            stack.push(BT);
            p = p->lchild;
        }
        while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点
            BT = stack.top();
            stack.pop();//退栈
            printf("%c ",BT->biTree->data);
        }
        if (!stack.empty()) {//遍历右子树
            BT = stack.top();
            BT->tag = 'R';//访问过右子树
            p = BT->biTree;
            p = p->rchild;
        }
    }
}

void LevelOrder(BiTree T) {//层次遍历
    if (T == NULL) return;
    BiTree p = T;
    queue<BiTree> queue;//队列
    queue.push(p);//根节点入队
    while (!queue.empty()) {    //队列不空循环
        p = queue.front();      //对头元素出队
        printf("%c ",p->data);  //访问p指向的结点
        queue.pop();            //退出队列
        if (p->lchild != NULL) {//左子树不空,将左子树入队
            queue.push(p->lchild);
        }
        if (p->rchild != NULL) {//右子树不空,将右子树入队
            queue.push(p->rchild);
        }
    }
}
int main() {
    BiTree T;

    setlocale(LC_ALL,"chs");
    CreateBiTree(T);

    printf("先序遍历        :");PreOrder  (T);printf("\n");
    printf("先序遍历(非递归):");PreOrder2 (T);printf("\n");
                                               printf("\n");
    printf("中序遍历        :");InOrder   (T);printf("\n");
    printf("中序遍历(非递归):");InOrder2  (T);printf("\n");
                                               printf("\n");
    printf("后序遍历        :");PostOrder (T);printf("\n");
    printf("后序遍历(非递归):");PostOrder2(T);printf("\n");
                                               printf("\n");
    printf("层次遍历        :");LevelOrder(T);printf("\n");

    return 0;
}
//ABC##DE#G##F###
//先序遍历        :A B C D E G F
//先序遍历(非递归):A B C D E G F
//
//中序遍历        :C B E G D F A
//中序遍历(非递归):C B E G D F A
//
//后序遍历        :C G E F D B A
//后序遍历(非递归):C G E F D B A
//
//层次遍历        :A B C D E F G
//

///       A
///      /
///     B
///    / \
///   C   D
///      / \
///     E   F
///      \
///       G

深度优先遍历:

//深度优先遍历
void depthFirstSearch(Tree root){
    stack<Node *> nodeStack;  //使用C++的STL标准模板库
    nodeStack.push(root);
    Node *node;
    while(!nodeStack.empty()){
        node = nodeStack.top();
        printf(format, node->data);  //遍历根结点
        nodeStack.pop();
        if(node->rchild){
            nodeStack.push(node->rchild);  //先将右子树压栈
        }
        if(node->lchild){
            nodeStack.push(node->lchild);  //再将左子树压栈
        }
    }
}<pre class="cpp" name="code">
</pre><pre class="cpp" name="code">
/**
 * <!--
 * File   : binarytree.h
 * Author : fancy
 * Email  : fancydeepin@yeah.net
 * Date   : 2013-02-03
 * --!>
 */
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <Stack>
#include <Queue>
using namespace std;
#define Element char
#define format "%c"

typedef struct Node {
    Element data;
    struct Node *lchild;
    struct Node *rchild;
} *Tree;

int index = 0;  //全局索引变量

//二叉树构造器,按先序遍历顺序构造二叉树
//无左子树或右子树用'#'表示
void treeNodeConstructor(Tree &root, Element data[]){
    Element e = data[index++];
    if(e == '#'){
        root = NULL;
    }else{
        root = (Node *)malloc(sizeof(Node));
        root->data = e;
        treeNodeConstructor(root->lchild, data);  //递归构建左子树
        treeNodeConstructor(root->rchild, data);  //递归构建右子树
    }
}

//深度优先遍历
void depthFirstSearch(Tree root){
    stack<Node *> nodeStack;  //使用C++的STL标准模板库
    nodeStack.push(root);
    Node *node;
    while(!nodeStack.empty()){
        node = nodeStack.top();
        printf(format, node->data);  //遍历根结点
        nodeStack.pop();
        if(node->rchild){
            nodeStack.push(node->rchild);  //先将右子树压栈
        }
        if(node->lchild){
            nodeStack.push(node->lchild);  //再将左子树压栈
        }
    }
}

//广度优先遍历
void breadthFirstSearch(Tree root){
    queue<Node *> nodeQueue;  //使用C++的STL标准模板库
    nodeQueue.push(root);
    Node *node;
    while(!nodeQueue.empty()){
        node = nodeQueue.front();
        nodeQueue.pop();
        printf(format, node->data);
        if(node->lchild){
            nodeQueue.push(node->lchild);  //先将左子树入队
        }
        if(node->rchild){
            nodeQueue.push(node->rchild);  //再将右子树入队
        }
    }
}
  


广度优先遍历:

//广度优先遍历
void breadthFirstSearch(Tree root){
    queue<Node *> nodeQueue;  //使用C++的STL标准模板库
    nodeQueue.push(root);
    Node *node;
    while(!nodeQueue.empty()){
        node = nodeQueue.front();
        nodeQueue.pop();
        printf(format, node->data);
        if(node->lchild){
            nodeQueue.push(node->lchild);  //先将左子树入队
        }
        if(node->rchild){
            nodeQueue.push(node->rchild);  //再将右子树入队
        }
    }
}

完整代码:

时间: 2024-09-14 09:48:24

【编程练习】复习一下树的遍历的相关文章

树的遍历

之前的工作都没有接触到树,也就很少研究它.幸运地的是,在目前的工作中多次遇到树型结构的数据,那么访问树节点中的数据就是必然的了,而且还需要按照指定规则对节点中的数据进行额外处理.经过学习之后,对与树相关的基本算法有了一些认知,就计划写几篇小文.其实这样的文章早已是汗牛充栋,而我只是把它当作我的学习总结罢了,以加深记忆与理解,如能对其他朋友有所助益,则更感愉悦了 :-) (2009.04.01最后更新) 这次先从最基础的开始--树的遍历.本文使用了两种极常用的方法来遍历树中的所有节点--递归:迭代

c#扩展方法奇思妙用高级篇七:“树”通用遍历器

先看一个简单的类People(将作为测试用的例子): 1 public abstract class People 2 { 3 public bool IsMale { get; private set; } 4 public abstract IEnumerable<People> Children { get; } 5 } People类有一个Children属性,返回该People的所有孩子.People类通过Children属性最终可形成一个People树. "树"

mfc-MFC的CTreeView的树的遍历

问题描述 MFC的CTreeView的树的遍历 我在 CTreeView 的 OnInitialUpdate() 函数中写的插入树节点的代码 CTreeCtrl & TCtrl = GetTreeCtrl(); TCtrl.ModifyStyle(0,TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT); HTREEITEM father = TCtrl.InsertItem(_T("日常消费")); m_HTree[0] = TCtrl.I

树的存储-树的遍历与计数中运用队列来实现

问题描述 树的遍历与计数中运用队列来实现 #include #include #include #include #define MAX_TREE_SIZE 100 #define TElemType int #define QElemType int #define Status int #define OVERFLOW -2 #define OK 1 #define ERROR 0 typedef struct BiTNode//结点结构 { QElemType data; int pare

树的遍历与图的遍历

研发时候,不要受原来的术语的影响,其实就是想着原来学过的或者看过的可以解决新遇到的问题,这其实是侥幸心理,忘记原来的术语吧,那只是你创新的源泉. 遍历就是把节点按一定规则构成一个线性序列,不同的规则得到不同顺序的线性序列,仅此而已 . 算法是实际问题工作步骤的抽象,不要一味想算法,想想实际情况怎么做的,然后提取算法,然后优化. 不论怎样,要和具体的数据结构结合在一起. 一.树的遍历 对于树的遍历,有三种,就拿前序遍历来说,得到的序列不论怎么拆分(子串,就是要连续),始 终要是根左右,跟在左右前面

数据结构~树的遍历(Service层和UI层代码)

问题是这样的,Department表是一个部门表,由DeptId,name和Father组成,它是一种树型的关系,一个部门下可以有多个子部门,同时,它有一个父部门,祖宗部门没有父部门. 以下是测试数据(相当于Data层里取出数据的方法): static List<Department> deptList = new List<Department> { new Department(1,"根",0), new Department(2,"计算机&quo

二叉搜索树与树的遍历非递归练习

复习了二叉搜索树的实现,包括插入.查找和删除操作,顺便做了下二叉树的三种遍历操作.全部操作采用非递归方式.   #include<iostream>   #include<stack>   using namespace std;     typedef int T;   // 值类型      // 节点定义    struct node {       T val;       node *left,*right;       node(const T& val):va

JSP编译成Servlet(二)语法树的遍历——访问者模式

语法树可以理解成是一种数据结构,假如某些语句已经被解析成一棵语法树,那么接下来就是要对此语法树进行处理,但考虑到不将处理操作与数据结构混合在一块,我们需要一种方法将其分离.其实对于语法树的处理最典型的处理模式就是访问者模式,它能很好的将数据结构与处理分离,提供了很好的解耦作用,让我们可以在生成语法树的过程只需关注如何构建相关的数据结构,而在对语法树处理的时候只需关注处理的逻辑,是一种非常巧的设计模式,接下来通过一个简单的代码案例看看如何实现一个访问者模式. ①定义访问者操作方法接口,声明所有访问

积累的VC编程小技巧之树操作

1.如何在TreeList中加图标?   [问题提出]  请问treeview控件和treectrl控件的用法有何不同呢?向如何imagelist控件中加图象呀?  [解决方法]  1)    HICON hicon[8];    m_imageList.Create(16,16,0,8,8);    hicon[0]=AfxGetApp()->LoadIcon(IDI_ICON0);    hicon[1]=AfxGetApp()->LoadIcon(IDI_ICON1);    hicon