zoukankan      html  css  js  c++  java
  • 二叉链的基本操作

    【目的】

      1. 领会二叉链存储结构;掌握二叉树的各种基本运算和构造二叉树的算法设计。

      2. 领会线索二叉树的构造过程以及构造线索二叉树的算法设计。
    【内容及要求】编写程序实现两种方式建立二叉树:

    编写一个程序btree.cpp,实现二叉树的基本运算,并在此基础上设计一个程序完成以下功能:(见教材P247,实验题1)
    (1)由图7.33所示的二叉树创建对应的二叉链存储结构b,该二叉树的括号表示串为“A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”。
    (2)输出二叉树b。(采用凹入表示法)
    (3)输出’H’结点的左、右孩子结点值。
    (4)输出二叉树b的高度。
    (5)释放二叉树b。
    (6)利用先序序列和中序序列重新构造该
    二叉树(执行(5)的操作后再执行这一功能),
    并以括号表示法输出该二叉树。
    (7)对该二叉树进行中序线索化。

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #define ElemType char
    #define BTNode TBTNode
    #define MaxSize 100
    #define maxsize 100
    typedef struct node
    {
        ElemType data;
        int ltag, rtag; //线索的标记
        struct node *lchild;
        struct node *rchild;
    } BTNode;
    
    BTNode *pre; //全局变量的指针类型
    
    char Pre[100];
    char In[100];
    int i = 0;
    
    void CreateBTree(BTNode *&b, char *str) //创建二叉树
    {
        BTNode *St[MaxSize], *p;
        int top = -1, k, j = 0;
        char ch;
        b = NULL;
        ch = str[j];
    
        while (ch != '')
        {
            switch (ch)
            {
            case '(':
                top++;
                St[top] = p;
                k = 1;
                break;
            case ')':
                top--;
                break;
            case ',':
                k = 2;
                break;
            default:
                p = (BTNode *)malloc(sizeof(BTNode));
                p->data = ch;
                p->lchild = p->rchild = NULL;
                if (b == NULL)
                    b = p;
                else
                {
                    switch (k)
                    {
                    case 1:
                        St[top]->lchild = p;
                        break;
                    case 2:
                        St[top]->rchild = p;
                        break;
                    }
                }
            }
            j++;
            ch = str[j];
        }
    }
    
    void DestoryBTree(BTNode *&b) //摧毁二叉树
    {
        if (b != NULL)
        {
            DestoryBTree(b->lchild);
            DestoryBTree(b->rchild);
            free(b);
        }
    }
    
    BTNode *FindNode(BTNode *b, ElemType x) //寻找值为x的结点
    {
        BTNode *p;
        if (b == NULL)
            return NULL;
        else if (b->data == x)
            return b;
        else
        {
            p = FindNode(b->lchild, x);
            if (p != NULL)
                return p;
            else
                return FindNode(b->rchild, x);
        }
    }
    
    BTNode *LchildNode(BTNode *p) //返回左孩子结点
    {
        return p->lchild;
    }
    
    BTNode *RchildNode(BTNode *p) //返回右孩子结点
    {
        return p->rchild;
    }
    
    int BTHeight(BTNode *b) //输出高度
    {
        int lchildh, rchildh;
        if (b == NULL)
            return 0;
        else
        {
            lchildh = BTHeight(b->lchild);
            rchildh = BTHeight(b->rchild);
            return (lchildh > rchildh) ? (lchildh + 1) : (rchildh + 1);
        }
    }
    
    void DispBTree(BTNode *b) //输出二叉树
    {
        if (b != NULL)
        {
            printf("%c", b->data);
            if (b->lchild != NULL || b->rchild != NULL)
            {
                printf("(");
                DispBTree(b->lchild);
                if (b->rchild != NULL)
                    printf(",");
                DispBTree(b->rchild);
                printf(")");
            }
        }
    }
    
    void PreOrder(BTNode *b)
    //先序遍历的递归形式
    {
        if (b != NULL)
        {
            printf("%c ", b->data);
            Pre[i] = b->data;
            i++;
            PreOrder(b->lchild);
            PreOrder(b->rchild);
        }
    }
    void InOrder(BTNode *b)
    //中序遍历的递归算法
    {
        if (b != NULL)
        {
            InOrder(b->lchild);
            In[i] = b->data;
            i++;
            printf("%c ", b->data);
            InOrder(b->rchild);
        }
    }
    
    BTNode *CreateBTree1(char *pre, char *in, int n)
    //根据前序和中序推出二叉树序列
    {
        BTNode *b;
        char *p;
        int k;
        if (n <= 0)
            return NULL;
        b = (BTNode *)malloc(sizeof(BTNode));
        b->data = *pre;
    
        for (p = in; p < in + n; p++)
            if (*p == *pre)
                break;
    
        k = p - in;
        b->lchild = CreateBTree1(pre + 1, in, k);
        b->rchild = CreateBTree1(pre + k + 1, p + 1, n - k - 1);
        return b;
    }
    
    void Thread(TBTNode *&p) //生成二叉树的线索
    {
        if (p != NULL)
        {
            Thread(p->lchild);
            if (p->lchild == NULL) //节点左孩子为空时就直接指向前驱的节点线索
            {
                p->lchild = pre;
                p->ltag = 1;
            }
            else
                p->ltag = 0;
    
            if (pre->rchild == NULL) //右孩子为空时则指向后继的结点线索位置
            {
                pre->rchild = p;
                pre->rtag = 1;
            }
            else
                pre->rtag = 0;
    
            pre = p;
            Thread(p->rchild);
        }
    }
    
    TBTNode *CreateThread(TBTNode *b) //把二叉链转换成线索的形式
    {
        TBTNode *root;
        root = (BTNode *)malloc(sizeof(BTNode));
        root->ltag = 0;
        root->rtag = 1;
        root->rchild = b;
    
        if (b == NULL)
            root->lchild = root; //原二叉链为空,则指针指回自己root
        else
        {
            root->lchild = b;
            pre = root;
            Thread(b);
            pre->rchild = root;
            pre->rtag = 1;
            root->rchild = pre;
        }
        return root;
    }
    
    void ThInOrder(TBTNode *tb)
    {
        TBTNode *p = tb->lchild;
    
        while (p != tb)
        {
            while (p->ltag == 0)
                p = p->lchild;                      //找到中序的第一个节点
            printf("%c ", p->data);                 //如果无左孩子说明是已经到达了树梢的叶子节点,直接输出
            while (p->rtag == 1 && p->rchild != tb) //输出在中序中的下一个节点值
            {
                p = p->rchild;
                printf("%c ", p->data);
            }
            p = p->rchild; //回溯到p的前一个节点或者是直接找下一个的右孩子节点
        }
    }
    
    void PreOrder2(BTNode *b, int n, int k)
    //凹入法输出二叉链
    {
        if (b != NULL)
        {
    
            for (int j = 0; j < k; j++)
                printf(" ");
            printf("%c ", b->data);
            for (int j = 0; j < n; j++)
                printf("-");
            printf("
    ");
            PreOrder2(b->lchild, n - 1, k + 1);
            PreOrder2(b->rchild, n - 1, k + 1);
        }
    }
    
    int main()
    {
        char a[] = "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";
        int n = 14;
        BTNode *t, *b;
        CreateBTree(t, a);
        b = FindNode(t, 'H');
        printf("括号法输出二叉树:
    ");
        DispBTree(t);
        putchar(10);
        printf("凹入表示法输出二叉树:
    ");
        PreOrder2(t, 14, 1);
        putchar(10);
        printf("该结点的左孩子是 %c , 该孩子的右孩子是 %c 
    ", b->lchild->data, b->rchild->data);
    
        printf("该二叉树的高度是 %d .
    ", BTHeight(t));
    
        printf("先序遍历的结果:");
        PreOrder(t);
        i = 0;
        printf("
    中序遍历的结果:");
        InOrder(t);
    
        DestoryBTree(t);
        printf("
    成功销毁二叉树
    ");
        printf("
    由先序序列和中序序列生成二叉树:");
        b = CreateBTree1(Pre, In, n);
        putchar(10);
        DispBTree(b);
        putchar(10);
    
        printf("二叉树的线索化
    ");
        TBTNode *g;
        g = CreateThread(b);
        printf("成功创建线索化的二叉树
    ");
        printf("中序线索化遍历二叉树:");
        ThInOrder(g);
        putchar(10);
    
        putchar(10);
    
        system("pause");
        return 0;
    }

    喜欢的话,记得支持关注哦。 关注我或者我的csdn博客:https://blog.csdn.net/horizon08/article/details/106254585

  • 相关阅读:
    vim使用
    linux下编译openjdk8
    《鸟哥的Linux私房菜》学习笔记(9)——条件判断
    《鸟哥的Linux私房菜》学习笔记(8)——bash脚本编程之变量
    《鸟哥的Linux私房菜》学习笔记(7)——grep及正则表达式
    《鸟哥的Linux私房菜》学习笔记(6)——管道及IO重定向
    《鸟哥的Linux私房菜》学习笔记(5)——权限管理
    《鸟哥的Linux私房菜》学习笔记(4)——用户和组
    《鸟哥的Linux私房菜》学习笔记(0)——磁盘与文件系统管理
    Intellij Idea 创建JavaWeb项目
  • 原文地址:https://www.cnblogs.com/billyme/p/13031911.html
Copyright © 2011-2022 走看看