DS基础--二叉树的递归与非递归先中后序遍历(C描述)

来源:互联网 发布:淘宝价格字体 编辑:程序博客网 时间:2024/06/06 03:30

RT,二叉树的递归与非递归算法描述,理解还涉及到栈和队列的ADT,都是些基础。考试和面试中常考的问题,层序构造二叉树,C描述如下:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define FUNC_MACRO_PRINT(X) printf("%d.%s\n",X,#X)


#define OK 1
#define ERROR 0
#define OVERFLOW -1


/* 
 * Parent Node Queue Maxsize is 16. 
 * Support The Tree's Depth = 5.
 * If The Tree is Full Binary Tree.
 * The Mount of Leaves Node is 2 ^ (Depth - 1);
 * Depth = log(16) + 1 = 5;
 *
 */
#define MAXSIZE 16/* Support Depth is 5 */


/*
 * In Fact,The Stack's Maxsize is the Binary Tree's Depth.
 * The Worst Situation:"Single-Branch Tree"(A Root With Leaves).
 * So Stack Maxsize = 16 - 1
 *
 */
#define STACK_MAXSIZE 15
#define STACK_INCREMENT 5


#define DEBUG 1


typedef enum CURRENT_CREATE_STATUS{
EMPTY_TREE,
NOMRAL
}CUR_STATUS;


typedef enum BINARY_TREE_BUILD{
CREATE_OVER,
INSERT,
PASS,
DEFAULT
}BITREE_BUILD;


typedef enum BINARY_TREE_TRAVERSE{
EXIT_TRAVERSE,
PERORDER,
INORDER,
POSTORDER,
_PERORDER,
_INORDER,
_POSTORDER
}BINARY_TREE_TRAVERSE;


typedef int Status;
typedef int Elemtype;


typedef struct BiTreeNode{
Elemtype data;
struct BiTreeNode *lchild,*rchild;
}BiTNode,*BiTree;


typedef struct{
BiTree *Data;
int front,rear;
}CycQueue;


typedef struct{
Status (*Traverse)(BiTree ,Status (*visit)(Elemtype));
char *name;
}TraverseTable;


typedef struct{
BiTree *base,*top;
int length;
}SqStack;


/* ---------- Queue Operation ---------- */


static Status InitQueue(CycQueue *Queue)
{
if(!(Queue->Data = (BiTree *)malloc(MAXSIZE * sizeof(BiTree))))
exit(OVERFLOW);

memset(Queue->Data,0,MAXSIZE * sizeof(BiTree));

Queue->front = Queue->rear = 0;

return OK;
}


static Status DestoryQueue(CycQueue *Queue)
{
if(NULL == Queue->Data)
return ERROR;

free(Queue->Data);
return OK;
}


static Status EnQueue(CycQueue *Queue,BiTree Node)
{
if((Queue->rear + 1 & 0x0F) == Queue->front)
return ERROR;


Queue->Data[Queue->rear] = Node;
Queue->rear = Queue->rear + 1 & 0x0F;

return OK;
}


static Status DeQueue(CycQueue *Queue,BiTree *Node)
{
if(Queue->rear == Queue->front)
return ERROR;


*Node = Queue->Data[Queue->front];
Queue->front = Queue->front + 1 & 0x0F;

return OK;
}


/* ---------- Tree Operation ---------- */


static Status InitBiTree(BiTree *T)
{
if(!(*T = (BiTree)malloc(sizeof(BiTNode))))
exit(OVERFLOW);

(*T)->data = -1;/* Empty Tree */
(*T)->lchild = NULL;
(*T)->rchild = NULL;


return OK;
}


#if DEBUG
/* 
 * Show The Binary Tree in "List" Way. 
 * In Fact,Lists Expression is a Kind of PreOrderTraverse.
 * Just For Debug.
 *
 */
static void PreOrderList(BiTree T)
{
if(NULL == T)
{
printf("NULL");
return ;
}
else
printf("%p",T);

if(NULL == T->lchild && NULL == T->rchild)
return ;

printf("(");
PreOrderList(T->lchild);
printf(",");
PreOrderList(T->rchild);
printf(")");

return ;
}


static void ShowBiTree(BiTree T)
{
if(NULL == T)
printf("This is a NULL Tree!\n");
else
{
printf("Tree's List-Expression:(");
PreOrderList(T);
printf(")\n");
}
}
#endif


static Status CreateBiTree(BiTree T)
{
int Choice = DEFAULT;
Elemtype Value;
Status CurrentStatus = EMPTY_TREE;
int child = 0;/* 0:lchid,1:rchild */
BiTree ParentNode;
CycQueue NodeQueue;

if(NULL == T)
exit(OVERFLOW);


InitQueue(&NodeQueue);

while(Choice != CREATE_OVER)
{
printf("---Create The Binary Tree Node By Level Traverse From Root---\n");

FUNC_MACRO_PRINT(INSERT);
FUNC_MACRO_PRINT(PASS);
FUNC_MACRO_PRINT(CREATE_OVER);

printf("Please Input Your Choice\n");
scanf("%d",&Choice);

switch(Choice)
{
case INSERT:
printf("Please Insert The Elem:\n");
scanf("%d",&Value);
system("clear");

if(EMPTY_TREE == CurrentStatus)
{
T->data = Value;
CurrentStatus = NOMRAL;
EnQueue(&NodeQueue,T);
}
else
{
BiTree ChildNode = (BiTree)malloc(sizeof(BiTNode));


if(NULL == ChildNode)
exit(OVERFLOW);


ChildNode->data = Value;
ChildNode->lchild = NULL;
ChildNode->rchild = NULL;
EnQueue(&NodeQueue,ChildNode);

if(child & 1)
ParentNode->rchild = ChildNode;
else
{
DeQueue(&NodeQueue,&ParentNode);
ParentNode->lchild = ChildNode;
}
++child;
}

break;

case PASS:
system("clear");
if(EMPTY_TREE == CurrentStatus)
Choice = CREATE_OVER;
else
{
if(child & 1)
ParentNode->rchild = NULL;
else
{
DeQueue(&NodeQueue,&ParentNode);
ParentNode->lchild = NULL;
}
++child;
}

break;

case CREATE_OVER:
system("clear");
printf("Create Complete.\n");
break;

default:
printf("Wrong Choice.\n");
}
}

DestoryQueue(&NodeQueue);


#if DEBUG
ShowBiTree(T);
#endif


return OK;
}


static int BiTreeDepth(BiTree Root)
{
if(NULL == Root)
return 0;
if(NULL == Root->lchild && NULL == Root->rchild)
return 1;

return (BiTreeDepth(Root->lchild) > BiTreeDepth(Root->rchild) ? 
BiTreeDepth(Root->lchild) : BiTreeDepth(Root->rchild)) + 1;
}


static Status ReleaseNode(BiTree Root)
{
if(NULL == Root)
return ERROR;

if(Root->lchild != NULL)
ReleaseNode(Root->lchild);


if(Root->rchild != NULL)
ReleaseNode(Root->rchild);


free(Root);
Root = NULL;

return OK;
}


static void Destory(BiTree T)
{
ReleaseNode(T);
}


/* ---------- Stack Operation ---------- */


static Status InitStack(SqStack *Stack)
{
if(!(Stack->base = (BiTree *)malloc(STACK_MAXSIZE * sizeof(BiTree))))
exit(OVERFLOW);


Stack->top = Stack->base;
Stack->length = STACK_MAXSIZE;


return OK;
}


static Status DestoryStack(SqStack *Stack)
{
if(NULL == Stack->base)
return ERROR;

free(Stack->base);
Stack->top = Stack->base = NULL;
Stack->length = 0;


return OK;
}


static Status Push(SqStack *Stack,BiTree e)
{
if(Stack->top - Stack->base >= Stack->length)
{
if(!(Stack->base = (BiTree *)realloc(Stack->base,(Stack->length + STACK_INCREMENT) * sizeof(BiTree))))
exit(OVERFLOW);

Stack->top = Stack->base + Stack->length;
Stack->length += STACK_INCREMENT;
}

*Stack->top++ = e;

return OK;
}


static Status Pop(SqStack *Stack,BiTree *e)
{
if(Stack->top == Stack->base)
return ERROR;

*e = *--Stack->top;
return OK;
}


static Status StackEmpty(SqStack *Stack)
{
return Stack->base == Stack->top;
}


static Status StackGetTop(SqStack *Stack,BiTree *e)
{
if(Stack->top == Stack->base)
return ERROR;


*e = *(Stack->top - 1);
return OK;
}


/* DIY Simple visit Operation.Just a Way of Traverse(). */
static Status PrintNode(Elemtype data)
{
printf("%d",data);
return OK;
}


/* ---------- Tree Traverse Recurse ---------- */


static Status PreOrderTraverse(BiTree T,Status (*visit)(Elemtype))
{
if(T)
{
if(!visit(T->data))
return ERROR;
PreOrderTraverse(T->lchild,visit);
PreOrderTraverse(T->rchild,visit);
}

return OK;
}


static Status InOrderTraverse(BiTree T,Status (*visit)(Elemtype))
{
if(T)
{
InOrderTraverse(T->lchild,visit);
if(!visit(T->data))
return ERROR;
InOrderTraverse(T->rchild,visit);
}

return OK;
}


static Status PostOrderTraverse(BiTree T,Status (*visit)(Elemtype))
{
if(T)
{
PostOrderTraverse(T->lchild,visit);
PostOrderTraverse(T->rchild,visit);
if(visit(T->data))
return ERROR;
}


return OK;
}


/* ---------- Tree Traverse No Recurse ---------- */


static Status _PreOrderTraverse(BiTree T,Status (*visit)(Elemtype))
{
SqStack Stack;
BiTree p = T;


InitStack(&Stack);


while(p || !StackEmpty(&Stack))
{
if(p)
{
if(!visit(p->data))
return ERROR;

Push(&Stack,p);
p = p->lchild;
}
else
{
Pop(&Stack,&p);
p = p->rchild;
}
}

DestoryStack(&Stack);
return OK;
}


static Status _InOrderTraverse(BiTree T,Status (*visit)(Elemtype))
{
SqStack Stack;
BiTree p = T;

InitStack(&Stack);


while(p || !StackEmpty(&Stack))
{
if(p)
{
Push(&Stack,p);
p = p->lchild;
}
else
{
Pop(&Stack,&p);

if(!visit(p->data))
return ERROR;

p = p->rchild;
}
}

DestoryStack(&Stack);
return OK;
}


static Status _PostOrderTraverse(BiTree T,Status (*visit)(Elemtype))
{
SqStack Stack;
BiTree p = T,r = NULL;


InitStack(&Stack);


while(p || !StackEmpty(&Stack))
{
if(p)
{
Push(&Stack,p);

p = p->lchild;
}
else
{
StackGetTop(&Stack,&p);

if(p->rchild && p->rchild != r)
{
p = p->rchild;
Push(&Stack,p);
p = p->lchild;
}
else
{
Pop(&Stack,&p);
if(!visit(p->data))
return ERROR;

r = p;
p = NULL;
}
}
}

DestoryStack(&Stack);
return OK;
}


static void TraverseMenu(BiTree T)
{
int i,choice = -1;

TraverseTable BiTreeTraverse[7] = 
{
[EXIT_TRAVERSE].name = "Exit Traverse",[EXIT_TRAVERSE].Traverse = NULL,
[PERORDER].name = "PreOrderTraverse",[PERORDER].Traverse = PreOrderTraverse,
[INORDER].name = "InOrderTraverse" ,[INORDER].Traverse = InOrderTraverse,
[POSTORDER].name = "PostOrderTraverse",[POSTORDER].Traverse = PostOrderTraverse,
[_PERORDER].name = "No Recurse PreOrder",[_PERORDER].Traverse = _PreOrderTraverse,
[_INORDER].name = "No Recurse InOrder",[_INORDER].Traverse = _InOrderTraverse,
[_POSTORDER].name = "No Recurse PostOrder",[_POSTORDER].Traverse = _PostOrderTraverse
};


while(choice)
{
printf("Function List of Traverse:\n");

for(i = 0;i < 7;++i)
printf("%d.%s\n",i,BiTreeTraverse[i].name);

printf("Please Choice The Way of Traverse:\n");
scanf("%d",&choice);
system("clear");

if(choice > 0 && choice < 7)
BiTreeTraverse[choice].Traverse(T,PrintNode);
else if(0 == choice)
printf("Exiting...");
else
printf("Choice is illegal");

printf("\n");
}
}


int main(void)
{
BiTree Root = NULL;

InitBiTree(&Root);

CreateBiTree(Root);
TraverseMenu(Root);

Destory(Root);

return 0;
}

0 0
原创粉丝点击