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;
}