中序線索化二叉樹及遍歷

中序線索化二叉樹及遍歷。
函數接口定義

void InThreading(BiThrTree p);// 以結點P爲根的子樹中序線索化
void InOrderTraverse_Thr(BiThrTree T);// 中序遍歷二叉線索樹T的非遞歸算法,對每個數據元素直接輸出

裁判測試程序樣例:

#include<iostream>
using namespace std;

typedef struct BiThrNode
{				
	char data;						
	struct BiThrNode *lchild,*rchild;
	int LTag,RTag;
}BiThrNode,*BiThrTree;


BiThrNode *pre=new BiThrNode;

void CreateBiTree(BiThrTree &T)
{	
	char ch;
	cin >> ch;
	if(ch=='#')  T=NULL;			
	else
	{							
		T=new BiThrNode;
		T->data=ch;					
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);	
	}								
}								

void InThreading(BiThrTree p);
void InOrderTraverse_Thr(BiThrTree T);

int main()
{
	pre->RTag=1;
	pre->rchild=NULL;
	BiThrTree tree;
	CreateBiTree(tree);
	InThreading(tree);
	InOrderTraverse_Thr(tree);
	return 0;
}
/* 請在這裏填寫答案 */

輸入樣例:

ABD###CEG###FH##I##

輸出樣例:

DBAGECHFI

分析:從裁判樣例入手

  1. 先序遍歷建樹
void CreateBiTree(BiThrTree &T)
{
    char ch;
    cin >> ch;
    if(ch=='#')
        T=NULL;
    else
    {
        T=new BiThrNode;
        T->data=ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}
  1. 建立中序線索,賦予前驅和後繼的值
void InThreading(BiThrTree root)/* 對root所指的二叉樹進行中序線索化,其中pre始終指向剛訪問過的結點,其初值爲NULL*/
{
    if (root!=NULL)
    {
        InThreading(root->lchild);  /* 線索化左子樹 */
        if (root->lchild==NULL)/*沒有左孩子指向前驅*/
        {
            root->LTag=1;
            root->lchild=pre->rchild;  /*置前驅線索 */
            /*主函數是對pre->rchild=NULL,賦值爲空。第一個結點的前驅爲空,此時要把pre->rchild賦給root->lchild,而不是把pre賦給root->lchild*/
        }
        if (pre!=NULL&&pre->rchild==NULL)  /* 置後繼線索 */
        {
            pre->rchild=root;
            pre->RTag=1;
        }
        pre=root;
        InThreading(root->rchild);  /*線索化右子樹*/
    }
}
  1. 找到中序遍歷的第一個結點,並不斷找後繼,此時輸出的就是中序遍歷
BiThrNode * InNext(BiThrNode *p)
/*在中序線索二叉樹中查找p的中序後繼結點,並用next指針返回結果*/
{
    BiThrNode *Next;
    BiThrNode *q;
    if (p->RTag==1)
        Next=p->rchild;  /*直接利用線索*/
    else
    {
        /*在p的右子樹中查找"最左下端"結點*/
        if(p->rchild!=NULL)
        {
            for(q=p->rchild; q->LTag==0 ; q=q->lchild);
            Next=q;
        }
        else
            Next = NULL;
    }
    return Next;
}
BiThrNode* TinFirst(BiThrTree root)
{
    BiThrNode *q=root;
    q=root;
    if(q)
        while(q->lchild!=NULL)/*找左子樹的左子樹。。。*/
            q=q->lchild;
    return q;
}
void InOrderTraverse_Thr(BiThrTree root)
{
    BiThrNode *p;
    p=TinFirst(root);/*找到第一個結點*/
    while(p!=NULL)
    {
        printf("%c",p->data);
        p=InNext(p);
    }
}

完整代碼

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef struct BiThrNode
{
    char data;
    struct BiThrNode *lchild,*rchild;
    int LTag,RTag;
} BiThrNode,*BiThrTree;
BiThrNode *pre=new BiThrNode;
void CreateBiTree(BiThrTree &T)
{
    char ch;
    cin >> ch;
    if(ch=='#')
        T=NULL;
    else
    {
        T=new BiThrNode;
        T->data=ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}
void InThreading(BiThrTree root)/* 對root所指的二叉樹進行中序線索化,其中pre始終指向剛訪問過的結點,其初值爲NULL*/
{
    if (root!=NULL)
    {
        InThreading(root->lchild);  /* 線索化左子樹 */
        if (root->lchild==NULL)/*沒有左孩子指向前驅*/
        {
            root->LTag=1;
            root->lchild=pre->rchild;  /*置前驅線索 */
        }
        if (pre!=NULL&&pre->rchild==NULL)  /* 置後繼線索 */
        {
            pre->rchild=root;
            pre->RTag=1;
        }
        pre=root;
        InThreading(root->rchild);  /*線索化右子樹*/
    }
}
BiThrNode * InNext(BiThrNode *p)
/*在中序線索二叉樹中查找p的中序後繼結點,並用next指針返回結果*/
{
    BiThrNode *Next;
    BiThrNode *q;
    if (p->RTag==1)
        Next=p->rchild;  /*直接利用線索*/
    else
    {
        /*在p的右子樹中查找"最左下端"結點*/
        if(p->rchild!=NULL)
        {
            for(q=p->rchild; q->LTag==0 ; q=q->lchild);
            Next=q;
        }
        else
            Next = NULL;
    }
    return Next;
}
BiThrNode* TinFirst(BiThrTree root)
{
    BiThrNode *q=root;
    q=root;
    if(q)
        while(q->lchild!=NULL)/*找左子樹的左子樹。。。*/
            q=q->lchild;
    return q;
}
void InOrderTraverse_Thr(BiThrTree root)
{
    BiThrNode *p;
    p=TinFirst(root);/*找到第一個結點*/
    while(p!=NULL)
    {
        printf("%c",p->data);
        p=InNext(p);
    }
}
int main()
{
    pre->RTag=1;
    pre->rchild=NULL;
    BiThrTree tree;
    CreateBiTree(tree);
    InThreading(tree);
    InOrderTraverse_Thr(tree);
    return 0;
}

若在主函數初始化pre爲NULL,則建立中序線索二叉樹時

void  Inthread(BiTree root)/* 對root所指的二叉樹進行中序線索化,其中pre始終指向剛訪問過的結點,其初值爲NULL*/
{
    if (root!=NULL)
    {
        Inthread(root->LChild);  /* 線索化左子樹 */
        if (root->LChild==NULL)/*沒有左孩子指向前驅*/
        {
            root->Ltag=1;
            root->LChild=pre;  /*置前驅線索*/
            /*第一個結點沒有前驅,則直接把pre賦值給root->LChild*/
        }
        if (pre!=NULL&& pre->RChild==NULL)  /* 置後繼線索 */
        {
            pre->RChild=root;
            pre->Rtag=1;
        }
        pre=root;
        Inthread(root->RChild);  /*線索化右子樹*/
    }
}

完整代碼

#include <stdio.h>
#include <malloc.h>
#include <conio.h>
typedef char DataType;
typedef struct Node
{
    DataType data;
    int  Ltag;
    int  Rtag;
    struct Node *LChild;
    struct Node *RChild;
} BiTNode, *BiTree;
BiTree pre;
void CreateBiTree(BiTree *bt)/*先序遍歷建立二叉樹*/
{
    char ch;
    ch = getchar();
    if(ch=='#')
        *bt=NULL;
    else
    {
        *bt=(BiTree)malloc(sizeof(BiTNode)); //生成一個新結點
        (*bt)->data=ch;
        (*bt)->Ltag=0;/*相當於初始化*/
        (*bt)->Rtag=0;
        CreateBiTree(&((*bt)->LChild)); //生成左子樹
        CreateBiTree(&((*bt)->RChild)); //生成右子樹
    }
}
void  Inthread(BiTree root)/* 對root所指的二叉樹進行中序線索化,其中pre始終指向剛訪問過的結點,其初值爲NULL*/
{
    if (root!=NULL)
    {
        Inthread(root->LChild);  /* 線索化左子樹 */
        if (root->LChild==NULL)/*沒有左孩子指向前驅*/
        {
            root->Ltag=1;
            root->LChild=pre;  /*置前驅線索 */
        }
        if (pre!=NULL&& pre->RChild==NULL)  /* 置後繼線索 */
        {
            pre->RChild=root;
            pre->Rtag=1;
        }
        pre=root;
        Inthread(root->RChild);  /*線索化右子樹*/
    }
}
BiTNode * InNext(BiTNode * p)
/*在中序線索二叉樹中查找p的中序後繼結點,並用next指針返回結果*/
{
    BiTNode *Next;
    BiTNode *q;
    if (p->Rtag==1)
        Next = p->RChild;  /*直接利用線索*/
    else
    {
        /*在p的右子樹中查找"最左下端"結點*/
        if(p->RChild!=NULL)
        {
            for(q=p->RChild; q->Ltag==0 ; q=q->LChild);
            Next=q;
        }
        else
            Next = NULL;
    }
    return(Next);
}
BiTNode* TinFirst(BiTree root)
{
    BiTNode *p;
    p = root;
    if(p)
        while(p->LChild!=NULL)
            p=p->LChild;
    return p;
}
void TinOrder(BiTree root)
{
    BiTNode *p;
    p=TinFirst(root);
    while(p!=NULL)
    {
        printf("%c",p->data);
        p=InNext(p);
    }
}
int main()
{
    BiTree T;
    BiTree p,q;
    CreateBiTree(&T);
    pre=NULL;
    Inthread(T);
    TinOrder(T);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章