zoukankan      html  css  js  c++  java
  • 包含了四种遍历方法的 BST

    tree.h

    typedef int ElementType;
    
    /* START: fig4_16.txt */
    #ifndef _Tree_H
    #define _Tree_H
    
    struct TreeNode; // 定义结构体节点
    typedef struct TreeNode *Position; // 指向节点的指针
    typedef struct TreeNode *SearchTree; // 指针,表示搜索树,是搜索树的根节点
    
    SearchTree MakeEmpty( SearchTree T );
    Position Find( ElementType X, SearchTree T );
    Position FindMin( SearchTree T );
    Position FindMax( SearchTree T );
    SearchTree Insert( ElementType X, SearchTree T );
    SearchTree Delete( ElementType X, SearchTree T );
    ElementType Retrieve( Position P );
    
    /* 后增的树的遍历方法 */
    void PreOrderTraversal(SearchTree T);
    void InOrderTraversal(SearchTree T);
    void PostOrderTraversal(SearchTree T);
    void LevelOrderTraversal(SearchTree T);
    
    /* 后增的树的遍历方法 */
    
    #endif  /* _Tree_H */
    
    /* END */
    

    tree.c

    #include "tree.h"
    #include <stdlib.h>
    #include "fatal.h"
    #include "queueli.h"
    
    struct TreeNode
    {
        ElementType Element; // 树节点存储的元素
        SearchTree Left; // 左子树
        SearchTree Right; // 右子树
    };
    
    /* START: fig4_17.txt */
    // 建立一棵空树
    SearchTree
    MakeEmpty(SearchTree T)
    {
        if (T != NULL)
        {
            MakeEmpty(T->Left); // 递归删除左子树
            MakeEmpty(T->Right); // 递归删除右子树
            free(T); // 释放该节点
        }
        return NULL;
    }
    /* END */
    
    /* START: fig4_18.txt */
    // 二叉搜索树的查找操作
    Position
    Find(ElementType X, SearchTree T)
    {
        if (T == NULL)
            return NULL;
        if (X < T->Element) // 如果待查找元素比根节点小,那么递归查找左子树
            return Find(X, T->Left);
        else if (X > T->Element) // 如果待查找元素比根节点大,那么递归查找右子树
            return Find(X, T->Right);
        else
            return T;
    }
    /* END */
    
    /* START: fig4_19.txt */
    // 查找最小元素,即找出最左边的叶子节点
    Position
    FindMin(SearchTree T)
    {
        if (T == NULL)
            return NULL;
        else if (T->Left == NULL)
            return T;
        else
            return FindMin(T->Left);
    }
    /* END */
    
    /* START: fig4_20.txt */
    // 查找最大值
    Position
    FindMax(SearchTree T)
    {
        if (T != NULL)
            while (T->Right != NULL)
                T = T->Right;
    
        return T;
    }
    /* END */
    
    /* START: fig4_22.txt */
    // 插入操作
    SearchTree
    Insert(ElementType X, SearchTree T)
    {
    /* 1*/      if (T == NULL)
                {
            /* Create and return a one-node tree 创建并返回一个单节点树 */
    /* 2*/          T = malloc(sizeof(struct TreeNode));
    /* 3*/          if (T == NULL)
    /* 4*/              FatalError("Out of space!!!"); // 空间用尽的情况
                    else
                    {
    /* 5*/              T->Element = X; // 赋值
    /* 6*/              T->Left = T->Right = NULL; // 左右子树置空
                    }
                } else
    /* 7*/      if (X < T->Element)
    /* 8*/          T->Left = Insert(X, T->Left); // 递归寻找合适的插入位置
                else
    /* 9*/      if (X > T->Element)
    /*10*/          T->Right = Insert(X, T->Right);
                /* Else X is in the tree already; we'll do nothing */
    
    /*11*/      return T;  /* Do not forget this line!! */
    }
    /* END */
    
    /* START: fig4_25.txt */
    // 删除操作
    SearchTree
    Delete(ElementType X, SearchTree T)
    {
        Position TmpCell;
    
        // 寻找节点
        if (T == NULL)
            Error("Element not found");
        else if (X < T->Element)  /* Go left */
            T->Left = Delete(X, T->Left);
        else if (X > T->Element)  /* Go right */
            T->Right = Delete(X, T->Right);
        else  /* Found element to be deleted 找到了该删除的节点 */
        {
            if (T->Left && T->Right)  /* Two children 有两个孩子 */
            {
                /* Replace with smallest in right subtree 用右子树中最小的节点进行替换 */
                TmpCell = FindMin(T->Right); // 找出右子树中最小的节点
                T->Element = TmpCell->Element; // 替换
                T->Right = Delete(T->Element, T->Right); // 删除刚刚的那个在右子树中最小的节点
            } else  /* One or zero children 有 1 个或者 0 个孩子 */
            {
                TmpCell = T;
                if (T->Left == NULL) /* Also handles 0 children */
                    T = T->Right; // 如果左子树为空,那么将 T 更新为右子树,下同
                else if (T->Right == NULL)
                    T = T->Left;
                free(TmpCell); // 释放原来的 T 节点
            }
        }
    
    
        return T;
    }
    
    /* END */
    
    // 取出 Position P 中的元素
    ElementType
    Retrieve(Position P)
    {
        return P->Element;
    }
    
    /* 后增方法 */
    // 先序
    void PreOrderTraversal(SearchTree T)
    {
        if (T) {
            printf("%d ", T->Element);
            PreOrderTraversal(T->Left);
            PreOrderTraversal(T->Right);
        }
    }
    
    // 中序
    void InOrderTraversal(SearchTree T) {
        if (T) {
            InOrderTraversal(T->Left);
            printf("%d ", T->Element);
            InOrderTraversal(T->Right);
        }
    }
    
    // 后序
    void PostOrderTraversal(SearchTree T) {
        if (T) {
            PostOrderTraversal(T->Left);
            PostOrderTraversal(T->Right);
            printf("%d ", T->Element);
        }
    }
    
    // 层序
    void LevelOrderTraversal(SearchTree T) {
        Queue Q;
        SearchTree ST;
        if (!T) return; /* 如果是空树就直接返回 */
        Q = CreateQueue();
        Enqueue(T, Q); /* 将根节点入队 */
        while (!IsEmpty(Q)) {
            ST = FrontAndDequeue(Q);
            printf("%d ", ST->Element); /* 访问取出队列的节点 */
            if (ST->Left) Enqueue(ST->Left, Q);
            if (ST->Right) Enqueue(ST->Right, Q);
        }
    }
    
    /* 后增方法 */
    

    queueli.h

    这个队列是用来辅助树的层序遍历的

    #include "tree.h"
    
    typedef Position ElementType1;
    
    /* START: fig3_57.txt */
    #ifndef _Queueli_h
    #define _Queueli_h
    
    struct Node;
    struct QNode;
    typedef struct Node *PtrToNode; // 指向Node节点的指针
    typedef struct QNode *Queue; // 队列头,也是指向QNode节点的指针
    
    int IsEmpty(Queue Q);
    
    Queue CreateQueue(void);
    
    void DisposeQueue(Queue Q);
    
    void MakeEmpty1(Queue Q);
    
    void Enqueue(ElementType1 X, Queue Q);
    
    ElementType1 Front(Queue Q);
    
    void Dequeue(Queue Q);
    
    ElementType1 FrontAndDequeue(Queue Q);
    
    #endif  /* _Queue_h */
    /* END */
    

    queueli.c

    #include "queueli.h"
    #include "fatal.h"
    #include <stdio.h>
    // #include "tree.h"
    
    // 节点
    struct Node
    {
        ElementType1 Element;
        PtrToNode Next;
    };
    
    struct QNode
    {
        PtrToNode rear; // 指向队尾节点
        PtrToNode front; // 指向对头节点
    };
    
    // 判断队列是否为空
    int IsEmpty(Queue Q)
    {
        return (Q->front == NULL);
    }
    
    Queue CreateQueue(void)
    {
        Queue Q;
        Q = malloc(sizeof(struct QNode));
        if (Q == NULL)
            FatalError("Out of space!!!"); // 空间用尽警告
        Q->front = NULL;
        Q->rear = NULL;
        MakeEmpty1(Q); // 还是感觉有些多此一举
        return Q;
    }
    
    // 创建一个空队列
    void MakeEmpty1(Queue Q)
    {
        if (Q == NULL)
            Error("Must use CreateQueue first");
        else
            while (!IsEmpty(Q))
                Dequeue(Q);
    }
    
    // 清除队列
    void DisposeQueue(Queue Q)
    {
        if (Q != NULL)
        {
            MakeEmpty1(Q);
            free(Q);
        }
    }
    
    // 入队操作
    void Enqueue(ElementType1 X, Queue Q)
    {
        PtrToNode TmpCell;
    
        TmpCell = malloc(sizeof(struct Node));
        if (TmpCell == NULL)
            FatalError("Out of space!!!");
        TmpCell->Element = X;
        TmpCell->Next = NULL;
        if (Q->rear == NULL)
        { // 此时队列为空
            Q->rear = TmpCell;
            Q->front = TmpCell;
        } else { // 不为空
            Q->rear->Next = TmpCell; // 将节点入队
            Q->rear = TmpCell; // rear 仍然保持最后
        }
    }
    
    // 取出队首元素
    ElementType1 Front(Queue Q)
    {
        if (!IsEmpty(Q))
            return Q->front->Element;
        Error("Empty queue");
        return NULL; // Return value used to avoid warning
    }
    
    // 出队操作
    void Dequeue(Queue Q)
    {
        PtrToNode FrontCell;
        if (IsEmpty(Q))
            Error("Empty queue");
        else
        {
            FrontCell = Q->front;
            if (Q->front == Q->rear) { // 只有一个元素
                Q->front = Q->rear = NULL;
            } else { // 有多个元素时
                Q->front = Q->front -> Next; // 先将front指向队首元素的下一个元素
            }
            free(FrontCell); // 不要忘了释放出对的节点
        }
    }
    
    // 在出队的同时返回该元素,即队首元素
    ElementType1 FrontAndDequeue(Queue Q)
    {
        ElementType1 X = NULL;
    
        if (IsEmpty(Q))
            Error("Empty queue");
        else
        {
            X = Front(Q);
            Dequeue(Q);
        }
        return X;
    }
    

    main.c(测试函数)

    #include "tree.h"
    #include <stdio.h>
    
    int main( )
    {
        SearchTree T;
        Position P;
        int i;
        int j = 15;
    
        T = MakeEmpty( NULL ); // 创建一棵空树
        for( i = 0; i < 50; i++, j = ( j + 7 ) % 50 ) // 将 50 个数插入树中
            T = Insert( j, T );
        for( i = 0; i < 50; i++ )
            if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i ) // 测试查找函数
                printf( "Error at %d
    ", i );
    
        /* 测试遍历 */
        printf("先序遍历 
    ");
        PreOrderTraversal(T);
        printf("
    ");
        printf("中序遍历 
    ");
        InOrderTraversal(T);
        printf("
    ");
        printf("后序遍历 
    ");
        PostOrderTraversal(T);
        printf("
    ");
        printf("层序遍历 
    ");
        LevelOrderTraversal(T);
        printf("
    ");
    
        /* 测试遍历 */
    
        for( i = 0; i < 50; i += 2 )
            T = Delete( i, T ); // 以 1 为步长,作删除操作
    
        // 测试删除操作是否成功
        for( i = 1; i < 50; i += 2 )
            if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
                printf( "Error at %d
    ", i );
        for( i = 0; i < 50; i += 2 )
            if( ( P = Find( i, T ) ) != NULL )
                printf( "Error at %d
    ", i );
    
        // 打印最大数和最小数
        printf( "Min is %d, Max is %d
    ", Retrieve( FindMin( T ) ),
                Retrieve( FindMax( T ) ) );
    
        return 0;
    }
    

    fatal.h(定义错误的函数)

    #include <stdio.h>
    #include <stdlib.h>
    
    #define Error(Str)        FatalError( Str )
    #define FatalError(Str)   fprintf( stderr, "%s
    ", Str ), exit( 1 )
    
  • 相关阅读:
    区别TPS QPS HPS RPS PV UV
    C/C++常用库及工具
    CentOS常用命令备忘
    PHP的学习--Traits新特性
    CentOS7创建本地YUM源的三种方法
    CentOS下iptables详解
    Linux备份压缩命令
    Nginx HTTPS功能部署实践
    Fuel 30 分钟快速安装OpenStack
    hadoop学习通过虚拟机安装hadoop完全分布式集群
  • 原文地址:https://www.cnblogs.com/fanlumaster/p/13833330.html
Copyright © 2011-2022 走看看