二叉树:
首先了解一下树的概念:树是有n个节点的有限集,它可以为空树(n==0),而二叉树其具有以下性质:
1.二叉树是一种每个结点最多只有两个孩子的树。
2.每一个子集又是一颗树,叫做子树。
3.每一个可子树的根叫做根的孩子,而该子树又叫双亲。
4.具有相同双亲的结点称为兄弟。
5.树中结点的所在最大层次叫做树的深度。
6.树的访问顺序有先序,中序,后序,层次。
先序就是中左右,中序就是左中右,后序就是左右中,层次就是逐层访问,从左到右。
二叉树基本操作:遍历二叉树
思想:二叉树通常以结构体形式来定义,主要包括三部分,节点存储的值,左孩子的节点,右孩子的节点。
对于先序遍历,就是来一个结点输出一个,所以是中左右,其实就是跟先序输入一样(创造二叉树
而对于中序遍历:就是找到一个最左的叶子结点,然后因为printf在中间,所以IN(l)没有,printf出来,IN(r)没有,会到上一个栈就是中间结点,他的printf在中间,所以他会先p再看IN(r)
5.2建立二叉树
重点:对于建立二叉树,对于每一个结点特别是叶子结点,要当没个结点度为二来输入,对于度为0当作(就是叶子结点)就要输入两个空,通常用‘#’来做标志。
//建立二叉树中每个子树结点
struct TreeNode{
int data;
struct TreeNode*lchild;
struct TreeNode*rchild;
}; BiNode,*BiTree;
//建立二叉树(二叉树的建立都是先序输入)
BiTree CreateTree(){
int data;
scanf("%d",&data);
BiTree root;
if(data <= 0){
return Null;
}else{
root =(BiTree)malloc(sizeof(BiNode));
root->data = data;
root ->lchild = CreateTree();
root->rchildc = CreateTree();
}//off if
}
return root;
5.3先序遍历:
先序遍历就是首先访问根结点,然后先序访问左子树,最后先序遍历根的右子树(就是说先把左边的访问完)。
//先序访问PreorderTraverse(PT)(递归思想)
void PT(BiTree root){
if(root){
printf("%d ",root->data);
PT(root->lchild);
PT(root->rchild);
}//off if
} //off PT
//非递归(栈思想)
void PT(BiTree root){
BiTree stack[MaxSize];
BiTree p;
int top = -1;
if(root != NULL){
//根节点入站
top++;
stack[top] = root;
while(top>-1){
//出栈并且访问该节点
p = stack[top];
top--;
printf("%d ",p->data);
//右孩子入栈
if(p->rchild ! = NULL){
top++;
stack[top] = p->rchild;
}
//左孩子入栈
if(p-lchild != NULL){
top++;
stack[top] = p-lchild;
}
} //off while
}//off if
} //off PT
5.4中序遍历:
中序遍历的过程是首先中序遍历左子树,然后访问根结点,最后中序遍历根的右子树。
//中序遍历二叉树:递归实现
void IT(BiTree root) {
if (root) {
InOrderTraverse(root->lchild);
printf("%d ", root->data);
InOrderTraverse(root->rchild);
}off if
} off IT
//中序遍历二叉树:非递归实现
void IT(BiTree root) {
BiTree stack[MaxSize];
BiTree p;
int top = -1;
if (root != NULL) {
p = root;
while (top > -1 || p != NULL) {
//扫描p的所有左节点并入栈
while (p != NULL) {
top++;
stack[top] = p;
p = p->lchild;
}
if (top > -1) {
//出栈并访问节点
p = stack[top];
top--;
printf("%d ", p->data);
//扫描右孩子
p = p->rchild;
}//of if
}off while
} off if
}off IT
5.5后序遍历
序遍历的过程是首先后序遍历左子树,然后后序遍历根的右子树,最后访问根结点。
//后序遍历二叉树:递归实现
void PostOrderTraverse(BiTree root) {
if (root) {
PostOrderTraverse(root->lchild);
PostOrderTraverse(root->rchild);
printf("%d ", root->data);
}off if
} off void
//后序遍历二叉树:非递归实现
void PostOrderTraverseNonRec(BiTree root) {
BiTree stack[MaxSize];
BiTree p;
int top = -1;
int sign;
if (root != NULL) {
do {
//root节点入栈
while (root != NULL) {
top++;
stack[top] = root;
root = root->lchild;
}
//p指向栈顶前一个已访问节点
p = NULL;
//置root为已访问
sign = 1;
while (top != -1 && sign) {
//取出栈顶节点
root = stack[top];
//右孩子不存在或右孩子已访问则访问root
if (root->rchild == p) {
printf("%d ", root->data);
top--;
//p指向被访问的节点
p = root;
} else {
//root指向右孩子节点
root = root->rchild;
//置未访问标记
sign = 0;
}
}off while
} while (top != -1);
} off if
}off void