赞
踩
用二叉链表来存储二叉树
typedef struct BiTNode //二叉树
{
int data; //结点数值
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode, *BiTree;
输入一个数组,以层次遍历的顺序进行建树,规定数组元素都大于0。当数组元素为-1时,表示该结点为空。
举个例子,比如数组大小为 12,数组元素为
3 5 6 8 -1 2 7 8 1 34 -1 65
则建立的二叉树为
建立二叉树的代码:
queue<BiTree> q;//辅助队列 void createBiTree() { int n; int a[1010]; //读取输入 scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } //建立二叉树 int counts = 1; for (int i = 1; i <= n; i++) { BiTree tmp = (BiTree)malloc(sizeof(BiTNode)); tmp = q.front(); q.pop(); tmp->data = a[i];//赋值 tmp->lchild = (BiTree)malloc(sizeof(BiTNode)); tmp->rchild = (BiTree)malloc(sizeof(BiTNode)); if(a[i] != -1) { tmp->num = counts;//给非空结点编号 counts++; q.push(tmp->lchild);//后面的元素必须挂在非空结点下面 q.push(tmp->rchild); } else //空结点标记 { tmp->lchild->data = -1; tmp->rchild->data = -1; } } while(!q.empty())//清除队列中的空结点 { q.front()->data = -1; q.pop(); } }
访问结点
void visit(BiTree T)
{
if(T->data != -1)
printf("%d ", T->data);
}
层次遍历
void LevelOrder(BiTree T) { while(!q.empty())//初始化队列 { q.pop(); } q.push(T);//根结点入队 while(!q.empty()) { BiTree tmp = q.front(); q.pop();//队头结点出队 visit(tmp);//访问出队结点 if(tmp->lchild->data != -1) q.push(tmp->lchild); if(tmp->rchild->data != -1) q.push(tmp->rchild); } }
先序遍历,也叫前序遍历
void PreOrder(BiTree T)
{
if(T->data != -1)//结点非空
{
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
中序遍历
void InOrder(BiTree T)
{
if(T->data != -1)//结点非空
{
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
后序遍历
void PostOrder(BiTree T)
{
if(T->data != -1)//结点非空
{
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
中序遍历
void InOrder2(BiTree T) { stack<BiTree> s; BiTree p = T; while((p->data != -1) || (!s.empty()))//p不空或栈不空 { if(p->data != -1) //非空结点 { s.push(p); //入栈,一路向左 p = p->lchild; } else //出栈,转向出栈结点的右子树 { p = s.top(); s.pop(); visit(p); p = p->rchild; } } }
先序遍历和中序遍历很相似,区别在于扫描结点时先访问结点,再将其入栈
void PreOrder2(BiTree T) { stack<BiTree> s; BiTree p = T; while((p->data != -1) || (!s.empty()))//p不空或者栈不空 { if(p->data != -1) //结点非空 { visit(p); //先访问结点,再入栈 s.push(p); p = p->lchild; } else { p = s.top(); //出栈,转向出栈结点的右子树 s.pop(); p = p->rchild; } } }
后序遍历
初始时依次扫描根结点的所有左侧结点并将它们全部依次进栈
读栈顶元素,若其右孩子不为空且未被访问过,将右子树转向 1
否则,栈顶元素出栈并访问
注意:
在第二步中,需要分清返回时是从左子树返回的还是右子树返回的,设置一个辅助指针 r,指向最近访问过的结点。
每次出栈访问完一个结点就相当于遍历完以该结点为根的子树,需要将 p 置空。
void PostOrder2(BiTree T) { stack<BiTree> s; BiTree p = T; BiTree r = NULL; //r指针记录最后一个访问的结点 BiTree kong = (BiTree)malloc(sizeof(BiTNode));//空指针,方便p置空 kong->data = -1; while((p->data != -1) || (!s.empty()))//p不空或栈不空 { if(p->data != -1) //非空结点 { s.push(p); //入栈,一路向左 p = p->lchild; } else { p = s.top(); //访问栈顶元素(不出栈) if((p->rchild->data != -1) && (p->rchild != r))//右子树存在且未被访问过 { p = p->rchild; //转向右子树 s.push(p); p = p->lchild; //仍然一路向左 } else //否则,弹出栈顶元素并访问 { s.pop(); visit(p); r = p; //记录最近访问过的结点 p = kong; //结点访问完后,p置空 } } } }
#include <cstdio> #include <cstdlib> #include <queue> #include <stack> using namespace std; typedef struct BiTNode //二叉树 { int data; //结点数值 struct BiTNode *lchild; struct BiTNode *rchild; }BiTNode, *BiTree; queue<BiTree> q;//辅助队列 void createBiTree(); //层次序列建立二叉树 void visit(BiTree R); //访问结点 void LevelOrder(BiTree R); //层次遍历 /* 递归的先序、中序、后序遍历 */ void PreOrder(BiTree R); void InOrder(BiTree R); void PostOrder(BiTree R); /* 非递归的先序、中序、后序遍历 */ void PreOrder2(BiTree R); void InOrder2(BiTree R); void PostOrder2(BiTree R); int main() { BiTree bit; bit = (BiTree)malloc(sizeof(BiTNode)); q.push(bit); createBiTree(); //层次遍历 printf("\n层次遍历: "); LevelOrder(bit); printf("\n\n"); /* 递归 */ printf("递归\n"); printf("先序遍历: "); PreOrder(bit); printf("\n"); printf("中序遍历: "); InOrder(bit); printf("\n"); printf("后序遍历: "); PostOrder(bit); printf("\n\n"); /* 非递归 */ printf("非递归\n"); printf("先序遍历: "); PreOrder2(bit); printf("\n"); printf("中序遍历: "); InOrder2(bit); printf("\n"); printf("后序遍历: "); PostOrder2(bit); printf("\n"); return 0; } void createBiTree() { int n; int a[1010]; //读取输入 scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } //建立二叉树 for (int i = 1; i <= n; i++) { BiTree tmp = (BiTree)malloc(sizeof(BiTNode)); tmp = q.front(); q.pop(); tmp->data = a[i];//赋值 tmp->lchild = (BiTree)malloc(sizeof(BiTNode)); tmp->rchild = (BiTree)malloc(sizeof(BiTNode)); if(a[i] != -1) { q.push(tmp->lchild);//后面的元素必须挂在非空结点下面 q.push(tmp->rchild); } else //空结点标记 { tmp->lchild->data = -1; tmp->rchild->data = -1; } } while(!q.empty())//清除队列中的空结点 { q.front()->data = -1; q.pop(); } } void visit(BiTree T) { if(T->data != -1) printf("%d ", T->data); } void LevelOrder(BiTree T) { while(!q.empty())//初始化队列 { q.pop(); } q.push(T);//根结点入队 while(!q.empty()) { BiTree tmp = q.front(); q.pop();//队头结点出队 visit(tmp);//访问出队结点 if(tmp->lchild->data != -1) q.push(tmp->lchild); if(tmp->rchild->data != -1) q.push(tmp->rchild); } } void PreOrder(BiTree T) { if(T->data != -1)//结点非空 { visit(T); PreOrder(T->lchild); PreOrder(T->rchild); } } void InOrder(BiTree T) { if(T->data != -1)//结点非空 { InOrder(T->lchild); visit(T); InOrder(T->rchild); } } void PostOrder(BiTree T) { if(T->data != -1)//结点非空 { PostOrder(T->lchild); PostOrder(T->rchild); visit(T); } } void PreOrder2(BiTree T) { stack<BiTree> s; BiTree p = T; while((p->data != -1) || (!s.empty()))//p不空或者栈不空 { if(p->data != -1) //结点非空 { visit(p); //先访问结点,再入栈 s.push(p); p = p->lchild; } else { p = s.top(); //出栈,转向出栈结点的右子树 s.pop(); p = p->rchild; } } } void InOrder2(BiTree T) { stack<BiTree> s; BiTree p = T; while((p->data != -1) || (!s.empty()))//p不空或栈不空 { if(p->data != -1) //非空结点 { s.push(p); //入栈,一路向左 p = p->lchild; } else //出栈,转向出栈结点的右子树 { p = s.top(); s.pop(); visit(p); p = p->rchild; } } } void PostOrder2(BiTree T) { stack<BiTree> s; BiTree p = T; BiTree r = NULL; //r指针记录最后一个访问的结点 BiTree kong = (BiTree)malloc(sizeof(BiTNode));//空指针,方便p置空 kong->data = -1; while((p->data != -1) || (!s.empty()))//p不空或栈不空 { if(p->data != -1) //非空结点 { s.push(p); //入栈,一路向左 p = p->lchild; } else { p = s.top(); //访问栈顶元素(不出栈) if((p->rchild->data != -1) && (p->rchild != r))//右子树存在且未被访问过 { p = p->rchild; //转向右子树 s.push(p); p = p->lchild; //仍然一路向左 } else //否则,弹出栈顶元素并访问 { s.pop(); visit(p); r = p; //记录最近访问过的结点 p = kong; //结点访问完后,p置空 } } } }
程序运行结果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。