线索二叉树的创建和遍历

线索二叉树由一个头指针来统领,头指针的右孩子指针指向根节点,左孩子指向中序遍历的最后一个结点。。

PS:锁链二叉数只能由中序遍历实现。

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define OVERFLOW -1
#define ERROR 0

//线索二叉树结构的实现//
typedef int Status;
typedef char TElemtype;
typedef enum{Link,Thread} PointTag;  //Link==0表示指向左右孩子
typedef struct BiThrNode {
	TElemtype data;
	struct BiThrNode *lchild, *rchild;//左右孩子指针
	PointTag lTag;
	PointTag rTag;
}BiThrNode,*BiThrTree;
BiThrTree pre;//前驱指针,始终指向刚刚访问过的结点
//用前序遍历的顺序构建二叉树//
void CreateBiTree(BiThrTree *T) {
	char c;
	printf("请输入结点的数据,以#表示空:");
	scanf_s("%c", &c);
	getchar();
	if (c == '#') {
		*T = NULL;
	}
	else {
		(*T) = (BiThrTree)malloc(sizeof(BiThrNode));
		(*T)->data = c;
		(*T)->lTag = Link;
		(*T)->rTag = Link;
		printf("写入成功,该结点的值为%c\n", (*T)->data);
		CreateBiTree(&(*T)->lchild);   //先写左子树
		CreateBiTree(&(*T)->rchild);   //再写右子树
	}
}

//中序遍历进行线索化//
void InThreading(BiThrTree T) {
	//左tag表示前驱,右tag表示后继
	if (T) {
		//如果该节点存在
		InThreading(T->lchild);//中序遍历
		if (!T->lchild) {
			//如果该节点不存在左孩子,则应该指向他的前驱
			T->lTag = Thread;//线索化
			T->lchild = pre; //指向前驱
		}
		if (!pre->rchild) {
			//如果该节点不存在有孩子,则应该该节点为后继
			pre->rTag = Thread;
			pre->rchild = T;
		}
		pre = T;//始终指向前驱(对下一个结点来说)
		InThreading(T->rchild);
	}
}
void InOrderThreading(BiThrTree *P, BiThrTree T) {
	(*P) = (BiThrTree)malloc(sizeof(BiThrNode));
	(*P)->lTag = Link;   //左孩子指向头结点
	(*P)->rTag = Thread; //右孩子是线索,指向最后一个结点
	(*P)->rchild = *P;
	if (!T) {
		//如果T树是一颗空树的话
		(*P)->lchild = *P;
	}
	else {
		//如果不是空树的话
		(*P)->lchild = T;//左孩子指向根节点
		pre = *P;
		InThreading(T);
		//这里pre已经指向了最后一个结点
		pre->rchild = *P;
		pre->rTag = Thread;
		(*P)->rchild = pre;
	}
}
//遍历代码//
Status InOrderTraverse(BiThrTree T) {
	BiThrTree P;
	P = T->lchild;
	while (P != T) {
		//当P不指向头结点的时候表示还没有遍历完
		while (P->lTag == Link)
			//表示有左孩子,要循环遍历到最左边
			P = P->lchild;
		printf("%c\t", P->data);//显示结点数据,可以更改为其他对结点的操作
		while (P->rTag == Thread && P->rchild != T) {
			//当右指针表示后继,并且不是最后一个结点的时候
			P = P->rchild;
			printf("%c\t", P->data);
		}
		P = P->rchild;  //前进至其右子树根
	}
	return OK;
}
int main()
{
	BiThrTree P,T = NULL;
	CreateBiTree(&T);
	InOrderThreading(&P, T);
	printf("遍历结果:");
	InOrderTraverse(P);
    return 0;
}

调试结果:



猜你喜欢

转载自blog.csdn.net/haohulala/article/details/80142583