1.先(根)序遍历的
递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴ 访问根结点;
⑵ 遍历左子树;
⑶ 遍历右子树。
2.中(根)序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵访问根结点;
⑶遍历右子树。
3.后(根)序遍历得递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵遍历右子树;
⑶访问根结点。
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);">
</span>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);">
</span>
typedef struct node{
int data;
struct node *lchild,*rchild;
} NODE;
NODE *root;
先序遍历:
DLR(NODE *root )
{
if (root) //非空二叉树
{
printf(“%d”,root->data); //访问D
DLR(root->lchild); //递归遍历左子树
DLR(root->rchild); //递归遍历右子树
}
}
中序遍历:
LDR(NODE *root)
{
if(root !=NULL)
{
LDR(root->lchild);
printf(“%d”,root->data);
LDR(root->rchild);
}
}
后序遍历:
LRD (NODE *root)
{
if(root !=NULL)
{
LRD(root->lchild);
LRD(root->rchild);
printf(“%d”,root->data);
}
}
通过中序遍历和先序遍历可以确定一个树
通过中序遍历和后续遍历可以确定一个树。
通过先序遍历和后序遍历确定不了一个数。
利用先序遍历来建树(结点值陆续从键盘输入,用DLR为宜)
Bintree createBTpre( )
{ Bintree T; char ch;
scanf(“%c”,&ch);
if(ch==’#’) T=NULL;
else
{ T=( Bintree )malloc(sizeof(BinTNode));
T->data=ch;
T->lchild=createBTpre();
T->rchild=createBTpre();
}
return T;
}
中序遍历非递归算法
分析1:什么时候访问根、什么时候访问左子树、什么访问右子树
当左子树为空或者左子树已经访问完毕以后,再访问根
访问完毕根以后,再访问右子树。
分析2:为什么是栈,而不是其他队列。
先走到的后访问、后走到的先访问,显然是栈结构
分析3:结点所有路径情况
步骤1:结点的所有路径情况
如果结点有左子树,该结点入栈;
如果结点没有左子树,访问该结点;
分析3:路径所有情况
如果结点有右子树,重复步骤1;
如果结点没有右子树(结点访问完毕),回退,让栈顶元素出栈,访问栈顶元素,并访问右子树,重复步骤1
如果栈为空,表示遍历结束。
注意:入栈的结点表示,本身没有被访问过,同时右子树也没有被访问过。
分析4:有一个一直往左走入栈的操作
#include "iostream"
#include "stack"
using namespace std;
//二叉链表
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild; //左孩子 右孩子
}BiTNode,*BiTree;
/*
1
2 3
4 5
*/
BiTNode *GoFarLeft(BiTNode *T, stack<BiTNode *> &s)
{
if (T == NULL)
{
return NULL;
}
//如果T有左孩子 入栈
while (T->lchild)
{
s.push(T);
T= T->lchild;//一直往左走
}
return T; //找到一个没有左孩子的节点,就是中序遍历的起点
}
void InOrder2(BiTNode *T)
{
stack<BiTNode *>s;
BiTNode *t = GoFarLeft(T, s); //中序遍历的起点
while(t)
{
printf("%d ", t->data);
if (t->rchild) //如果有右孩子 重复12步骤
{
t = GoFarLeft(T->rchild, s);
}
else if (!s.empty()) //如果没有右孩子,说明该节点的树放完毕,需要返回。
{
t = s.top(); //非空就从栈顶拿元素
s.pop();
}
else //如果没有右孩子,并且栈为空 t = NULL;
{
t = NULL;
}
}
}
void main()
{
BiTNode b1, b2, b3, b4, b5;
BiTNode *pNewTree = NULL;
memset(&b1, 0, sizeof(BiTNode));
memset(&b2, 0, sizeof(BiTNode));
memset(&b3, 0, sizeof(BiTNode));
memset(&b4, 0, sizeof(BiTNode));
memset(&b5, 0, sizeof(BiTNode));
b1.data = 1;
b2.data = 2;
b3.data = 3;
b4.data = 4;
b5.data = 5;
//构建树关系
b1.lchild = &b2;
b1.rchild = &b3;
b2.lchild = &b4;
b3.lchild = &b5;
InOrder2(&b1);
system("pause");
}
二叉树编程:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
//二叉链表
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild; //左孩子 右孩子
}BiTNode, *BiTree;
//三叉链表
typedef struct TriTNode
{
int data;
//左右孩子指针
struct TriTNode *lchild, *rchild;
struct TriTNode *parent;
}TriTNode, *TriTree;
//双亲链表
#define MAX_TREE_SIZE 100
typedef struct BPTNode
{
int data;
int *parent; //指向双亲的指针
char LRTag; //左右孩子标志域
}BPTNode;
typedef struct BPTree
{
BPTNode nodes[MAX_TREE_SIZE]; //因为节点之间是分散的,需要把节点存储到数组中
int num_node; //节点数目
int root; //根结点的位置 //注意此域存储的是父亲节点在数组的下标
}BPTree;
void PreOrder(BiTNode *T)
{
if (T != NULL)
{
printf("%d ", T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
void InOrder(BiTNode *T)
{
if (T != NULL)
{
InOrder(T->lchild);
printf("%d ", T->data);
InOrder(T->rchild);
}
}
void PostOrder(BiTNode *T)
{
if (T != NULL)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
printf("%d ", T->data);
}
}
/*
1
2 3
4 5
*/
//1 遍历算法 3种
//2
int g_count = 0;
void CountLeaf(BiTNode *T) //先根
{
if (T != NULL)
{
CountLeaf(T->lchild);
CountLeaf(T->rchild);
if (T->lchild == NULL && T->rchild == NULL)
{
g_count++;
}
}
}
void CountLeaf2(BiTNode *T, int *ncount) //先根
{
if (T != NULL)
{
CountLeaf2(T->lchild, ncount);
CountLeaf2(T->rchild, ncount);
if (T->lchild == NULL && T->rchild == NULL)
{
(*ncount)++;
}
}
}
//求树的深度
int depth(BiTNode *node){
int depthval = 0, depthL = 0, depthR = 0;
if (node == NULL){
depthval = 0;
return depthval;
}
depthL = depth(node->lchild);
depthR = depth(node->rchild);
depthval = 1 + ((depthL > depthR) ? depthL:depthR);
return depthval;
}
//拷贝树
BiTNode* copyTree(BiTNode *t){
if (t == NULL){
return NULL;
}
BiTNode *newNode = NULL, *newLptr=NULL,*newRptr=NULL;
if (t->lchild != NULL){
newLptr = copyTree(t->lchild);
}
if (t->rchild != NULL){
newRptr = copyTree(t->rchild);
}
newNode = (BiTNode *)malloc(sizeof(BiTNode));
newNode->lchild = newLptr;
newNode->rchild = newRptr;
newNode->data = t->data;
}
void main()
{
BiTNode b1, b2, b3, b4, b5;
memset(&b1, 0, sizeof(BiTNode));
memset(&b2, 0, sizeof(BiTNode));
memset(&b3, 0, sizeof(BiTNode));
memset(&b4, 0, sizeof(BiTNode));
memset(&b5, 0, sizeof(BiTNode));
b1.data = 1;
b2.data = 2;
b3.data = 3;
b4.data = 4;
b5.data = 5;
//构建树关系
b1.lchild = &b2;
b1.rchild = &b3;
b2.lchild = &b4;
b3.lchild = &b5;
printf("\n先根遍历");
PreOrder(&b1);
printf("\n中根遍历");
InOrder(&b1);
printf("\n后根遍历");
PostOrder(&b1);
{
int ncoutn = 0;
CountLeaf2(&b1, &ncoutn);
printf("\n叶子结点个数:%d\n", ncoutn);
}
int dep = depth(&b1);
printf("树的深度:%d \n", dep);
BiTree *bt = copyTree(&b1);
PreOrder(bt);
system("pause");
}