摘录

分类: C/C++

 

树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的系统的访问,即依次对树中每个结点访问一 次且仅访问一次。树的3种最重要的遍历方式分别称为前序遍历、中序遍历和后序遍历。以这3种方式遍历一棵树时,若按访问结点的先后次序将结点排列起来,就 可分别得到树中所有结点的前序列表,中序列表和后序列表。相应的结点次序分别称为结点的前序、中序和后序。
 
数据结构里, 
就是对一棵二叉树所有结点的访问 
前序遵循“根左右” 
中序遵循“左根右” 
后序遵循“左右根” 
根:根节点 
左:左子女 
右:右子女 
如:一棵二叉树 : 

/ \ 
B C 
/ \ 
D E 
前序访问顺序就是:ABDEC(根一定第一个) 
中序访问顺序就是:DBEAC(根一定在中间) 
后序访问顺序就是:DEBCA(根一定在最后)


#include 
#include 
#define STACK_MAX_SIZE 30 
#define QUEUE_MAX_SIZE 30 
#ifndef elemType 
typedef char elemType; 
#endif 
/************************************************************************/ 
/* 以下是关于二叉树操作的11个简单算法 */ 
/************************************************************************/ 
struct BTreeNode{ 
elemType data; 
struct BTreeNode *left; 
struct BTreeNode *right; 
}; 

/* 1.初始化二叉树 */ 
void initBTree(struct BTreeNode* *bt) 

*bt = NULL; 
return; 


/* 2.建立二叉树(根据a所指向的二叉树广义表字符串建立) */ 
void createBTree(struct BTreeNode* *bt, char *a) 

struct BTreeNode *p; 
struct BTreeNode *s[STACK_MAX_SIZE];/* 定义s数组为存储根结点指针的栈使用 */ 
int top = -1; /* 定义top作为s栈的栈顶指针,初值为-1,表示空栈 */ 
int k; /* 用k作为处理结点的左子树和右子树,k = 1处理左子树,k = 2处理右子树 */ 
int i = 0; /* 用i扫描数组a中存储的二叉树广义表字符串,初值为0 */ 
*bt = NULL; /* 把树根指针置为空,即从空树开始建立二叉树 */ 
/* 每循环一次处理一个字符,直到扫描到字符串结束符为止 */ 
while(a[i] != ''){ 
switch(a[i]){ 
case ' ': 
break; /* 对空格不作任何处理 */ 
case '(': 
if(top == STACK_MAX_SIZE - 1){ 
printf("栈空间太小!n"); 
exit(1); 

top++; 
s[top] = p; 
k = 1; 
break; 
case ')': 
if(top == -1){ 
printf("二叉树广义表字符串错误!n"); 
exit(1); 

top--; 
break; 
case ',': 
k = 2; 
break; 
default: 
p = malloc(sizeof(struct BTreeNode)); 
p->data = a[i]; 
p->left = p->right = NULL; 
if(*bt == NULL){ 
*bt = p; 
}else{ 
if( k == 1){ 
s[top]->left = p; 
}else{ 
s[top]->right = p; 



i++; /* 为扫描下一个字符修改i值 */ 

return; 


/* 3.检查二叉树是否为空,为空则返回1,否则返回0 */ 
int emptyBTree(struct BTreeNode *bt) 

if(bt == NULL){ 
return 1; 
}else{ 
return 0; 



/* 4.求二叉树深度 */ 
int BTreeDepth(struct BTreeNode *bt) 

if(bt == NULL){ 
return 0; /* 对于空树,返回0结束递归 */ 
}else{ 
int dep1 = BTreeDepth(bt->left); /* 计算左子树的深度 */ 
int dep2 = BTreeDepth(bt->right); /* 计算右子树的深度 */ 
if(dep1 > dep2){ 
return dep1 + 1; 
}else{ 
return dep2 + 1; 




/* 5.从二叉树中查找值为x的结点,若存在则返回元素存储位置,否则返回空值 */ 
elemType *findBTree(struct BTreeNode *bt, elemType x) 

if(bt == NULL){ 
return NULL; 
}else{ 
if(bt->data == x){ 
return &(bt->data); 
}else{ /* 分别向左右子树递归查找 */ 
elemType *p; 
if(p = findBTree(bt->left, x)){ 
return p; 

if(p = findBTree(bt->right, x)){ 
return p; 

return NULL; 




/* 6.输出二叉树(前序遍历) */ 
void printBTree(struct BTreeNode *bt) 

/* 树为空时结束递归,否则执行如下操作 */ 
if(bt != NULL){ 
printf("%c", bt->data); /* 输出根结点的值 */ 
if(bt->left != NULL || bt->right != NULL){ 
printf("("); 
printBTree(bt->left); 
if(bt->right != NULL){ 
printf(","); 

printBTree(bt->right); 
printf(")"); 


return; 


/* 7.清除二叉树,使之变为一棵空树 */ 
void clearBTree(struct BTreeNode* *bt) 

if(*bt != NULL){ 
clearBTree(&((*bt)->left)); 
clearBTree(&((*bt)->right)); 
free(*bt); 
*bt = NULL; 

return; 


/* 8.前序遍历 */ 
void preOrder(struct BTreeNode *bt) 

if(bt != NULL){ 
printf("%c ", bt->data); /* 访问根结点 */ 
preOrder(bt->left); /* 前序遍历左子树 */ 
preOrder(bt->right); /* 前序遍历右子树 */ 

return; 



/* 9.中序遍历 */ 
void inOrder(struct BTreeNode *bt) 

if(bt != NULL){ 
inOrder(bt->left); /* 中序遍历左子树 */ 
printf("%c ", bt->data); /* 访问根结点 */ 
inOrder(bt->right); /* 中序遍历右子树 */ 

return; 


/* 10.后序遍历 */ 
void postOrder(struct BTreeNode *bt) 

if(bt != NULL){ 
postOrder(bt->left); /* 后序遍历左子树 */ 
postOrder(bt->right); /* 后序遍历右子树 */ 
printf("%c ", bt->data); /* 访问根结点 */ 

return; 


/* 11.按层遍历 */ 
void levelOrder(struct BTreeNode *bt) 

struct BTreeNode *p; 
struct BTreeNode *q[QUEUE_MAX_SIZE]; 
int front = 0, rear = 0; 
/* 将树根指针进队 */ 
if(bt != NULL){ 
rear = (rear + 1) % QUEUE_MAX_SIZE; 
q[rear] = bt; 

while(front != rear){ /* 队列非空 */ 
front = (front + 1) % QUEUE_MAX_SIZE; /* 使队首指针指向队首元素 */ 
p = q[front]; 
printf("%c ", p->data); 
/* 若结点存在左孩子,则左孩子结点指针进队 */ 
if(p->left != NULL){ 
rear = (rear + 1) % QUEUE_MAX_SIZE; 
q[rear] = p->left; 

/* 若结点存在右孩子,则右孩子结点指针进队 */ 
if(p->right != NULL){ 
rear = (rear + 1) % QUEUE_MAX_SIZE; 
q[rear] = p->right; 


return; 


/************************************************************************/ 

/* 
int main(int argc, char *argv[]) 

struct BTreeNode *bt; /* 指向二叉树根结点的指针 */ 
char *b; /* 用于存入二叉树广义表的字符串 */ 
elemType x, *px; 
initBTree(&bt); 
printf("输入二叉树广义表的字符串:n"); 
/* scanf("%s", b); */ 
b = "a(b(c), d(e(f, g), h(, i)))"; 
createBTree(&bt, b); 
if(bt != NULL) 
printf(" %c ", bt->data); 
printf("以广义表的形式输出:n"); 
printBTree(bt); /* 以广义表的形式输出二叉树 */ 
printf("n"); 
printf("前序:"); /* 前序遍历 */ 
preOrder(bt); 
printf("n"); 
printf("中序:"); /* 中序遍历 */ 
inOrder(bt); 
printf("n"); 
printf("后序:"); /* 后序遍历 */ 
postOrder(bt); 
printf("n"); 
printf("按层:"); /* 按层遍历 */ 
levelOrder(bt); 
printf("n"); 
/* 从二叉树中查找一个元素结点 */ 
printf("输入一个待查找的字符:n"); 
scanf(" %c", &x); /* 格式串中的空格跳过空白字符 */ 
px = findBTree(bt, x); 
if(px){ 
printf("查找成功:%cn", *px); 
}else{ 
printf("查找失败!n"); 

printf("二叉树的深度为:"); 
printf("%dn", BTreeDepth(bt)); 
clearBTree(&bt); 
return 0; 

*/
posted @ 2015-08-18 17:11  .anna  阅读(117)  评论(0编辑  收藏  举报