您的位置:首页 > 理论基础 > 数据结构算法

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

2018-02-27 19:49 459 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息