• DS博客作业03--树


    0.PTA得分截图

    1.本周学习总结

    1.1 总结树及串内容

    • 串的BF算法

      1. 从目标串s 的第一个字符起和模式串t的第一个字符进行比较,若相等,则继续逐个比较后续字符,否则就串s 的第二个字符起再重新和串t进行比较。
      1. 依此类推,直至串t 中的每个字符依次和串s的一个连续的字符序列相等,则称模式匹配成功,此时串t的第一个字符在串s 中的位置就是t 在s中的位置,否则模式匹配不成功。
        代码
    {  
        if (pos <1 ||  pos > S[0] ) exit(ERROR);  
        int i = pos, j =1;  
        while (i<= S[0] && j <= T[0])  
        {  
            if (S[i] == T[j])  
            {  
                ++i; ++j;  
            } else {  
                i = i- j+ 2;  
                j = 1;  
            }  
        }  
        if(j > T[0]) return i - T[0];  
        return ERROR;  
    }  
    
    • KMP算法
      每当遍历出现字符比较不等时,不需要回到I指针,而是用“部分匹配”的结果将模式向右滑动尽可能远的一段距离后,继续进行比较。
      代码实现
    int KMPindex(SString S, SString T, int pos)  
    {  
        if (pos <1 ||  pos > S[0] ) exit(ERROR);  
        int i = pos, j =1;  
        while (i<= S[0] && j <= T[0])  
        {  
            if (S[i] == T[j]) {  
                ++i; ++j;  
            } else {  
                j = next[j+1];  
            }  
        }  
        if(j > T[0]) return i - T[0];  
        return ERROR;  
    }  
    
    • 二叉树存储结构、建法、遍历及应用

    二叉树存储结构

    1 顺序存储结构

    顺序存储一棵二叉树时,首先对该树中的每个结点进行编号,然后以各结点的编号为下标,把各结点的值对应存储到一个一位数组中。每个结点的编号与等深度的满二叉树中对应结点的编号相等,即树根结点的编号为1,接着按照从上到下和从左到右的次序,若一个结点的编号为i,则左、右孩子的编号分别为2i和2i+1。

    2 链接存储结构

    链接存储的方法是:在上面的结点结构中再增加一个parent指针域,用来指向其双亲结点。这种存储结构既便于查找孩子结点,也便于查找双亲结点,当然也带来存储空间的相应增加。

    二叉树建法

    递归法

    void CreateBiTree(BiTree& T, char str[], int& i)
    {
    		if (str[i] == '#')
    			T = NULL;
    		else
    		{
    			T = new BiTNode;
    			T->data = str[i];
    			CreateBiTree(T->lchild, str, ++i);
    			CreateBiTree(T->rchild, str, ++i);
    		}
    }
    

    二叉树遍历及应用

    1.先序遍历

    先序遍历的规则如下:若当前二叉树为空,则返回空,否则

    1. 访问根结点;
    2. 先序遍历左子树;
    3. 先序遍历右子树;
    void PreorderPrintLeaves(BinTree BT)
    {
        if (BT)
        {
            if (!BT->Left && !BT->Right)
                printf(" %c", BT->Data);
            PreorderPrintLeaves(BT->Left);
            PreorderPrintLeaves(BT->Right);
        }
    }
    

    2.中序遍历

    中序遍历的规则如下:若当前二叉树为空,则返回空,否则

    1. 中序列根结点的左子树;
    2. 访问根结点;
    3. 中序遍历根结点的右子树;
    void PreorderPrintLeaves(BinTree BT)
    {
        if (BT)
        {
            if (!BT->Left && !BT->Right);
            PreorderPrintLeaves(BT->Left);
            printf(" %c", BT->Data);
            PreorderPrintLeaves(BT->Right);
        }
    }
    

    3.后序遍历

    后序遍历的规则如下:若当前二叉树为空,则返回空,否则

    1. 后序列根结点的左子树;
    2. 后序遍历根结点的右子树;
    3. 访问根结点;
    void PreorderPrintLeaves(BinTree BT)
    {
        if (BT)
        {
            if (!BT->Left && !BT->Right);
            PreorderPrintLeaves(BT->Left);
            PreorderPrintLeaves(BT->Right);
            printf(" %c", BT->Data);
        }
    }
    

    树的结构、操作、遍历及应用

    #include <stdio.h>
    #include <stdlib.h>
    typedef struct node {
     char data;
     struct node *l, *r;
    }BinNode;
    BinNode *create_tree()  //创建树
    {
     BinNode *t;
     char ch;
     ch = getchar();
     if(ch == '#')     //#表示空
      t = NULL;
     else
     {
      t = (BinNode *)malloc(sizeof *t);
      t->data = ch;
      t->l = create_tree();    //递归创建左子树
      t->r = create_tree();     //递归创建右子树
     }
     return t;
    }
    void pre_ord(BinNode *t)     //先序遍历
    {
     if(t)
     {
      printf("%c", t->data);
      pre_ord(t->l);     //遍历左子树
      pre_ord(t->r);    //遍历左子树 
     }
    }
    void in_ord(BinNode *t)    //中序遍历  
    {
     if(t)
     {
      in_ord(t->l);     //中序左子树遍历
      printf("%c", t->data);
      in_ord(t->r);     //中序右子树遍历
     }
    }
    void post_ord(BinNode *t)     //后序遍历
    {
     if(t)
     {
      post_ord(t->l);      //后序左子树遍历
      post_ord(t->r);        //后序右子树遍历 
      printf("%c", t->data);
     }
    }
    void main()
    {
     BinNode *root = NULL;      
     root = create_tree();
     printf("先序遍历:");  pre_ord(root); printf("
    ");
     printf("中序遍历:");   in_ord(root);  printf("
    ");
     printf("后序遍历:");   post_ord(root);  printf("
    "); 
    }
    

    线索二叉树

    利用原来的空链域存放指针,指向树中其他结点。这种指针称为线索。
    记ptr指向二叉链表中的一个结点,以下是建立线索的规则:
    (1)如果ptr->lchild为空,则存放指向中序遍历序列中该结点的前驱结点。这个结点称为ptr的中序前驱;
    (2)如果ptr->rchild为空,则存放指向中序遍历序列中该结点的后继结点。这个结点称为ptr的中序后继;
    显然,在决定lchild是指向左孩子还是前驱,rchild是指向右孩子还是后继,需要一个区分标志的。因此,我们在每个结点再增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量。

    void InThreading(BiTree p)  
    {  
        if(p)  
        {  
            InThreading(p->lchild);          //递归左子树线索化  
                    //===  
            if(!p->lchild)           //没有左孩子  
            {  
                p->ltag = Thread;    //前驱线索  
                p->lchild = pre; //左孩子指针指向前驱  
            }  
            if(!pre->rchild)     //没有右孩子  
            {  
                pre->rtag = Thread;  //后继线索  
                pre->rchild = p; //前驱右孩子指针指向后继(当前结点p)  
            }  
            pre = p;  
                    //===  
            InThreading(p->rchild);      //递归右子树线索化  
        }  
    }  
    
    其中:
    (1)ltag为0时指向该结点的左孩子,为1时指向该结点的前驱;
    (2)rtag为0时指向该结点的右孩子,为1时指向该结点的后继;
    (3)因此对于上图的二叉链表图可以修改为下图的养子。
    

    哈夫曼树

    • 我们称判定过程最优的二叉树为哈夫曼树,又称最优二叉树

    -路径: 树中一个结点到另一个结点之间的分支构成这两个结点之间的路径。

    -路径长度:路径上的分枝数目称作路径长度。

    -树的路径长度:从树根到每一个结点的路径长度之和。

    -结点的带权路径长度:在一棵树中,如果其结点上附带有一个权值,通常把该结点的路径长度与该结点上的权值

    1.2.谈谈你对树的认识及学习体会。

    • 树确实在数据结构中占有很重要的地位,也是一个很难的点,需要有足够的耐心和精力去学习并理解,但在学习成功的时刻却会很自豪,
      总之还是要好好的将数据结构这门难关给攻克了。

    2.阅读代码

    2.1 题目及解题代码



    2.1.1 该题的设计思路

    • 考察循环和多维数组的精确应用,通过数组来实现数独游戏的完成

    2.1.3 运行结果

    2.1.4分析该题目解题优势及难点。

    • 此题的难点主要在于对数独功能的实际施行,如每行每列每斜行都不可有重复数字,对此的具体代码限制就显得有点困难,巧妙的运用多维数组可以很好的解决问题。
  • 相关阅读:
    使用密码记录工具keepass来保存密码
    ADO.NET Entity Framework CodeFirst 如何输出日志(EF 5.0)
    Mono 3.2 测试NPinyin 中文转换拼音代码
    Reactive Extensions(Rx) 学习
    Reactive Extensions介绍
    Mono 3.2 上跑NUnit测试
    RazorEngine 3.3 在Mono 3.2上正常运行
    标准数据源访问库
    .Net 跨平台可移植类库正在进行
    Windows安装和使用zookeeper
  • 原文地址:https://www.cnblogs.com/hak1143704299/p/12688302.html
Copyright © 2020-2023  润新知