zoukankan      html  css  js  c++  java
  • 摘录

    分类: C/C++

    树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的系统的访问,即依次对树中每个结点访问一 次且仅访问一次。树的3种最重要的遍历方式分别称为前序遍历、中序遍历和后序遍历。以这3种方式遍历一棵树时,若按访问结点的先后次序将结点排列起来,就 可分别得到树中所有结点的前序列表,中序列表和后序列表。相应的结点次序分别称为结点的前序、中序和后序。
     
    数据结构里, 
    就是对一棵二叉树所有结点的访问 
    前序遵循“根左右” 
    中序遵循“左根右” 
    后序遵循“左右根” 
    根:根节点 
    左:左子女 
    右:右子女 
    如:一棵二叉树 : 

    /  
    B C 
    /  
    D E 
    前序访问顺序就是:ABDEC(根一定第一个) 
    中序访问顺序就是:DBEAC(根一定在中间) 
    后序访问顺序就是:DEBCA(根一定在最后)


    #include 
    #include 
    #define STACK_MAX_SIZE 30 
    #define QUEUE_MAX_SIZE 30 
    #ifndef elemType 
    typedef char elemType; 
    #endif 
    /************************************************************************/ 
    /* 以下是关于二叉树操作的11个简单算法 */ 
    /************************************************************************/ 
    struct BTreeNode{ 
    elemType data; 
    struct BTreeNode *left; 
    struct BTreeNode *right; 
    }; 

    /* 1.初始化二叉树 */ 
    void initBTree(struct BTreeNode* *bt) 

    *bt = NULL; 
    return; 


    /* 2.建立二叉树(根据a所指向的二叉树广义表字符串建立) */ 
    void createBTree(struct BTreeNode* *bt, char *a) 

    struct BTreeNode *p; 
    struct BTreeNode *s[STACK_MAX_SIZE];/* 定义s数组为存储根结点指针的栈使用 */ 
    int top = -1; /* 定义top作为s栈的栈顶指针,初值为-1,表示空栈 */ 
    int k; /* 用k作为处理结点的左子树和右子树,k = 1处理左子树,k = 2处理右子树 */ 
    int i = 0; /* 用i扫描数组a中存储的二叉树广义表字符串,初值为0 */ 
    *bt = NULL; /* 把树根指针置为空,即从空树开始建立二叉树 */ 
    /* 每循环一次处理一个字符,直到扫描到字符串结束符为止 */ 
    while(a[i] != ''){ 
    switch(a[i]){ 
    case ' ': 
    break; /* 对空格不作任何处理 */ 
    case '(': 
    if(top == STACK_MAX_SIZE - 1){ 
    printf("栈空间太小!n"); 
    exit(1); 

    top++; 
    s[top] = p; 
    k = 1; 
    break; 
    case ')': 
    if(top == -1){ 
    printf("二叉树广义表字符串错误!n"); 
    exit(1); 

    top--; 
    break; 
    case ',': 
    k = 2; 
    break; 
    default: 
    p = malloc(sizeof(struct BTreeNode)); 
    p->data = a[i]; 
    p->left = p->right = NULL; 
    if(*bt == NULL){ 
    *bt = p; 
    }else{ 
    if( k == 1){ 
    s[top]->left = p; 
    }else{ 
    s[top]->right = p; 



    i++; /* 为扫描下一个字符修改i值 */ 

    return; 


    /* 3.检查二叉树是否为空,为空则返回1,否则返回0 */ 
    int emptyBTree(struct BTreeNode *bt) 

    if(bt == NULL){ 
    return 1; 
    }else{ 
    return 0; 



    /* 4.求二叉树深度 */ 
    int BTreeDepth(struct BTreeNode *bt) 

    if(bt == NULL){ 
    return 0; /* 对于空树,返回0结束递归 */ 
    }else{ 
    int dep1 = BTreeDepth(bt->left); /* 计算左子树的深度 */ 
    int dep2 = BTreeDepth(bt->right); /* 计算右子树的深度 */ 
    if(dep1 > dep2){ 
    return dep1 + 1; 
    }else{ 
    return dep2 + 1; 




    /* 5.从二叉树中查找值为x的结点,若存在则返回元素存储位置,否则返回空值 */ 
    elemType *findBTree(struct BTreeNode *bt, elemType x) 

    if(bt == NULL){ 
    return NULL; 
    }else{ 
    if(bt->data == x){ 
    return &(bt->data); 
    }else{ /* 分别向左右子树递归查找 */ 
    elemType *p; 
    if(p = findBTree(bt->left, x)){ 
    return p; 

    if(p = findBTree(bt->right, x)){ 
    return p; 

    return NULL; 




    /* 6.输出二叉树(前序遍历) */ 
    void printBTree(struct BTreeNode *bt) 

    /* 树为空时结束递归,否则执行如下操作 */ 
    if(bt != NULL){ 
    printf("%c", bt->data); /* 输出根结点的值 */ 
    if(bt->left != NULL || bt->right != NULL){ 
    printf("("); 
    printBTree(bt->left); 
    if(bt->right != NULL){ 
    printf(","); 

    printBTree(bt->right); 
    printf(")"); 


    return; 


    /* 7.清除二叉树,使之变为一棵空树 */ 
    void clearBTree(struct BTreeNode* *bt) 

    if(*bt != NULL){ 
    clearBTree(&((*bt)->left)); 
    clearBTree(&((*bt)->right)); 
    free(*bt); 
    *bt = NULL; 

    return; 


    /* 8.前序遍历 */ 
    void preOrder(struct BTreeNode *bt) 

    if(bt != NULL){ 
    printf("%c ", bt->data); /* 访问根结点 */ 
    preOrder(bt->left); /* 前序遍历左子树 */ 
    preOrder(bt->right); /* 前序遍历右子树 */ 

    return; 



    /* 9.中序遍历 */ 
    void inOrder(struct BTreeNode *bt) 

    if(bt != NULL){ 
    inOrder(bt->left); /* 中序遍历左子树 */ 
    printf("%c ", bt->data); /* 访问根结点 */ 
    inOrder(bt->right); /* 中序遍历右子树 */ 

    return; 


    /* 10.后序遍历 */ 
    void postOrder(struct BTreeNode *bt) 

    if(bt != NULL){ 
    postOrder(bt->left); /* 后序遍历左子树 */ 
    postOrder(bt->right); /* 后序遍历右子树 */ 
    printf("%c ", bt->data); /* 访问根结点 */ 

    return; 


    /* 11.按层遍历 */ 
    void levelOrder(struct BTreeNode *bt) 

    struct BTreeNode *p; 
    struct BTreeNode *q[QUEUE_MAX_SIZE]; 
    int front = 0, rear = 0; 
    /* 将树根指针进队 */ 
    if(bt != NULL){ 
    rear = (rear + 1) % QUEUE_MAX_SIZE; 
    q[rear] = bt; 

    while(front != rear){ /* 队列非空 */ 
    front = (front + 1) % QUEUE_MAX_SIZE; /* 使队首指针指向队首元素 */ 
    p = q[front]; 
    printf("%c ", p->data); 
    /* 若结点存在左孩子,则左孩子结点指针进队 */ 
    if(p->left != NULL){ 
    rear = (rear + 1) % QUEUE_MAX_SIZE; 
    q[rear] = p->left; 

    /* 若结点存在右孩子,则右孩子结点指针进队 */ 
    if(p->right != NULL){ 
    rear = (rear + 1) % QUEUE_MAX_SIZE; 
    q[rear] = p->right; 


    return; 


    /************************************************************************/ 

    /* 
    int main(int argc, char *argv[]) 

    struct BTreeNode *bt; /* 指向二叉树根结点的指针 */ 
    char *b; /* 用于存入二叉树广义表的字符串 */ 
    elemType x, *px; 
    initBTree(&bt); 
    printf("输入二叉树广义表的字符串:n"); 
    /* scanf("%s", b); */ 
    b = "a(b(c), d(e(f, g), h(, i)))"; 
    createBTree(&bt, b); 
    if(bt != NULL) 
    printf(" %c ", bt->data); 
    printf("以广义表的形式输出:n"); 
    printBTree(bt); /* 以广义表的形式输出二叉树 */ 
    printf("n"); 
    printf("前序:"); /* 前序遍历 */ 
    preOrder(bt); 
    printf("n"); 
    printf("中序:"); /* 中序遍历 */ 
    inOrder(bt); 
    printf("n"); 
    printf("后序:"); /* 后序遍历 */ 
    postOrder(bt); 
    printf("n"); 
    printf("按层:"); /* 按层遍历 */ 
    levelOrder(bt); 
    printf("n"); 
    /* 从二叉树中查找一个元素结点 */ 
    printf("输入一个待查找的字符:n"); 
    scanf(" %c", &x); /* 格式串中的空格跳过空白字符 */ 
    px = findBTree(bt, x); 
    if(px){ 
    printf("查找成功:%cn", *px); 
    }else{ 
    printf("查找失败!n"); 

    printf("二叉树的深度为:"); 
    printf("%dn", BTreeDepth(bt)); 
    clearBTree(&bt); 
    return 0; 

    */
  • 相关阅读:
    各种筛法与莫比乌斯反演
    欧拉函数技巧与学习笔记
    莫比乌斯函数与欧拉函数的单个值的快速求法
    最短路算法总结
    NOI2018网络同步赛游记
    中国剩余定理及其扩展学习笔记
    构造方法的格式
    private关键字
    成员变量和局部变量的区别
    数据加密代码实现
  • 原文地址:https://www.cnblogs.com/annapolis/p/4739966.html
Copyright © 2011-2022 走看看