数据结构实践原码--2--(参考书籍清华大学“数据结构”作者严尉敏)

实践二:
操作系统:中文WindowsXp
开发工具:VC7
语言:C
编写时间:20051011
完成时间:20051018
功能:对二叉树建立、添加、删除、遍历及销毁。

  • 二叉树实现原码下载地址

    源码如下:
    main.c
    #include  < stdio.h >
    #include 
    < stdlib.h >
    #include 
    " BianaryTree.h "
    #include 
    " OperJm.h "

    void  main ( void )
    {
        BiTree T 
    = NULL;    //二叉树根结点。

        
    if ( BiTreeEmpty (T) ) 
        
    {
            T 
    = InitBiTree (T);
            
    if (T != NULL)
            
    {
                
    do
                
    {
                    system (
    "cls");
                }
    while ( OperJm (&T) );
            }

        }

    }

    OperJm.h
    /*
        文件名称:OperJm.h
        文件内容:二叉树操作相关的人机界面函数声明。
        创建日期:20051012
        创建人:高玉涵
        创建地点:郑州
    */

    #define NUM_MAX    
    50        //数据最大数。

    Status OperJm (BiTree 
    *T);    //操作结果:显示一个操作菜单。返回用户输入的值。
    Status AddData (BiTree T);    //操作结果:添加数据。成功返回添加的结点数。
    void  PrintData (BiTree T);    //操作结果:打印结点数据域中的值。
    void  InputCheck (TElemType *check);    //
    OperJm.c
    /*
        文件名称:OperJm.c
        文件内容:二叉树操作相关的人机界面函数定义。
        创建日期:20051012
        创建人:高玉涵
        创建地点:郑州
    */

    #include 
    <stdio.h>
    #include 
    <stdlib.h>
    #include 
    <string.h>
    #include 
    "sjjg.h"
    #include 
    "BianaryTree.h"
    #include 
    "OperJm.h"

    int  g_nCount = 0;    //全局变量,存放递归的执行次数。

    Status OperJm (BiTree 
    * T)
    {
        
    /*
            操作结果:显示一个操作菜单。返回用户输入的值。
        
    */

        
    int value;            /* 选项值 */
        
    int pos;            //结点位置信息。
        TElemType check;    //查找值。
        BiTree BTreturn = NULL;    //返回结点的值。
        BiTree bt = NULL;

        printf (
    " -------二叉树二叉链表结构实现----- "
    );
        printf (
    " | 1.添加数据。 | "
    );
        printf (
    " | 3.删除一项记录。 | "
    );
        printf (
    " | 4.先序遍历结点。 | "
    );
        printf (
    " | 5.中序遍历结点。 | "
    );
        printf (
    " | 6.后序遍历结点。 | "
    );
        printf (
    " | 7.查找数据。 | "
    );
        printf (
    " | 0.退出。 | "
    );
        printf (
    " --------------------------------- "
    );
        printf (
    " 请选择:"
    );
        
        fflush(stdin);    
    /* 清除键盘缓冲区。(在ANIS C中此函数对输入流操作,
                            其结果是未定义的,一般是起到清空缓冲区的作用。
                            这根据所使用的编辑器有关,所以特别声明。
                        
    */

        scanf (
    "%d"&value);    /* 获取输入的值 */
        
        
    switch( value )
        
    {
            
    case 1
    :
                printf ( 
    "成功的添加了%d个数据。", AddData (*
    T) );
                system (
    "pause"
    );
                
    break
    ;
            
    case 3
    :
                InputCheck (
    &check);    //校验用户输入的值。

                if ( check != ' ' || check != EOF || check != '
    sjjg.h
    /*
        文件名称:sjjg.h
        文件内容:自己定义的一些新的数据类型(参考<<数据结构>>严尉敏)。
        创建日期:20051011
        创建人:高玉涵
    */

    #define TRUE    
    1
    #define FALSE    
    0
    #define OK        
    1
    #define ERROR    
    0
    #define INFEASIBLE    
    -1    //不可实行的。
    #define OVERFLOW    -2    //溢值。
    typedef int Status;    //是函数的类型,其值是函数结果状态代码。

    /*
        说明:
            i        为循环计数器。
            iCout    累加计数器(多用于返回函数的执行结果值)。
    */
    BianaryTree.h
    /*
        文件名称:BianaryTree.h
        文件内容:二叉树操作相关的函数声明。
        创建日期:20051011
        创建人:高玉涵
        创建地点:郑州
    */

    #include 
    " sjjg.h "

    typedef 
    char  TElemType;     // 树中数据域的类型。

    typedef struct BiTNode    
    // 二叉树的二叉链表存储表示。
    {
        TElemType data;
        struct BiTNode 
    *lchild;    //左子树。
        struct BiTNode *rchild;    //右子树。
    }
    BiTNode;

    typedef BiTNode 
    * BiTree;

    // 下面是对二叉树操作相关的函数。
    BiTree InitBiTree (BiTree T);     // 操作结果:构造空二叉树T。成功返回地址,否则返回NULL。
    Status BiTreeEmpty ( const  BiTree T);     // 操作结果:若T为空二叉树,则返回TRUE,否则FALSE。
    Status CreateBiTree (BiTree T,  char  definition);     // 操作结果:按definition构造二叉树。成功返回TRUE,否则FALSE。
    void  EmpressPreface ( const  BiTree T,  void  ( * opter) (BiTree T));     // 操作结果:后序遍历二叉树T。对每个结点调用函数opter。
    void  DestroyBiTree (BiTree T);     // 操作结果:销毁二叉树。
    void  FirstPreface ( const  BiTree T,  void  ( * opter) (BiTree T));     // 操作结果:先序遍历T,对每个结点调用函数opter。
    void  MediumPreface ( const  BiTree T,  void  ( * opter) (BiTree T));     // 操作结果:中序遍历T,对每个结点调用函数opter。
    BiTree SearchBiTree ( const  BiTree T, TElemType e,  int   * position); // 操作结果:二叉树二分查找e指定的值。成功返回地址及所属结点位置信息,否则NULL。
    Status DeleteNode (BiTree T, BiTree  * parent, TElemType e,  int   * position, BiTree ( * opter) ( const  BiTree T, TElemType e,  int   * position) );
    BiTree Parent (
    const  BiTree T, TElemType e);     // 操作结果:若e是T的非根结点,则返回它的双亲,否则返回NULL。
    BianaryTree.c
    /*
        文件名称:BianaryTree.c
        文件内容:二叉树操作相关的函数定义。
        创建日期:20051011
        完成日期:20051018
        创建人:高玉涵
        创建地点:郑州
    */

    #include 
    < stdio.h >
    #include 
    < stdlib.h >
    #include 
    " BianaryTree.h "

    BiTree InitBiTree (BiTree T)
    {
        
    /*
            操作结果:构造空二叉树T。成功返回地址,否则返回NULL。
        
    */

        
    if (T == NULL)    //二叉树为空树时。
        {
            T 
    = (BiTree) malloc (sizeof(BiTNode));
            
    if (T == NULL)    return NULL;    //存储空间分配失败。
            T->data = NULL;
            T
    ->lchild = NULL;
            T
    ->rchild = NULL;
            
    return T;
        }

        
    return NULL;
    }

    Status BiTreeEmpty (
    const  BiTree T)
    {
        
    /*
            初始条件:二叉树T存在。
            操作结果:若T为空二叉树,则返回TRUE,否则FALSE。
        
    */

        
    if (T == NULL) return TRUE;    //二叉树为空。
        return ERROR;
    }

    Status CreateBiTree (BiTree T, TElemType definition)
    {
        
    /*
            初始条件:definition给出二叉树T的定义。
            操作结果:按definition构造二叉树。成功返回TRUE,否则FALSE。
        
    */

        BiTree NewNode;            
    //新结点指针。
        BiTree CurrentNode;        //当前结点指针。
        BiTree ParentNode;        //父结点指针。
        
        
    if ( (T->data == NULL) )//当二叉树只有一个根结点且数据域未赋值。
        {
            T
    ->data = definition;
            
    return TRUE;
        }


        
    //创建新结点。
        NewNode = (BiTree) malloc (sizeof(BiTNode));
        
    if (NewNode == NULL) return ERROR;        //存储空间分配失败。

        NewNode
    ->data = definition;    //将definition中的数据复制到新结点中。
        NewNode->lchild = NULL;
        NewNode
    ->rchild = NULL;

        CurrentNode 
    = T;

        
    while (CurrentNode != NULL)
        
    {
            ParentNode 
    = CurrentNode;    //存储父结点指针。
            if (CurrentNode->data > NewNode->data)
            
    {
                CurrentNode 
    = CurrentNode->lchild;
            }

            
    else
            
    {
                CurrentNode 
    = CurrentNode->rchild;
            }

        }


        
    if (ParentNode->data > NewNode->data )
        
    {
            ParentNode
    ->lchild = NewNode;
        }

        
    else
        
    {
            ParentNode
    ->rchild = NewNode;
        }

        
    return TRUE;
    }

    void  DestroyBiTree (BiTree T)
    {
        
    /*
            初始条件:二叉树T存在。
            操作结果:销毁二叉树。
        
    */

        free (T);    
    //释放占用的资源。
        T = NULL;    //赋NULL值。
    }

    void  EmpressPreface ( const  BiTree T,  void  ( * opter) (BiTree T))
    {
        
    /*
            初始条件:二叉树T存在。
            操作结果:后序遍历二叉树T。对每个结点调用函数opter。
        
    */

        extern 
    int g_nCount;    //访问外部变量。

        
    if (T != NULL)
        
    {
            g_nCount
    ++;    //计数。
            EmpressPreface (T->lchild, opter);    //处理左子树。
            EmpressPreface (T->rchild, opter);    //处理右子树。
            opter (T);
        }

    }

    void  FirstPreface ( const  BiTree T,  void  ( * opter) (BiTree T))
    {
        
    /*
            初始条件:二叉树T存在。
            操作结果:先序遍历T,对每个结点调用函数opter。
        
    */

        extern 
    int g_nCount;    //访问外部变量。

        
    if (T != NULL)
        
    {
            g_nCount
    ++;    //计数。
            opter (T);
            FirstPreface (T
    ->lchild, opter);
            FirstPreface (T
    ->rchild, opter);
        }

    }

    void  MediumPreface ( const  BiTree T,  void  ( * opter) (BiTree T))
    {
        
    /*
            初始条件:二叉树T存在。
            操作结果:中序遍历T,对每个结点调用函数opter。
        
    */

        extern 
    int g_nCount;    //访问外部变量。

        
    if (T != NULL)
        
    {
            g_nCount
    ++;    //计数。
            MediumPreface (T->lchild, opter);
            opter (T);
            MediumPreface (T
    ->rchild, opter);
        }

    }

    BiTree SearchBiTree (
    const  BiTree T, TElemType e,  int   * position)
    {
        
    /*
            初始条件:二叉树T存在。
            操作结果:二叉树二分查找e指定的值。成功返回地址及所属结点位置信息,否则NULL。
        
    */

        BiTree point;        
    //当前结点。

        point 
    = T;
        
    *position = 0;        //初始位置信息。0=根,-1=左子树,1=右子树。

        
    while (point != NULL)
        
    {
            
    if (point->data == e)
            
    {
                
    return point;
            }

            
    else
            
    {
                
    if (point->data > e)
                
    {
                    point 
    = point->lchild;
                    
    *position = -1;    //左子树。
                }

                
    else
                
    {
                    point 
    = point->rchild;
                    
    *position = 1;    //右子树。
                }

            }

        }

        
    return NULL;
    }

    Status DeleteNode (BiTree T, BiTree 
    * RootNode, TElemType e,  int   * position, 
                       BiTree (
    * opter) ( const  BiTree T, TElemType e,  int   * position) )
    {
        
    /*
            初始条件:二叉树T存在,e指向中T中某个结点,pos为-1,0,1。
            操作结果:根据pos为-1,0,1,删除T中p所指结点。成功返回TRUE,否则FALSE。
        
    */

        BiTree parent 
    = NULL;    //父结点。
        BiTree point = NULL;    //欲删除结点。
        BiTree child = NULL;    //子结点指针。

        point 
    = opter (T, e, position);    //寻找欲删除结点的指针。
        parent = Parent (T, e);            //寻找欲删除结点的父结点(双亲)。

        
    if (point == NULL )    //该结点不在二叉树中。
        {
            
    return FALSE;
        }

        
    else
        
    {
            
    //没有左子树也没有右子树。
            if (point->lchild == NULL && point->rchild == NULL)
            
    {
                
    switch ( *position )    //判断删除位置。
                {
                
    case -1
                    (
    *RootNode)->lchild = NULL;    //将父结点的左指针指向NULL。
                    free (point);point = NULL;break;    //释放资源。
                case 1
                    (
    *RootNode)->rchild = NULL;//将父结点的右指针指向NULL。
                    free (point);point = NULL;break;    //释放资源。
                case 0
                    
    *RootNode = NULL;    //将父结点指向NULL。
                    free (point);point = NULL;break;    //释放资源。
                }

                
    return TRUE;
            }

            
    //没有左子树。
            if (point->lchild == NULL && point->rchild != NULL)
            
    {
                
    if (parent == NULL) parent = point;//说明parent与point都指的是root结点。

                
    if (parent != point)
                
    {
                    parent
    ->rchild = point->rchild;    //将父结点右指针->结点右指针。
                    free (point);point = NULL;    //释放资源。
                }

                
    else
                
    {
                    
    *RootNode = parent->rchild;    //将右指针地址赋给父结点。
                    
    //parent = parent->rchild;
                    free (point);point = NULL;    //释放资源。
                }

                
    return TRUE;
            }

            
    //没有右子树。
            else if (point->rchild == NULL && point->lchild != NULL)
            
    {
                
    if (parent == NULL) parent = point;//说明parent与point都指的是root结点。

                
    if (parent != point)
                
    {
                    parent
    ->lchild = point->lchild;    //将父结点右指针->结点右指针。
                    free (point);point = NULL;    //释放资源。
                }

                
    else
                
    {
                    
    *RootNode = parent->lchild;    //将右指针地址赋给父结点。
                    
    //parent = parent->lchild;    //将右指针地址赋给父结点。
                    free (point);point = NULL;    //释放资源。
                }

                
    return TRUE;
            }

            
    //有左子树也有右子树。
            else if (point->lchild != NULL && point->rchild != NULL)
            
    {
                parent 
    = point;            //将父结点指向目前结点。
                child = point->lchild;    //向左走设置子结点。

                
    while (child->rchild != NULL)//找左子树最右边的叶子节点。
                {
                    parent 
    = child;            //保留父结点指针。
                    child = child->rchild;    //往右子树前进。
                }


                point
    ->data = child->data;    //将原结点设置成叶结点数据值。

                
    if (parent->lchild == child)
                
    {
                    parent
    ->lchild = child->lchild;
                }

                
    else
                
    {
                    parent
    ->rchild = child->rchild;
                }

                free (child);child 
    = NULL;    //释放资源。
            }

            
    return FALSE;
        }

    }

    BiTree Parent (
    const  BiTree T, TElemType e)
    {
        
    /*
            初始条件:二叉树T存在,e是T中某个结点。
            操作结果:若e是T的非根结点,则返回它的双亲,否则返回NULL。
        
    */

        BiTree point;        
    //当前结点。
        BiTree parent;        //父结点(双亲结点)。

        parent 
    = T;
        point 
    = T;

        
    while (point != NULL)
        
    {
            
    if (point->data == e)
            
    {
                
    return (T == point? NULL: parent);
            }

            
    else
            
    {
                
    if (point->data > e)
                
    {
                    parent 
    = point;    //保留父结点。
                    point = point->lchild;
                }

                
    else
                
    {
                    parent 
    = point;
                    point 
    = point->rchild;
                }

            }

        }

        
    return NULL;
    }

    未完待续......

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值