zoukankan      html  css  js  c++  java
  • 数据结构学习第十三天

    09:44:07 2019-08-28

    学习

    昨天做了 课程要求的 PTA的三道题 

    基本上涉及了 树的建立 以及树的遍历

    今天把昨天 学到的树的遍历 的非递归 实现了一下

    写的过程也不是特别顺利 看来 知道代码怎么一回事 和 把代码写出 还是有很大区别的

    利用 前序中序后序遍历 以及 层序遍历 输出该树

      1 #define _CRT_SECURE_NO_WARNINGS    //vs中scanf为不安全的函数 要使用 得加上这句话
      2 #include<stdio.h>
      3 #define Size 10
      4 struct TreeNode
      5 {
      6     char Data;
      7     int LeftChild;
      8     int RightChild;
      9     int times;   //为例后序遍历的非递归使用
     10 }Tree[10];
     11 int Stack[10];
     12 int STop;   //栈顶下标
     13 void Push(int Num)
     14 {
     15     Stack[STop++] = Num;
     16 }
     17 int Pop()
     18 {
     19     return Stack[--STop];
     20 }
     21 int IsEmpty()
     22 {
     23     return !STop;
     24 }
     25 
     26 int Queue[10];
     27 int Front = 1;
     28 int Rear = 0;
     29 int QSize;
     30 int Succ(int num)    //判断是否越界
     31 {
     32     if (num < Size)
     33         return num;
     34     else
     35         return 0;
     36 }
     37 void EnQueue(int num)
     38 {
     39     Rear = Succ(Rear+1);
     40     Queue[Rear] =num;
     41     QSize++;
     42 }
     43 int DeQueue()
     44 {
     45     int num = Queue[Front];
     46     Front = Succ(Front+1);
     47     QSize--;
     48     return num;
     49 }
     50 
     51 //非递归实现遍历 
     52 //前序中序后序遍历 的非递归做法都是利用栈    因为 前序中序后序的访问顺序是一样的
     53 void InOrderTraversal(int Bt);  //中序遍历  
     54 void PreOrderTraversal(int Bt); //先序遍历
     55 void PostOrderTraversal(int Bt); //后序遍历
     56 
     57 //层序遍历的做法是利用 队列
     58 void LevelOrderTraversal(int Bt); //层序遍历
     59 
     60 void InOrderTraversal(int Bt)
     61 {
     62     while (Bt!=-1||!IsEmpty())  //空树不输出 如果栈内还有元素 得输出
     63     {
     64         while (Bt != -1)
     65         {
     66             Push(Bt);                     //第一次遇见
     67             Bt = Tree[Bt].LeftChild;
     68         }
     69         if (!IsEmpty())
     70         {
     71             int T = Pop();                //第二次遇见 输出
     72             printf("%c ", Tree[T].Data);
     73             Bt = Tree[T].RightChild;   //转向右节点
     74         }
     75     }
     76 }
     77 void PreOrderTraversal(int Bt)
     78 {
     79     while (Bt != -1 || !IsEmpty())  //空树不输出 如果栈内还有元素 得输出
     80     {
     81         while (Bt != -1)
     82         {
     83             Push(Bt);                     //第一次遇见 输出
     84             printf("%c ", Tree[Bt].Data);
     85             Bt = Tree[Bt].LeftChild;
     86         }
     87         if (!IsEmpty())
     88         {
     89             int T = Pop();                
     90             Bt = Tree[T].RightChild;     //转向右节点
     91         }
     92     }
     93 }
     94 void PostOrderTraversal(int Bt)
     95 {
     96     while (Bt != -1 || !IsEmpty())  //空树不输出 如果栈内还有元素 得输出
     97     {
     98         while (Bt != -1)
     99         {
    100             Push(Bt);                     //第一次遇见 
    101             Tree[Bt].times++;
    102             Bt = Tree[Bt].LeftChild;
    103         }
    104         if (!IsEmpty())
    105         {
    106             int T = Pop();
    107             if (Tree[T].times == 2)            //判断是否第三次遇见
    108                 printf("%c ", Tree[T].Data);   //第三次遇见 输出
    109             else
    110             {
    111                 Push(T);
    112                 Tree[T].times++;
    113                 Bt = Tree[T].RightChild;    //第二次遇见 转向右孩子
    114             }
    115         }
    116     }
    117 }
    118 
    119 void LevelOrderTraversal(int Bt)
    120 {
    121     if (Bt == -1)  //空树
    122         return;
    123     EnQueue(Bt);    //首先必须进队 根节点
    124     while (QSize)     //队列不为空 
    125     {
    126         int T= DeQueue();
    127         printf("%c ", Tree[T].Data);
    128         if (Tree[T].LeftChild != -1) EnQueue(Tree[T].LeftChild);
    129         if (Tree[T].RightChild != -1)EnQueue(Tree[T].RightChild);
    130     }
    131 }
    132 int Convert(char num)     //将字符转换为数字
    133 {
    134     if (num == '-')
    135         return -1;
    136     else
    137         return num - '0';
    138 }
    139 int BuildTree()   //利用 数组建树
    140 {
    141     int Root=-1;   //记录根节点
    142     int N=0;     
    143     int Check[10] = { 0 };  //用来判断根节点的位置
    144     scanf("%d
    ", &N);
    145     for(int i=0;i<N;i++)
    146     {
    147         char Data, Num1, Num2;
    148         scanf("%c %c %c
    ", &Data, &Num1, &Num2);
    149         Tree[i].Data = Data;
    150         Tree[i].LeftChild = Convert(Num1);
    151         Tree[i].RightChild = Convert(Num2);
    152         if (Tree[i].LeftChild != -1)Check[Tree[i].LeftChild] = 1;
    153         if (Tree[i].RightChild != -1)Check[Tree[i].RightChild] = 1;
    154     }
    155     for (int i = 0; i < N; i++)
    156     {
    157         if (!Check[i])
    158             Root = i;
    159     }
    160     return Root;
    161 }
    162 int main()
    163 {
    164     int Tree;
    165     Tree = BuildTree();
    166     InOrderTraversal(Tree); printf("
    ");//中序遍历
    167     PreOrderTraversal(Tree); printf("
    ");  //先序遍历
    168     PostOrderTraversal(Tree); printf("
    "); //后序遍历
    169     LevelOrderTraversal(Tree); //层次遍历
    170 }
    View Code

    输入数据:

    8
    A 1 2
    B 3 4
    C 5 -
    D - -
    E 6 -
    G 7 -
    F - -
    H - -

     输出结果:

    结果正确

    今天了解了下 二叉搜索树 还学了平衡二叉树(AVL)

    !!!平衡二叉树是一颗二叉搜索树  左单旋 右单旋   左右旋 右左旋 都要保证二叉搜索树的性质不变

    然后又被题虐。。

    PAT 第9题 判断是否为同一颗 二叉搜索树

     1 #define _CRT_SECURE_NO_WARNINGS    //vs中scanf为不安全的函数 要使用 得加上这句话
     2 #include<stdio.h>
     3 #include<malloc.h>
     4 typedef struct TNode* BinTree;
     5 typedef BinTree Position;
     6 struct TNode
     7 {
     8     int Element;
     9     BinTree Left;
    10     BinTree Right;
    11 };
    12 BinTree Trees[10];
    13 
    14 BinTree Insert(int Element, BinTree BST)
    15 {
    16     if (!BST)       //BST为空 生成该节点 并且返回
    17     {
    18         BST = (Position)malloc(sizeof(struct TNode));
    19         BST->Element = Element; BST->Left = NULL; BST->Right = NULL;
    20     }
    21     else
    22         if (Element < BST->Element)
    23             BST->Left = Insert(Element, BST->Left);   //递归插入左子树
    24         else if (BST->Element < Element)
    25             BST->Right = Insert(Element, BST->Right);  //递归插入右子树
    26     return BST;
    27 }
    28 void MakeTrees(int N, int i)
    29 {
    30     int num;
    31     scanf("%d", &num);
    32     Trees[i] = (BinTree)malloc(sizeof(struct TNode));
    33     Trees[i]->Element = num;
    34     Trees[i]->Left = Trees[i]->Right = NULL;
    35     for (int j = 0; j < N - 1; j++)
    36     {
    37         scanf("%d", &num);
    38         Trees[i] = Insert(num, Trees[i]);
    39     }
    40     getchar();
    41 }
    42 int Charge(BinTree T, BinTree Tree)   //判断2个树是否相同
    43 {
    44     if (T == NULL && Tree == NULL)   //空树 一定相同
    45         return 1;
    46     if (T->Element != Tree->Element)  //判断节点处元素是否相同
    47         return 0;
    48     else
    49         return Charge(T->Left, Tree->Left) && Charge(T->Right, Tree->Right);  //递归判断2个子树
    50 }
    51 int main()
    52 {
    53     int N;
    54     int L;
    55     scanf("%d", &N);
    56     while (N)
    57     {
    58         scanf("%d
    ", &L);
    59         for (int i = 0; i <= L; i++)
    60             MakeTrees(N, i);
    61         for (int i = 1; i <= L; i++)
    62             if (Charge(Trees[0], Trees[i]))
    63                 printf("Yes
    ");
    64             else
    65                 printf("No
    ");
    66         scanf("%d", &N);
    67     }
    68 }
    View Code

    PAT 第10题 找平衡二叉树的根节点

      1 #define _CRT_SECURE_NO_WARNINGS    //vs中scanf为不安全的函数 要使用 得加上这句话
      2 #include<stdio.h>
      3 #include<malloc.h>
      4 typedef struct TNode* BinTree;
      5 typedef BinTree Position;
      6 struct TNode
      7 {
      8     int Element;
      9     BinTree Left;
     10     BinTree Right;
     11     int Heigth; //高度
     12 };
     13 int GetHeight(BinTree T)
     14 {
     15     if (!T)
     16         return -1;
     17     else
     18         return T->Heigth;
     19 }
     20 
     21 int Max(int a, int b)
     22 {
     23     return (a > b) ? a : b;
     24 }
     25 BinTree NewNode(int Element)
     26 {
     27     BinTree T = (BinTree)malloc(sizeof(struct TNode));
     28     T->Element = Element;
     29     T->Left = NULL;
     30     T->Right = NULL;
     31     T->Heigth = 0;
     32     return T;
     33 }
     34 BinTree SingleLeftRotation(BinTree T)
     35 {
     36     BinTree TL = T->Left;
     37     T->Left = TL->Right;
     38     TL->Right = T;
     39     T->Heigth = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;
     40     TL->Heigth = Max(GetHeight(TL->Left),T->Heigth)+1;
     41     return TL;
     42 }
     43 BinTree SingleRightRotation(BinTree T)
     44 {
     45     BinTree TR = T->Right;
     46     T->Right = TR->Left;
     47     TR->Left = T;
     48     T->Heigth = Max(GetHeight(T->Left),GetHeight(T->Right))+1;
     49     TR->Heigth =Max(GetHeight(TR->Right),T->Heigth)+1;
     50     return TR;
     51 }
     52 BinTree DoubleLeftRightRotation(BinTree T)
     53 { //先做一次右单旋 再做一次左单旋
     54     T->Left = SingleRightRotation(T->Left);
     55     return SingleLeftRotation(T);
     56 }
     57 BinTree DoubleRightLeftRotation(BinTree T)
     58 {//先做一次左旋 再做一次右旋
     59     T->Right = SingleLeftRotation(T->Right);
     60     return SingleRightRotation(T);
     61 }
     62 BinTree Insert(int Element, BinTree BST)
     63 {
     64     if (!BST)       //BST为空 生成该节点 并且返回
     65         BST = NewNode(Element);
     66     else
     67         if (Element < BST->Element)
     68         {
     69             BST->Left = Insert(Element, BST->Left);   //递归插入左子树
     70             if (GetHeight(BST->Left) - GetHeight(BST->Right) == 2)    //判断是否需要进行旋转
     71                 if (Element < BST->Left->Element)    //左单旋
     72                     BST=SingleLeftRotation(BST);
     73                 else
     74                     BST=DoubleLeftRightRotation(BST);     //左-右双旋
     75         }
     76         else if (BST->Element < Element)
     77         {
     78             BST->Right = Insert(Element, BST->Right);  //递归插入右子树
     79             if (GetHeight(BST->Left) - GetHeight(BST->Right) == -2)
     80                 if (Element > BST->Right->Element)    //右单旋
     81                     BST=SingleRightRotation(BST);
     82                 else
     83                     BST=DoubleRightLeftRotation(BST);    //右-左双旋
     84         }
     85     BST->Heigth = Max(GetHeight(BST->Left), GetHeight(BST->Right)) + 1;
     86     return BST;
     87 }
     88 BinTree MakeTree()
     89 {
     90     int N;
     91     scanf("%d",&N);
     92     int num;    
     93     scanf("%d", &num);
     94     BinTree T = NewNode(num);
     95     for (int i = 1; i < N; i++)
     96     {
     97         scanf("%d", &num);
     98         T=Insert(num, T);
     99     }
    100     return T;
    101 }
    102 int main()
    103 {
    104     BinTree Root = MakeTree();
    105     printf("%d", Root->Element);
    106 }
    View Code

    首先 我发现了 我刚开始数据输入就不对 格式什么都不匹配 再者 也想不出什么算法来。。。

  • 相关阅读:
    【2020Python修炼记】网络编程(三)socket编程之粘包
    2020python作业——scoket编程(一)
    月考二
    【2020Python修炼记】网络编程(二)socket编程之socket 的介绍+TCP/UDP
    Gym100889L
    poj3233
    upper_bound
    lower_bound
    Gym-102141E
    P1020 导弹拦截
  • 原文地址:https://www.cnblogs.com/57one/p/11423218.html
Copyright © 2011-2022 走看看