二叉树---实现先序、中序、后序和层序遍历

来源:互联网 发布:淘宝百圣珠宝真假? 编辑:程序博客网 时间:2024/05/06 08:52

1.采用二叉链表存储结构,实现其各种遍历的方法

1. 定义二叉链表的存储结构;

2.按先序遍历创建一棵二叉链表树;

3. 实现二叉链表的后序遍历;


2.采用中序线索链表存储结构,实现中序遍历

1. 定义线索链表的存储结构;

2.按先序遍历创建一棵二叉链表树;

3.实现二叉链表的中序线索化;

4.实现中序线索链表的中序遍历。




1.代码实现

//采用二叉链表存储结构,实现其各种遍历的方法
typedef int TElemType;
char ch;
//二叉树的二叉链表存储表示
typedef struct BiTNode {
    TElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

status CreateBiTree(BiTree &T) {//建树
    scanf("%c",&ch);
    if (ch == '@')//如果结点没有左右孩子,用空格表示
        T = NULL;
    else {
        if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))
            exit(OVERFLOW);
        T->data = ch;//生成根结点
        CreateBiTree(T->lchild);//构造左子树
        CreateBiTree(T->rchild);//构造右子树
    }
    return OK;
}

void LevelOrder(BiTree T) {
    BiTree p = T;
    //队列  
    queue<BiTree> queue;
    //根节点入队  
    queue.push(p);
    //队列不空循环  
    while (!queue.empty()) {
        //对头元素出队  
        p = queue.front();
        //访问p指向的结点  
        printf("%c ", p->data);
        //退出队列  
        queue.pop();
        //左子树不空,将左子树入队  
        if (p->lchild != NULL) {
            queue.push(p->lchild);
        }
        //右子树不空,将右子树入队  
        if (p->rchild != NULL) {
            queue.push(p->rchild);
        }
    }
}

//递归方式调用
void PreOrderTraverse(BiTree &T) {//先序遍历二叉树
    if (T) {
        printf("%c ", T->data);
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}

void InOrderTraverse(BiTree &T) {//中序遍历二叉树
    if (T) {
        InOrderTraverse(T->lchild);
        printf("%c ", T->data);
        InOrderTraverse(T->rchild);
    }
}

void PostOrderTraverse(BiTree &T) {//后序遍历二叉树
    if (T) {
        PostOrderTraverse(T->lchild);
        PostOrderTraverse(T->rchild);
        printf("%c ", T->data);
    }
}

int main() {
    BiTree T;
    T = (BiTNode *)malloc(sizeof(BiTNode));
    printf("请输入所需遍历的字符串: ");
    CreateBiTree(T);
    printf("后序序列为: ");
    PostOrderTraverse(T);
    printf("\n");
    printf("先序序列为: ");
    PreOrderTraverse(T);
    printf("\n");
    printf("中序序列为: ");
    InOrderTraverse(T);
    printf("\n");
    printf("层序序列为: ");
    LevelOrder(T);
    printf("\n");
   
    return 0;
}


2. 代码实现

//采用中序线索链表存储结构,实现中序遍历

//二叉树的二叉线索类型存储表示 

typedef struct BiThrNode

{
    char data;                          //结点数据域  
    struct BiThrNode *lchild, *rchild;   //左右孩子指针  
    int LTag, RTag;
}BiThrNode, *BiThrTree;

//全局变量pre,始终指向刚刚访问过的结点
BiThrNode *pre = (BiThrTree)malloc(sizeof(BiThrNode));

//用算法5.3建立二叉链表  
void CreateBiTree(BiThrTree &T)
{
    //按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T  
    char ch;
    cin >> ch;
    if (ch == '@')  T = NULL;    //递归结束,建空树  
    else
    {
        T = (BiThrTree)malloc(sizeof(BiThrNode));
        T->data = ch;                  //生成根结点  
        CreateBiTree(T->lchild); //递归创建左子树  
        CreateBiTree(T->rchild); //递归创建右子树  
    }                               //else  
}                                   //CreateBiTree
                                    
//用算法5.7以结点P为根的子树中序线索化  
void InThreading(BiThrTree p)
{
    //pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索  
    if (p)
    {
        InThreading(p->lchild);       //左子树递归线索化  
        if (!p->lchild)//没有左孩子
        {                                                 
            p->LTag = 1;  //前驱线索为1                                
            p->lchild = pre;//左孩子指针指向它的前驱                             
        }
        else//如果有右孩子,前驱线索标为0
            p->LTag = 0;
        if (!pre->rchild)//没有右孩子
        {                          //pre的右孩子为空  
            pre->RTag = 1;//后继线索为1          //给pre加上右线索  
            pre->rchild = p;//前驱右孩子指针指向后继(当前结点p) //pre的右孩子指针指向p(后继)  
        }
        else
            pre->RTag = 0;
        pre = p;              //保持pre指向p的前驱  
        InThreading(p->rchild);      //右子树递归线索化  
    }
}//InThreading  

 //用算法5.8带头结点的中序线索化  
void InOrderThreading(BiThrTree &Thrt, BiThrTree T)
{
    //中序遍历二叉树T,并将其中序线索化,Thrt指向头结点  
    Thrt = (BiThrTree)malloc(sizeof(BiThrNode)); //建头结点  
    Thrt->LTag = 0;//头结点有左孩子,若树非空,则其左孩子为树根  
    Thrt->RTag = 1;//头结点的右孩子指针为右线索  
    Thrt->rchild = Thrt;//初始化时右指针指向自己  
    if (!T)  Thrt->lchild = Thrt;//若树为空,则左指针也指向自己  
    else
    {
        Thrt->lchild = T;//头结点的左孩子指向根  
        pre = Thrt;//pre初值指向头结点  
        InThreading(T);//对以T为根的二叉树进行中序线索化  
        pre->rchild = Thrt;//pre为最右结点,pre的右线索指向头结点  
        pre->RTag = 1;
        Thrt->rchild = pre;//头结点的右线索指向pre  
    }
}

//t指向头结点,头结点左链lchild指向根结点,头结点右链rchild指向中序遍历的最后一个结点。
//中序遍历二叉线索树表示的二叉树t
void InOrderTraverse_Push(BiThrTree T){//输出中序线索化的二叉链表
    BiThrNode *p = (BiThrTree)malloc(sizeof(BiThrNode));//建立一个头结点
    p = T->lchild;//p指向根结点
    while (p != T)//空树或遍历结束时 P==T
    {
        while (p->LTag == 0)//当ltag = 0时循环到中序序列的第一个结点
            p = p->lchild;
        cout << p->data;//显示结点数据,可以更改为其他对结点的操作
        while (p->RTag == 1 && p->rchild != T) {
            p = p->rchild;
            cout << p->data;
        }
        p = p->rchild;//p进入其右子树

    }
}
int main()
{
    pre->RTag = 1;
    pre->rchild = NULL;
    BiThrTree tree, Thrt;
    cout << "请输入需中序线索化的二叉链表的字符串: ";
    CreateBiTree(tree);
    InOrderThreading(Thrt, tree);
    cout << "中序遍历线索二叉树为: ";
    InOrderTraverse_Push(Thrt);
    cout << endl;
  
    return 0;
}


0 0
原创粉丝点击