【数据结构】线索化二叉树(前序中序后序)

这篇博客详细介绍了如何使用C语言实现线索化二叉树,包括前序、中序和后序遍历的方法。通过ThreadTree.h、ThreadTree.c和test.c三个文件的代码示例,展示了具体的操作过程。
摘要由CSDN通过智能技术生成

ThreadTree.h


#pragma once

#include<stdio.h>

typedef enum Flag{
	Is_Chlid,
	Is_Thread,
}Flag;

typedef  char ThreadType;

typedef struct ThreadNode{
	ThreadType data;
	struct ThreadNode* left;
	struct ThreadNode* right;
	/*这个两个flag分别表示上面两个指针的状态*/
	Flag lflag;
	Flag rflag;
}ThreadNode;

/*创建一个树*/
ThreadNode* ThreadTreeCreate(ThreadType arr[], size_t size, ThreadType invalid);

/*把树线索化*/
/*前序线索化*/
void Pre_Threading(ThreadNode* root);
/*中序线索化*/
void In_Threading(ThreadNode* root);
/*后序线索化*/
void Post_Threading(ThreadNode* root);

/*线索化后遍历*/
/*前序*/
void PreOrderByThreading(ThreadNode* root); 
/*中序*/
void InOrderByThreading(ThreadNode* root);



ThreadTree.c


#define _CRT_SECURE_NO_WARNINGS 1
#include"ThreadTree.h"
#include"SeqStack.h"
#include<stdio.h>
#include<assert.h>

/*创建一个结点*/
ThreadNode* CreateThreadNode(ThreadType value) {
	ThreadNode* new_node = (ThreadNode*)malloc(sizeof(ThreadNode));

	if (new_node != NULL) {
		new_node->data = value;
		new_node->left = NULL;
		new_node->right = NULL;

		new_node->lflag = Is_Chlid;
		new_node->rflag = Is_Chlid;
	}
	return new_node;
}

/*创建一个树*/
ThreadNode* _ThreadTreeCreate(ThreadType pre_arr[], size_t size, int* index, ThreadType invalid) {
	if (*index >= size) {
		/*表示前序数组已经找完了*/
		return NULL;
	}
	/*判断当前结点是不是空字符*/
if (pre_arr[*index] == invalid) {
		return NULL;
	}
	/*创建一个结点*/
	ThreadNode* root = CreateThreadNode(pre_arr[*index]);
	if (root != NULL) {
		++(*index);
		root->left = _ThreadTreeCreate(pre_arr, size, index, invalid);
		++(*index);
		root->right = _ThreadTreeCreate(pre_arr, size, index, invalid);

		return root;
	}
}

ThreadNode* ThreadTreeCreate(ThreadType pre_arr[], size_t size, ThreadType invalid) {
	assert(pre_arr);
	int index = 0;
	return _ThreadTreeCreate(pre_arr, size, &index, invalid);
}

/*把树线索化*/

/*前序*/
ThreadNode* _Pre_Threading(ThreadNode* root, ThreadNode** prev) {
	if (root == NULL || prev == NULL) {
		return NULL;
	}
	if (root->left == NULL) {
		root->left = *prev;  //相当于前驱结点
		root->lflag = Is_Thread;
	}
	if ((*prev)!= NULL && (*prev)->right == NULL) {
		/*如果前序遍历的前一个结点的右结点等于空,则把它的右结点指向当前结点,后继结点*/
		(*prev)->right = root;
		(*prev)->rflag = Is_Thread;
	}
	*prev = root;

	if (root->lflag != Is_Thread) {
		root->left = _Pre_Threading(root->left, prev);
	}
	if (root->rflag != Is_Thread) {
		root->right = _Pre_Threading(root->right, prev);
	}
	return root;
}
/*先序线索化*/
void Pre_Threading(ThreadNode* root) {
	if (root == NULL) {
		return;
	}
	ThreadNode* prev = NULL;
	_Pre_Threading(root, &prev);
}

/*前序遍历线索化的二叉树*/
void PreOrderByThreading(ThreadNode* root) {
	if (root == NULL) {
		return;
	}
	while (root != NULL) {
		while (root->left != NULL && root->lflag != Is_Thread) {
			printf("%c ", root->data);
			root = root->left;
		}
		printf("%c ", root->data);
		/*一直打印到最左边的结点了*/
		root = root->right;
	}
}

/*中序线索化*/

ThreadNode* _In_Theading(ThreadNode* root, ThreadNode** prev) {
	if (root == NULL || prev == NULL) {
		return NULL;
	}

	if (root->lflag != Is_Thread) {
		root->left = _In_Theading(root->left, prev);
	}

	if (root->left == NULL) {
		root->left = (*prev);
		root->lflag = Is_Thread;
	}
	if ((*prev) != NULL && (*prev)->right == NULL) {
		(*prev)->right = root;
		(*prev)->rflag = Is_Thread;
	}
	*prev = root;

	if (root->rflag != Is_Thread) {
		root->right = _In_Theading(root->right, prev);
	}
	return root;
}

void In_Threading(ThreadNode* root) {
	ThreadNode* prev = NULL;

	_In_Theading(root, &prev);
}

/*后序线索化*/

ThreadNode* _Pos_Threading(ThreadNode* root, ThreadNode** prev) {
	if (root == NULL || prev == NULL) {
		return NULL;
	}
	if (root->lflag != Is_Thread) {
		root->left = _Pos_Threading(root->left, prev);
	}
	if (root->rflag != Is_Thread) {
		root->right = _Pos_Threading(root->right, prev);
	}

	if (root->left == NULL) {
		root->left = (*prev);
		root->lflag = Is_Thread;
	}
	if ((*prev) != NULL && (*prev)->right == NULL) {
		(*prev)->right = root;
		(*prev)->rflag = Is_Thread;
	}
	*prev = root;
	return root;
}

void Post_Threading(ThreadNode* root) {
	ThreadNode* prev = NULL;
	_Pos_Threading(root, &prev);
}

/*中序遍历*/
void InOrderByThreading(ThreadNode* root) {
	if (root == NULL) {
		return;
	}
	while (root != NULL) {

		while (root->lflag == Is_Chlid) {
			root = root->left;
		}
		/*root现在到了这棵树的最左边的那个结点*/
		printf("%c ", root->data);

		/*然后开始找中序后继节点*/
		while (root && root->rflag == Is_Thread) {
			root = root->right;
			printf("%c ", root->data);
		}
		/*如果没有当前节点没有后继结点了,那么它一定有右子树*/
		root = root->right;
	}
}



test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"ThreadTree.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define TESTHEAD printf("------------%s----------\n",__FUNCTION__)

void TestCreateThreadTree() {
	TESTHEAD;
	ThreadType pre_arr[] = "ABD##EG###C#F#";
	int sz = strlen(pre_arr);
	ThreadNode* root = NULL;
	root = ThreadTreeCreate(pre_arr, sz, '#');
}

void TestPrevThreading() {
	TESTHEAD;
	ThreadType pre_arr[] = "ABD##EG###C#F#";
	int sz = strlen(pre_arr);
	ThreadNode* root = NULL;
	root = ThreadTreeCreate(pre_arr, sz, '#');

	Pre_Threading(root);
}
/*线索二叉树的前序遍历*/
void TestPreOrderByThreading() {
	TESTHEAD;
	ThreadType pre_arr[] = "ABD###CE##F##";
	int sz = strlen(pre_arr);
	ThreadNode* root = NULL;
	root = ThreadTreeCreate(pre_arr, sz, '#');
	Pre_Threading(root);

	PreOrderByThreading(root);
	printf("\n");
	PrevOrderByLoop(root);
}

void TestInThreading() {
	TESTHEAD;
	ThreadType pre_arr[] = "ABD###CE##F##";
	int sz = strlen(pre_arr);
	ThreadNode* root = NULL;
	root = ThreadTreeCreate(pre_arr, sz, '#');
	In_Threading(root);
}

void TestPosThreading() {
	TESTHEAD;
	ThreadType pre_arr[] = "ABD###CE##F##";
	int sz = strlen(pre_arr);
	ThreadNode* root = NULL;
	root = ThreadTreeCreate(pre_arr, sz, '#');
	Post_Threading(root);
}

/*线索二叉树的中序遍历*/
void TestInOrderByThreading() {
	TESTHEAD;
	ThreadType pre_arr[] = "ABD###CE##F##";
	int sz = strlen(pre_arr);
	ThreadNode* root = NULL;
	root = ThreadTreeCreate(pre_arr, sz, '#');
	In_Threading(root);
	
	InOrderByThreading(root);
	printf("\n");
}

int main() {
	TestCreateThreadTree();
	TestPrevThreading();
	TestPreOrderByThreading();
	TestInThreading();
	TestInOrderByThreading();
	TestPosThreading();
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值