1. 采用二叉链表存储结构,实现其各种遍历的方法
1. 定义二叉链表的存储结构;
2. 按先序遍历创建一棵二叉链表树;
3. 实现二叉链表的后序遍历;
2. 采用中序线索链表存储结构,实现中序遍历
1. 定义线索链表的存储结构;
2. 按先序遍历创建一棵二叉链表树;
3. 实现二叉链表的中序线索化;
4. 实现中序线索链表的中序遍历。
1.代码实现
//采用二叉链表存储结构,实现其各种遍历的方法
typedef int TElemType;
char ch;
//二叉树的二叉链表存储表示
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
status CreateBiTree(BiTree &T) {//建树
scanf("%c",&ch);
if (ch == '@')//如果结点没有左右孩子,用空格表示
T = NULL;
else {
if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))
exit(OVERFLOW);
T->data = ch;//生成根结点
CreateBiTree(T->lchild);//构造左子树
CreateBiTree(T->rchild);//构造右子树
}
return OK;
}
void LevelOrder(BiTree T) {
BiTree p = T;
//队列
queue<BiTree> queue;
//根节点入队
queue.push(p);
//队列不空循环
while (!queue.empty()) {
//对头元素出队
p = queue.front();
//访问p指向的结点
printf("%c ", p->data);
//退出队列
queue.pop();
//左子树不空,将左子树入队
if (p->lchild != NULL) {
queue.push(p->lchild);
}
//右子树不空,将右子树入队
if (p->rchild != NULL) {
queue.push(p->rchild);
}
}
}
//递归方式调用
void PreOrderTraverse(BiTree &T) {//先序遍历二叉树
if (T) {
printf("%c ", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree &T) {//中序遍历二叉树
if (T) {
InOrderTraverse(T->lchild);
printf("%c ", T->data);
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree &T) {//后序遍历二叉树
if (T) {
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c ", T->data);
}
}
int main() {
BiTree T;
T = (BiTNode *)malloc(sizeof(BiTNode));
printf("请输入所需遍历的字符串: ");
CreateBiTree(T);
printf("后序序列为: ");
PostOrderTraverse(T);
printf("\n");
printf("先序序列为: ");
PreOrderTraverse(T);
printf("\n");
printf("中序序列为: ");
InOrderTraverse(T);
printf("\n");
printf("层序序列为: ");
LevelOrder(T);
printf("\n");
return 0;
}
2. 代码实现
//二叉树的二叉线索类型存储表示
typedef struct BiThrNode
{char data; //结点数据域
struct BiThrNode *lchild, *rchild; //左右孩子指针
int LTag, RTag;
}BiThrNode, *BiThrTree;
//全局变量pre,始终指向刚刚访问过的结点
BiThrNode *pre = (BiThrTree)malloc(sizeof(BiThrNode));
//用算法5.3建立二叉链表
void CreateBiTree(BiThrTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if (ch == '@') T = NULL; //递归结束,建空树
else
{
T = (BiThrTree)malloc(sizeof(BiThrNode));
T->data = ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
//用算法5.7以结点P为根的子树中序线索化
void InThreading(BiThrTree p)
{
//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
if (p)
{
InThreading(p->lchild); //左子树递归线索化
if (!p->lchild)//没有左孩子
{
p->LTag = 1; //前驱线索为1
p->lchild = pre;//左孩子指针指向它的前驱
}
else//如果有右孩子,前驱线索标为0
p->LTag = 0;
if (!pre->rchild)//没有右孩子
{ //pre的右孩子为空
pre->RTag = 1;//后继线索为1 //给pre加上右线索
pre->rchild = p;//前驱右孩子指针指向后继(当前结点p) //pre的右孩子指针指向p(后继)
}
else
pre->RTag = 0;
pre = p; //保持pre指向p的前驱
InThreading(p->rchild); //右子树递归线索化
}
}//InThreading
//用算法5.8带头结点的中序线索化
void InOrderThreading(BiThrTree &Thrt, BiThrTree T)
{
//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
Thrt = (BiThrTree)malloc(sizeof(BiThrNode)); //建头结点
Thrt->LTag = 0;//头结点有左孩子,若树非空,则其左孩子为树根
Thrt->RTag = 1;//头结点的右孩子指针为右线索
Thrt->rchild = Thrt;//初始化时右指针指向自己
if (!T) Thrt->lchild = Thrt;//若树为空,则左指针也指向自己
else
{
Thrt->lchild = T;//头结点的左孩子指向根
pre = Thrt;//pre初值指向头结点
InThreading(T);//对以T为根的二叉树进行中序线索化
pre->rchild = Thrt;//pre为最右结点,pre的右线索指向头结点
pre->RTag = 1;
Thrt->rchild = pre;//头结点的右线索指向pre
}
}
//t指向头结点,头结点左链lchild指向根结点,头结点右链rchild指向中序遍历的最后一个结点。
//中序遍历二叉线索树表示的二叉树t
void InOrderTraverse_Push(BiThrTree T){//输出中序线索化的二叉链表
BiThrNode *p = (BiThrTree)malloc(sizeof(BiThrNode));//建立一个头结点
p = T->lchild;//p指向根结点
while (p != T)//空树或遍历结束时 P==T
{
while (p->LTag == 0)//当ltag = 0时循环到中序序列的第一个结点
p = p->lchild;
cout << p->data;//显示结点数据,可以更改为其他对结点的操作
while (p->RTag == 1 && p->rchild != T) {
p = p->rchild;
cout << p->data;
}
p = p->rchild;//p进入其右子树
}
}
int main()
{
pre->RTag = 1;
pre->rchild = NULL;
BiThrTree tree, Thrt;
cout << "请输入需中序线索化的二叉链表的字符串: ";
CreateBiTree(tree);
InOrderThreading(Thrt, tree);
cout << "中序遍历线索二叉树为: ";
InOrderTraverse_Push(Thrt);
cout << endl;
return 0;
}