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

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

  • 相关阅读:
    LeetCode 40. 组合总和 II(Combination Sum II)
    LeetCode 129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers)
    LeetCode 60. 第k个排列(Permutation Sequence)
    LeetCode 47. 全排列 II(Permutations II)
    LeetCode 46. 全排列(Permutations)
    LeetCode 93. 复原IP地址(Restore IP Addresses)
    LeetCode 98. 验证二叉搜索树(Validate Binary Search Tree)
    LeetCode 59. 螺旋矩阵 II(Spiral Matrix II)
    一重指针和二重指针
    指针的意义
  • 原文地址:https://www.cnblogs.com/57one/p/11423218.html
Copyright © 2011-2022 走看看