二叉搜索树的数组实现

来源:互联网 发布:php跨域访问 编辑:程序博客网 时间:2024/05/17 01:25

tree.h:

/*

** 二叉搜索树模块的接口

*/

// 树的元素的类型.

#define TREE_TYPE  int 

 

// --------------------------外部接口-------------------------------

// 向树添加一个新值,参数是需要被添加的值,它必须原先并不存在于树中

void insert( TREE_TYPE value );

 

// 查找一个特定的值,函数返回该值的指针.

TREE_TYPE *find( TREE_TYPE value );

 

// 执行树的前序遍历,它的参数是一个回调函数指针,它所指向的函数将在

// 树中处理每个结点时被调用,结点的值作为参数传递给这个函数.

void pre_order_traverse( void (*callback)(TREE_TYPE value) );

 

// 执行树的中序遍历,它的参数是一个回调函数指针,它所指向的函数将在

// 树中处理每个结点时被调用,结点的值作为参数传递给这个函数.

void mid_order_traverse( void (*callback)(TREE_TYPE value) );

 

// 执行树的后序遍历,它的参数是一个回调函数指针,它所指向的函数将在

// 树中处理每个结点时被调用,结点的值作为参数传递给这个函数.

void back_order_traverse( void (*callback)(TREE_TYPE value) );

 

// --------------------------外部接口-------------------------------

 

// 临时函数

void treeprint();

 

tree.c:

/*

** 使用静态数组实现二叉搜索树

*/

#include "tree.h"

#include <assert.h>

#include <stdio.h>

 

#define TREE_SIZE 100

#define ARRAY_SIZE (TREE_SIZE + 1)

 

static TREE_TYPE tree[ARRAY_SIZE];

 

//计算左孩子的下标

static int left_child(int current)

{

       return current * 2;

}

 

//计算右孩子的下标

static int right_child(int current)

{

       return current * 2 + 1;

}

 

void insert(TREE_TYPE value)

{

       int current;

 

       //确保值非0,因为0用于提示一个未使用的节点

       assert(value != 0);

 

       //从根节点开始

       current = 1;

 

       //从合适的子树开始,直到到达一个叶节点

       while(tree[current] != 0)

       {

              if(value < tree[current])

              {

                     current = left_child(current);

              }

              else

              {

                     assert(value != tree[current]);

                     current = right_child(current);

              }

              assert(current < ARRAY_SIZE);

       }

 

       tree[current] = value;

}

 

TREE_TYPE *find(TREE_TYPE value)

{

       int current;

 

       //从根节点开始,直到找到那个值,进入合适的子树

       current = 1;

 

       while(current < ARRAY_SIZE && tree[current] != value)

       {

              //根据情况进入左子树或右子树

              if(value < tree[current])

              {

                     current = left_child(current);

              }

              else

              {

                     current = right_child(current);

              }

       }

      

       if(current < ARRAY_SIZE)

              return tree + current;

       else

              return 0;

}

 

//执行一层前序遍历,这个帮助函数用于保存我们当前正在处理的节点的信息

//它并不是用户接口的一部分

static void do_pre_order_traverse(int current, void (*callback)(TREE_TYPE value))

{

       if(current < ARRAY_SIZE && tree[current] != 0)

       {

              callback(tree[current]);

 

              do_pre_order_traverse(left_child(current), callback);

              do_pre_order_traverse(right_child(current), callback);

       }

}

 

// 执行一次中序遍历,这个帮助函数用于保存我们当前正在处理的节点的信息

// 它并不是用户接口的一部分

static void do_mid_order_traverse( int current, void (*callback)( TREE_TYPE value) )

{

    if( current < ARRAY_SIZE && tree[ current ] != 0)

    {

        do_mid_order_traverse( left_child(current), callback);

        callback( tree[ current ] );

        do_mid_order_traverse( right_child(current), callback);

    }

}

 

// 执行一次后序遍历,这个帮助函数用于保存我们当前正在处理的节点的信息

// 它并不是用户接口的一部分

static void do_back_order_traverse( int current, void (*callback)( TREE_TYPE value) )

{

    if( current < ARRAY_SIZE && tree[ current ] != 0)

    {

        do_back_order_traverse( left_child(current), callback);

        do_back_order_traverse( right_child(current), callback);

        callback( tree[ current ] );

    }

}

 

 

void pre_order_traverse(void (*callback)(TREE_TYPE value))

{

       do_pre_order_traverse(1, callback);

}

 

void mid_order_traverse( void (*callback)( TREE_TYPE value) )

{

    do_mid_order_traverse( 1, callback );

}

 

void back_order_traverse( void (*callback)( TREE_TYPE value) )

{

    do_back_order_traverse( 1, callback );

}

 

// 临时函数

void treeprint()

{

    int i;

      

       printf("打印数组……/n");

    for( i = 0; i< ARRAY_SIZE; i++)

    {

        printf("tree[%d]= %d    ", i, tree[ i ]);

 

        if( i % 5 == 0 )

        {

            printf("/n");

        }

    }

}

 

test.c:

#include "tree.h"

#include <stdio.h>

 

void my_callback(TREE_TYPE value)

{

       printf("%d  ", value);

}

 

void main()

{

       insert(20);

       insert(12);

       insert(25);

       insert(28);

       insert(26);

       insert(29);

       insert(5);

       insert(16);

       insert(9);

       insert(17);

 

       treeprint();

 

       printf("/n先序遍历:");

       pre_order_traverse(my_callback);

 

       printf("/n中序遍历:");

       mid_order_traverse(my_callback);

 

       printf("/n后序遍历:");

       back_order_traverse(my_callback);

 

       printf("/n/n");

}