二叉树、二叉排序树、线索树、树的遍历实现
/*
* 二叉树
*/
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
// 递归先序遍历
void PreOrder(BiTree T) {
if(T!=NULL) {
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
// 非递归先序遍历
void PreOrderNonRec(BiTree T) {
if(T!=NULL) {
InitStack(S);
BiTree p = T;
while(p||!IsEmpty(S)) {
if(p) {
visit(p);
Push(S,p);
p = p->lchild;
} else {
Pop(S,p);
p = p->rchild;
}
}
}
}
// 递归中序遍历
void InOrder(BiTree T) {
if(T!=NULL) {
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
// 非递归中序遍历
void InOrderNonRec(BiTree T) {
if(T!=NULL) {
InitStack(S);
BiTree p = T;
while(p||!IsEmpty(S)) {
if(p != NULL) {
Push(S,p);
p = p->lchild;
} else {
Pop(S,p);
visit(p);
p = p->rchild;
}
}
}
}
// 递归后续遍历
void PostOrder(BiTree T) {
if(T!=NULL) {
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
// 非递归后续遍历
void PostOrderNonRec(BiTree T) {
if(T!=NULL) {
InitStack(S);
BiTree p,r;
p = T;
r = NULL;
while(p||!IsEmpty(S)) {
if(p!=NULL) {
Push(S,p);
p = p->lchild;
} else {
GetTop(S,p);
if(p->rchild!=NULL && p->rchild!=r) { //右子树存在且未被访问过
p = p->rchild;
Push(S,p);
p = p->lchild; //再转向最左
} else {
Pop(S,p);
visit(p);
r = p; //记录最近访问过的结点
p = NULL;
}
}
}
}
}
// 层序遍历
void leverOrder(BiTree T) {
if(T==NULL)
return;
InitQueue(Q);
BiTree p = T;
EnQueue(Q,p);
while(!IsEmpty(Q)) {
DeQueue(Q,p);
visit(p);
if(p->lchild!=NULL)
EnQueue(Q,p->lchild);
if(p->rchild!=NULL)
EnQueue(Q,p->rchild);
}
}
// 自下而上、从右到左遍历二叉树
void R_levelOrder(BiTree T) {
if(T==NULL)
return;
InitQueue(Q);
InitStack(S);
BiTree p = T;
Push(S,p);
while(!IsEmpty(Q)) {
DeQueue(Q,p);
Push(S,p);
if(p->lchild!=NULL)
EnQueue(Q,p->lchild);
if(p->rchild!=NULL)
EnQueue(Q,p->rchild);
}
while(!IsEmpty(S)) {
Pop(S,p);
visit(p);
}
}
// 求二叉树高度
int Height(BiTree T) {
if(T==NULL)
return 0;
ldep = Height(T->lchild); // 左子树高度
rdep = Height(T->rchild); // 右子树高度
if(ldep > rdep)
return ldep+1;
else
return rdep+1;
}
// 计算二叉树中所有双分支结点个数
int DsonNodes(BiTree T) {
if(T==NULL)
return 0;
if(T->lchild!=NULL && T->rchild!=NULL)
return DsonNodes(T->lchild)+DsonNodes(T->rchild)+1;
return DsonNodes(T->lchild)+DsonNodes(T->rchild);
}
// 交换二叉树所有结点的左右子树
void ExchangeBiTreeChild(BiTree T) {
if(T==NULL)
return;
ExchangeBiTreeChild(T->lchild);
ExchangeBiTreeChild(T->rchild);
BiTNode p;
p = T->lchild;
T->lchild = T->rchild;
T->rchild = p;
p = NULL;
}
// 判断是否二叉排序树
void Judge_AVL(BiTree T, int &balance, int &h) {
if(T==NULL) {
h = 0;
balance = 1;
}
else if(T->lchild==NULL&&T->rchild==NULL) {
h = 1;
balance = 1;
} else {
Judge_AVL(T->lchild, bl, hl);
Judge_AVL(T->rchild, br, hr);
h = (hl>hr?hl:hr)+1;
if(abs(hl-hr)<2)
balance = bl&&br;
else
balance = 0;
}
}
// 求二叉排序树最小/最大值结点
BiTNode *MinNode(BiTNode T) {
while(T->lchild!=NULL)
T = T->lchild;
return T;
// while(T->rchild!=NULL)
// T = T->rchild;
// return T;
}
// 统计二叉树中度为0的结点个数
int countTreeNode_0(BiTree T) {
if(T==NULL)
return 0;
int lc,rc;
lc = countTreeNode_0(T->lchild);
rc = countTreeNode_0(T->rchild);
if(lc==0 && rc==0)
return 1;
return lc+rc;
}
'<Mark>'
// 找到二叉排序树第k小的结点
BiTNode *KthNode(BiTNode T, int &k) {
if(k<1||k>T->count)
return NULL;
if(T->lchild == NULL) {
if(k==1)
return T;
else return KthNode(T->rchild, k-1);
} else {
if(T->lchild->count==k-1)
return T;
if(T->lchild->count>k-1)
return KthNode(T->lchild,k);
if(T->lchild->count<k-1)
return KthNode(T->rchild,k-(T->lchild->count+1));
}
}
/*
* 线索树
*/
typedef struct ThreadNode {
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag;
}ThreadNode, *ThreadTree;
void InThread(ThreadTree &p, ThreadTree &pre) {
if(p!=NULL) {
InThread(p->lchild,pre); //递归线索化左子树
if(p->lchild == NULL) { //前驱
p->lchild = pre;
p->ltag = 1;
}
if(pre != NULL && pre->rchild == NULL) { //后继
pre->rchild = p;
pre->rtag = 1;
}
pre = p;
InThread(p->rchild, pre); //递归线索化右子树
}
}
// 主过程
void CreateInThread(ThreadTree T) {
ThreadTree pre = NULL;
if(T!=NULL) {
InThread(T,pre);
pre->rchild = NULL; //处理最后一个结点
pre->rtag = 1;
}
}
// 求中序线索二叉树的第一个结点
ThreadNode *FirstNode(ThreadNode *p) {
while(p->ltag==0)
p = p->lchild;
return p;
}
// 求中序线索二叉树下一个结点
ThreadNode *NextNode(ThreadNode *p) {
if(p->rtag==0)
return FirstNode(p->rchild); // 指向右孩子时需要找到右孩子第一个最左的结点
return p->rchild;
}
// 线索二叉树中序遍历
void Inorder(ThreadNode *T) {
for(ThreadNode *p=FirstNode(T); p!=NULL; p=NextNode(T))
visit(p);
}