树和二叉树
//BiTree.h struct BiTNode //采用二叉链表存储结构 { char data; struct BiTNode* lchild; struct BiTNode* rchild; }BiTNode; struct BiTNode* CreateBiTree(); int DestroyBiTree(struct BiTNode* T); int visit(char elem); //递归遍历算法 int PreOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem)); int InOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem)); int PostOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem)); //非递归遍历算法 void PreOrderTraverse(struct BiTNode* T, int (*visit)(char elem)); void InOrderTraverse(struct BiTNode* T, int (*visit)(char elem)); void PostOrderTraverse(struct BiTNode* T, int (*visit)(char elem));
//stack.h 堆栈数据结构,用于非递归算法中的附加空间 #define STACK_SIZE 256 struct stack { struct BiTNode* elem[STACK_SIZE]; int top; //top总是指向栈顶元素的上一个元素 int bottom; //恒0 }; void initStack(struct stack* s); struct BiTNode* getTop(struct stack* s); struct BiTNode* pop(struct stack* s); void push(struct stack* s,struct BiTNode* p); int isEmpty(struct stack* s);
//stack.c 堆栈的实现 #include<stdio.h> #include<string.h> #include "stack.h" //初始化堆栈为0,栈指针为0 void initStack(struct stack* s) { memset(s->elem,0,STACK_SIZE); s->top = s->bottom = 0; } //获取栈顶元素,栈顶指针不变 struct BiTNode* getTop(struct stack* s) { return s->elem[s->top-1]; } //弹出&返回栈顶元素 struct BiTNode* pop(struct stack* s) { if(s->top == s->bottom) //若栈空 { printf("Stack is empty!\n"); return 0; } --s->top; return s->elem[s->top]; } //将pB指针压入栈中 void push(struct stack* s,struct BiTNode* pB) { if(s->top<STACK_SIZE) //栈未满 { s->elem[s->top] = pB; ++s->top; } else printf("Stack is full!\n"); } //判断栈是否为空,空返回非0 int isEmpty(struct stack* s) { return s->top == s->bottom; }
//BiTree.c 二叉树创建、销毁、递归算法实现 #include<stdio.h> #include<malloc.h> #include "BiTree.h" #include "stack.h" struct BiTNode* CreateBiTree() //采用先序递归方法创建一棵二叉树 { struct BiTNode* T; char ch,tmp; printf("please input the value of the node:\n"); scanf("%c",&ch); tmp = getchar(); //忽略回车符 if(ch == ''&'') //输入&符号表示此节点为空 { printf("Null BiTreeNode Created!\n"); T = NULL; return NULL; } T = (struct BiTNode *)malloc(sizeof(BiTNode)); //为当前节点分配内存 if(!T) { printf("Allocate memory failed!\n"); return NULL; } T->data = ch; //为当前节点赋值 T->lchild = CreateBiTree(); //递归创建左子树 T->rchild = CreateBiTree(); //递归创建右子树 return T; } //销毁二叉树,销毁成功返回0,错误返回1 int DestroyBiTree(struct BiTNode* T) { if(T) { struct BiTNode* lchild = T->lchild; struct BiTNode* rchild = T->rchild; free(T); if(0 == DestroyBiTree(lchild)) { if(0 == DestroyBiTree(rchild)) return 0; else return 1; } } return 0; } //访问节点元素 int visit(char elem) { if(elem == ''&'') return 1; printf("%c ",elem); return 0; } //先序遍历递归算法,返回值为0表示遍历成功,1为失败 int PreOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem)) { if(T) { if(0 != visit(T->data)) //访问根节点 return 1; if(T->lchild) { if(0 != InOrderTraverse_R(T->lchild,visit)) //递归遍历左子树 return 1; } if(T->rchild) { if(0 != InOrderTraverse_R(T->rchild, visit)) //递归遍历右子树 return 1; } } return 0; } //中序遍历递归算法,返回值为0表示遍历成功,1为失败 int InOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem)) { if(T) { if(T->lchild) { if(0 != InOrderTraverse_R(T->lchild,visit)) //递归遍历左子树 return 1; } if(0 != visit(T->data)) //访问根节点 return 1; if(T->rchild) { if(0 != InOrderTraverse_R(T->rchild,visit)) //递归遍历右子树 return 1; } } return 0; } //后序遍历递归算法,返回0表示遍历成功,1为失败 int PostOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem)) { if(T) { if(T->lchild) { if(0 != PostOrderTraverse_R(T->lchild,visit)) //递归遍历左子树 return 1; } if(T->rchild) { if(0 != PostOrderTraverse_R(T->rchild,visit)) //递归遍历右子树 return 1; } if(0 != visit(T->data)) //访问根节点 return 1; } return 0; } //先序遍历非递归算法 void PreOrderTraverse(struct BiTNode* T, int (*visit)(char elem)) { struct stack ss; struct BiTNode* p = T; initStack(&ss); while(p||!isEmpty(&ss)) { if(p) { visit(p->data); push(&ss,p); p=p->lchild; } else { p = getTop(&ss); pop(&ss); p = p->rchild; } } } //中序遍历非递归算法 void InOrderTraverse(struct BiTNode* T, int (*visit)(char elem)) { struct stack ss; struct BiTNode* p; initStack(&ss); push(&ss,T); while(!isEmpty(&ss)) { while(p = getTop(&ss)) push(&ss,p->lchild); //向左走到尽头 p = pop(&ss); //空指针退栈 if(!isEmpty(&ss)) { p = pop(&ss); visit(p->data); //访问节点 push(&ss,p->rchild); //向右一步 } } } //后序遍历非递归算法 void PostOrderTraverse(struct BiTNode* T, int (*visit)(char elem)) { struct stack ss; struct BiTNode* p = T; struct BiTNode* q; initStack(&ss); //初始化空栈 while(p || !isEmpty(&ss)) { if(p) { push(&ss,p); p = p->lchild; } else { p =getTop(&ss); if(p) { push(&ss,NULL); p = p->rchild; } else { pop(&ss); q = pop(&ss); visit(q->data); } } } }
//main.c 测试主程序 #include<stdio.h> #include "BiTree.h" int main() { struct BiTNode* bt = 0; bt = CreateBiTree(bt); printf("先序遍历序列:\n"); PreOrderTraverse_R(bt,visit); printf("\n中序遍历序列:\n"); InOrderTraverse_R(bt,visit); printf("\n后序遍历序列:\n"); PostOrderTraverse_R(bt,visit); printf("\n非递归先序遍历序列:\n"); PreOrderTraverse(bt,visit); printf("\n非递归中序遍历序列:\n"); InOrderTraverse(bt,visit); printf("\n非递归后序遍历序列:\n"); PostOrderTraverse(bt,visit); DestroyBiTree(bt); return 0; }
查找结点
查找结点就是遍历二叉树中的每一个节点,逐个比较数据,当找到目标数据时将返回该数据所在结点的指针。
代码如下:
CBTType *TreeFindNode(CBTType *treeNode,DATA data)
{
CBTType *ptr;
if(treeNode==NULL)
{
return NULL;
}else
{
if(treeNode->data==data)
{
return treeNode;
}
else //分别向左右子树查找
{
if(ptr=TreeFindNode(treeNode->left,data)) //左子树递归查找
{
}
else if(ptr=TreeFindNode(treeNode->right,data)) //右子树递归查找
{
return ptr;
}
else
{
return NULL;
}
}
}
}
输入参数treeNode为待查找的二叉树的根结点,输入参数data为待查找的结点数据。程序中首先判断根结点是否为空,然后根据数据判断是否为根结点,然后分别向左右子树进行查找,采用递归的方法进行查找,查找到该结点则返回结点对应的指针;如果全都查找不到,则返回NULL。
计算二叉树的深度
计算二叉树深度就是计算二叉树中结点的最大层数,这里往往需要采用递归算法来实现。int TreeDepth(CBTType *treeNode)
{
int depleft,depright;
if(treeNode==NULL)
{
return 0; //结点为空的时候,深度为0
}
else
{
depleft=TreeDepth(treeNode->left); //左子树深度(递归调用)
depright=TreeDepth(treeNode->right); //右子树深度(递归调用)
if(depleft)
{
return ++depleft;
}
else
{
return ++depright;
}
}
}
输入参数treeNode为待计算的二叉树的根结点。首先判断根节点是否为空,然后分别按照递归调用来计算左子树深度和右子树深度,从而完成整个二叉树深度的计算。
版权声明: