树和二叉树
来源:互联网 发布:淘宝直通车课程 编辑:程序博客网 时间:2024/05/16 07:58
//BiTree.hstruct 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 256struct 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,栈指针为0void 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");}//判断栈是否为空,空返回非0int 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,错误返回1int 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为待计算的二叉树的根结点。首先判断根节点是否为空,然后分别按照递归调用来计算左子树深度和右子树深度,从而完成整个二叉树深度的计算。
0 0
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- 树和二叉树
- iOS 8 TableviewCell侧滑出现更多Button
- Java学习笔记5
- 内核模块编译Makefile模板
- 一起talk Vim吧(第十回:Vim追命刀法)
- Shell基础-环境变量配置文件-简介
- 树和二叉树
- asp.net Server.Transfer 打开新页面,新页面可以使用Request.Form取值
- eclipse的配置
- C++中的static关键字的总结
- Android开发相关的优秀Blog推荐——站在巨人的肩膀上
- Nodejs 异步框架async
- 如何自动获取网页页面元素的xpath(基于火狐浏览器)
- 用递归实现整数的各数字之和
- oracle02