二叉木の先序,中序,後序の非再帰遍歴(C言語実装)
1、順序スタックの宣言
2、順序スタックの実現
3、循環キューの宣言
4、循環行列の実現
5.後段遍歴のための順序スタックタイプ宣言
6、ツリータイプ宣言
7、二叉木実現
8、試験手順
#ifndef _seq_stack_h
#define _seq_stack_h
#include "binary_tree.h"
#define STACK_INIT_SIZE 5
#define STACK_INCR_SIZE 2
typedef bitree_node * stack_elem_type;
//typedef int stack_elem_type;
typedef struct seq_stack
{
stack_elem_type * base;
stack_elem_type * top;
int size;
}seq_stack;
void init_stack_sq( seq_stack * stack );
void free_stack_sq( seq_stack * stack );
stack_elem_type get_top_sq( seq_stack stack );
void pop_elem_sq( seq_stack * stack );
void push_elem_sq( seq_stack * stack, stack_elem_type e );
int stack_empty_sq( seq_stack stack );
int stack_length_sq( seq_stack stack );
void trav_stack_sq( seq_stack stack );
#endif
2、順序スタックの実現
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "seq_stack.h"
void init_stack_sq( seq_stack * stack )
{
stack->size = STACK_INIT_SIZE;
stack->base = stack->top = ( stack_elem_type * )malloc( STACK_INIT_SIZE * sizeof( stack_elem_type ) );
assert( stack->base != NULL );
}
void free_stack_sq( seq_stack * stack )
{
stack->size = 0;
free( stack->base );
stack->base= stack->top = NULL;
}
void push_elem_sq( seq_stack * stack, stack_elem_type e )
{
stack_elem_type * base = NULL, * p = NULL, * q = NULL;
if( stack->top - stack->base >= stack->size )
{
stack->size += STACK_INCR_SIZE;
base = ( stack_elem_type * )malloc( sizeof( stack_elem_type ) * stack->size );
assert( base != NULL );
p = base; q = stack->base;
while( q < stack->top )
*p++ = *q++;
free( stack->base );
stack->base = base;
stack->top = stack->base + ( stack->size - STACK_INCR_SIZE );
}
*stack->top++ = e;
}
stack_elem_type get_top_sq( seq_stack stack )
{
return stack_empty_sq( stack ) ? NULL : *( stack.top - 1 );
}
void pop_elem_sq( seq_stack * stack )
{
assert( stack->top > stack->base );
--stack->top;
}
int stack_length_sq( seq_stack stack )
{
return stack.top - stack.base;
}
int stack_empty_sq( seq_stack stack )
{
return stack.base == stack.top;
}
void trav_stack_sq( seq_stack stack )
{
stack_elem_type * p = stack.base;
while( p < stack.top )
printf( "%c ", (*p++)->data );
printf( "
" );
}
3、循環キューの宣言
#ifndef _circ_queue_h
#define _circ_queue_h
#include "binary_tree.h"
typedef bitree_node * queue_elem_type;
typedef struct circ_queue
{
queue_elem_type * buffer;
int front, rear;
int size;
}circ_queue;
void init_circ_queue( circ_queue * cq );
void clear_circ_queue( circ_queue * cq );
void free_circ_queue( circ_queue * cq );
void trav_circ_queue( circ_queue cq );
int push_elem_cq( circ_queue * cq, queue_elem_type e );
queue_elem_type get_front_elem_cq( circ_queue cq );
void pop_elem_cq( circ_queue * cq );
int circ_queue_length( circ_queue cq );
int circ_queue_empty( circ_queue cq );
#endif
4、循環行列の実現
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "circ_queue.h"
void init_circ_queue( circ_queue * cq )
{
cq->size = 10;
cq->buffer = ( queue_elem_type * )malloc( sizeof( queue_elem_type ) * cq->size );
assert( cq->buffer );
cq->front = cq->rear = 0;
}
void clear_circ_queue( circ_queue * cq )
{
cq->front = cq->rear = 0;
}
void free_circ_queue( circ_queue * cq )
{
cq->size = 0;
free( cq->buffer );
cq->front = cq->rear = 0;
}
int circ_queue_empty( circ_queue cq )
{
return cq.front == cq.rear;
}
int circ_queue_full( circ_queue cq )
{
return ( cq.rear + 1 ) % cq.size == cq.front;
}
void trav_circ_queue( circ_queue cq )
{
int i;
if( ! circ_queue_empty( cq ) )
{
i = cq.front;
while( i % cq.size != cq.rear )
{
printf( "%c ", cq.buffer[i++]->data );
}
}
}
int push_elem_cq( circ_queue * cq, queue_elem_type e )
{
int res = -1;
if( ! circ_queue_full( *cq ) )
{
cq->buffer[cq->rear++] = e;
cq->rear %= cq->size;
res = 0;
}
return res;
}
queue_elem_type get_front_elem_cq( circ_queue cq )
{
return circ_queue_empty( cq ) ? NULL : cq.buffer[cq.front];
}
void pop_elem_cq( circ_queue * cq )
{
assert( ! circ_queue_empty( *cq ) );
cq->front = ( cq->front + 1 ) % cq->size;
}
int circ_queue_length( circ_queue cq )
{
return ( cq.rear - cq.front + cq.size ) % cq.size;
}
5.後段遍歴のための順序スタックタイプ宣言
#ifndef _post_order_seq_stack_h
#define _post_order_seq_stack_h
#include "binary_tree.h"
#define STACK_INIT_SIZE 5
#define STACK_INCR_SIZE 2
typedef enum visit_flag
{
LR, RR
}visit_tag;
typedef struct po_stack_elem_type
{
bitree_node * ptr;
visit_tag tag;
}po_stack_elem_type;
typedef struct po_seq_stack
{
po_stack_elem_type * base;
po_stack_elem_type * top;
int size;
}po_seq_stack;
void init_stack_posq( po_seq_stack * stack );
void free_stack_posq( po_seq_stack * stack );
po_stack_elem_type get_top_posq( po_seq_stack stack );
void pop_elem_posq( po_seq_stack * stack );
void push_elem_posq( po_seq_stack * stack, po_stack_elem_type e );
int stack_empty_posq( po_seq_stack stack );
int stack_length_posq( po_seq_stack stack );
#endif
6、ツリータイプ宣言
#ifndef _binary_tree_h
#define _binary_tree_h
typedef char elem_type;
typedef struct bitree_node
{
elem_type data;
struct bitree_node * lchild, * rchild;
}bitree_node;
typedef bitree_node * binary_tree;
void create_bitree( binary_tree * root );
void free_bitree( binary_tree * root );
void trav_preorder( binary_tree root );
void trav_preorder_recur( binary_tree root );
void trav_inorder( binary_tree root );
void trav_inorder_recur( binary_tree root );
void trav_postorder( binary_tree root );
void trav_postorder_recur( binary_tree root );
void trav_level_order( binary_tree root );
#endif
7、二叉木実現
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "binary_tree.h"
#include "seq_stack.h"
#include "circ_queue.h"
#include "po_seq_stack.h"
void create_bitree( binary_tree * root )
{
char ch;
if( ( ch = getchar() ) == '#' )
{
*root = NULL;
}
else
{
*root = ( bitree_node * )malloc( sizeof( bitree_node ) );
( *root )->data = ch;
create_bitree( &( *root )->lchild );
create_bitree( &( *root )->rchild );
}
}
void free_bitree( binary_tree * root )
{
if( *root != NULL )
{
free_bitree( &( *root )->lchild );
free_bitree( &( *root )->rchild );
free( *root );
*root = NULL;
}
}
void trav_preorder_recur( binary_tree root )
{
if( root != NULL )
{
printf( "%c", root->data );
trav_preorder_recur( root->lchild );
trav_preorder_recur( root->rchild );
}
}
void trav_inorder_recur( binary_tree root )
{
if( root != NULL )
{
trav_inorder_recur( root->lchild );
printf( "%c ", root->data );
trav_inorder_recur( root->rchild );
}
}
void trav_postorder_recur( binary_tree root )
{
if( root != NULL )
{
trav_postorder_recur( root->lchild );
trav_postorder_recur( root->rchild );
printf( "%c ", root->data );
}
}
void trav_preorder( binary_tree root )
{
seq_stack node_seq; /* node sequence */
stack_elem_type p = root;
init_stack_sq( &node_seq );
push_elem_sq( &node_seq, NULL );
while( p != NULL )
{
printf( "%c ", p->data );
if( p->rchild != NULL )
push_elem_sq( &node_seq, p->rchild );
if( p->lchild != NULL )
p = p->lchild;
else
{
p = get_top_sq( node_seq );
pop_elem_sq( &node_seq );
}
}
free_stack_sq( &node_seq );
}
void trav_inorder( binary_tree root )
{
seq_stack stack;
bitree_node * p = root;
init_stack_sq( &stack );
while( p != NULL || ! stack_empty_sq( stack ) )
{
if( p != NULL )
{
push_elem_sq( &stack, p );
p = p->lchild;
}
else
{
p = get_top_sq( stack );
pop_elem_sq( &stack );
printf( "%c ", p->data );
p = p->rchild;
}
}
free_stack_sq( &stack );
}
void trav_postorder( binary_tree root )
{
po_seq_stack stack; // po: post-order
po_stack_elem_type elem;
bitree_node * p = root;
init_stack_posq( &stack );
while( p != NULL || ! stack_empty_posq( stack ) )
{
while( p != NULL )
{
elem.ptr = p;
elem.tag = LR;
push_elem_posq( &stack, elem );
p = p->lchild;
}
elem = get_top_posq( stack );
pop_elem_posq( &stack );
p = elem.ptr;
if( elem.tag == LR )
{
elem.tag = RR;
push_elem_posq( &stack, elem );
p = p->rchild;
}
else
{
printf( "%c ", p->data );
p = NULL;
}
}
free_stack_posq( &stack );
}
void trav_level_order( binary_tree root )
{
circ_queue cq;
queue_elem_type p = NULL;
init_circ_queue( &cq );
if( root != NULL )
{
push_elem_cq( &cq, root );
while( ! circ_queue_empty( cq ) )
{
p = get_front_elem_cq( cq );
pop_elem_cq( &cq );
printf( "%c ", p->data );
if( p->lchild != NULL )
push_elem_cq( &cq, p->lchild );
if( p->rchild != NULL )
push_elem_cq( &cq, p->rchild );
}
}
free_circ_queue( &cq );
}
8、試験手順
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "binary_tree.h"
#include "seq_stack.h"
int main( int argc, char * argv[] )
{
binary_tree root = NULL;
create_bitree( &root );
printf( "PreOrder recursive: " );
trav_preorder_recur( root );
printf( "
" );
trav_preorder( root );
printf( "
" );
printf( "InOrder recursive: " );
trav_inorder_recur( root );
printf( "
" );
trav_inorder( root );
printf( "
" );
printf( "PostOrder recursive:" );
trav_postorder_recur( root );
printf( "
" );
trav_postorder( root );
printf( "
" );
printf( "Level Order: " );
trav_level_order( root );
printf( "
" );
free_bitree( &root );
return 0;
}