二叉树的遍历和线索二叉树
1.二叉树的遍历
先序:根左右
中序:左根右
后序:左右根
每个结点都只访问一次并且仅访问一次,故时间复杂度为O(n),在递归遍历中,递归工作栈的栈深恰好为树的深度,所以在最坏情况下,二叉树是有n个结点且深度为n的单支树,遍历算法的空间复杂度为O(n)。
void PreOrder(BiTree root) { if (root != NULL) { printf(root->data); PreOrder(root->lchild); PreOrder(root->rchild); } } //输出叶子结点 void PreleafNode(BiTree root) { if (root != NULL) { if (root->lchild == NULL && root->rchild == NULL) printf(root->data); PreleafNode(root->lchild); PreleafNode(root->rchild); } } //统计叶子结点数目,3种遍历均可 int leafcount = 0; void leaf(BiTree root) { if (root != NULL) { leaf(root->lchild); leaf(root->rchild); if (root->lchild == NULL && root->rchild == NULL) leafcount++; } } int leafc(BiTree root) { int Leafcount; if (root == NULL) Leafcount = 0; else if (root->lchild == NULL && root->rchild == NULL) Leafcount = 1; else Leafcount = leafc(root->lchild) + leafc(root->rchild); return Leafcount; } //先序遍历创建二叉链表 void CreateTree(BiTree* bt) { char ch; ch = getchar(); if (ch == '.') *bt = NULL; else { *bt = (BiTree)malloc(sizeof(BiTNode)); (*bt)->data = ch; CreateTree(&((*bt)->lchild)); CreateTree(&((*bt)->rchild)); } } //后序求高 int PostHeight(BiTree bt) { int hl, hr, max; if (bt != NULL) { hl = PostHeight(bt->lchild); hr = PostHeight(bt->rchild); max = hl > hr ? hl : hr; return (max + 1); } else return (0); } //先序求高 int height = 0; void PreHeigth(BiTree bt,int h) { if (bt != NULL) { if (h > height) height = h;//该结点层次值大于height,更新height的值 PreHeigth(bt->lchild, h + 1); PreHeigth(bt->rchild, h + 1); } return height; } //树形打印二叉树,从上往下看为逆中序顺序,即右子树,根结点,左子树 void PrintTree(BiTree bt,int nlayer) { if (bt == NULL) return; PrintTree(bt->rchild, nlayer + 1); for (int i = 0; i < nlayer; i++) printf(" "); printf("%c\n", bt->data); PrintTree(bt->lchild, nlayer + 1); }
//中序非递归 void InOrderF(BiTree root) { Stack S; BiTNode* p; InitStack(&S); p = root; while (p != NULL || !IsEmpty(&S)) { if (p != NULL) {//根指针进栈,遍历左子树 Push(&S, &p); p = p->LChild; } else { Pop(&S, &p);//根指针退栈,访问根结点,遍历右子树 printf("%d", p->data); p = p->RChild; } } } //后序遍历非递归 void PostOrderT(BiTree root) { BiTNode* p, * q; Stack S; InitStack(&S); p = root; q = NULL; while (p != NULL || !IsEmpty(&S)) { if (p != NULL) { Push(&S, &p); p = p->LChild;//遍历左子树 } else { GetTop(&S, &p); if (p->RChild == NULL || p->RChild == q) {//无右孩子或右孩子已被遍历过 visit(p->data);//访问根结点 q = p;//保存q,为下一次已处理结点前驱 Pop(&S, &p); p = NULL; } else { p = p->RChild; } } } }
#include "stdlib.h" #include "stdio.h" //线索二叉树 typedef char ElemType; typedef struct ThreadNode { ElemType data; struct ThreadNode* LChild, * RChild; int Ltag, Rtag; }ThreadNode,*ThreadTree; //中序线索化 void InThread(ThreadTree root) { ThreadNode *pre=NULL; if (root != NULL) { InThread(root->LChild); if (root->LChild == NULL) { root->Ltag = 1; root->LChild = pre; } if (pre != NULL && pre->RChild == NULL) { pre->RChild = root; pre->Rtag = 1; } pre = root; InThread(root->RChild); } }
//找前驱,p的左孩子的最右端
ThreadNode* Inpre(ThreadNode* p) {
ThreadNode* pre, * q;
pre = NULL;
if (p->ltag == 1)
pre = p->lchild;
else {
for (q = q->lchild; q->rtag == 0; q = q->rchild)
pre = q;
}
return (pre);
}
//找后继,找右孩子的最左端
ThreadNode* Innext(ThreadNode* p) {
ThreadNode* Next,* q;
if (p->rtag == 1)
Next = p->rchild;
else
{
for (q = p->rchild; q->ltag == 0; q = q->lchild)
Next = q;
}
return(Next);
}
努力的意义就是放眼望去以后都是喜欢的人和事......

浙公网安备 33010602011771号