zoukankan      html  css  js  c++  java
  • 树和二叉树->其他(待完善)

    关于树和二叉树的部分,还有如下三个知识点,待以后时间更充裕的时候再回头完善。

    1 树与等价问题

    文字描述

    关于等价关系和等价类的定义,在离散数学上的描述有点拗口, 其实在数据结构中,这部分相关的主要是如下三个函数:

     

    示意图

     

    算法分析:

     

    代码实现

      1 //
      2 // Created by lady on 18-12-15.
      3 //
      4 
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 #define MAX_TREE_SIZE 20
     10 
     11 typedef char TElemType;
     12 
     13 /*
     14  * 树的双亲表示法
     15  *
     16  * 以一组连续空间存储树的结点,同时在每个结点中附设一个指示器指示其双亲结点在链表中的位置。
     17  */
     18 //结点结构
     19 typedef struct PTNode{
     20     //结点的数据域
     21     TElemType data;
     22     //结点的双亲位置域
     23     int parent;
     24 }PTNode;
     25 //树的结构
     26 typedef struct{
     27     //树的结点
     28     PTNode node[MAX_TREE_SIZE];
     29     //树的根的位置
     30     int r;
     31     //树的结点数
     32     int n;
     33 }PTree;
     34 
     35 static void printMFSet(PTree *S)
     36 {
     37     printf("打印以树的双亲表示法表示的树:
    ");
     38     printf("树的结点数: %d
    ", S->n);
     39     printf("树的根的位置: %d
    ", S->r);
     40     int i = 0;
     41     for(i=0; i<=S->n; i++)
     42     {
     43         printf("index %d: (data %c, parent %d)
    ", i, S->node[i].data, S->node[i].parent);
     44     }
     45     printf("
    ");
     46 }
     47 
     48 //初始化操作, 构造一个由n个子集(每个子集只含单个成员xi)构成的集合S。
     49 static int initialMFSet(PTree *S)
     50 {
     51     printf("构造一个由n个子集(每个子集只含单个成员xi)构成的集合S:
    ");
     52     printf("输入n的值:");
     53     char tmp[10] = {0};
     54     scanf("%d", &S->n);
     55     int i = 0;
     56     for(i=0; i<S->n; i++)
     57     {
     58         printf("输入第%d个子集的值:", i+1);
     59         memset(tmp, 0, sizeof(tmp));
     60         scanf("%s", tmp);
     61         S->node[i+1].data = tmp[0];
     62         S->node[i+1].parent = -1;
     63     }
     64     S->r = 0;
     65     printf("
    ");
     66     return 0;
     67 }
     68 
     69 /* param1 S: S是已存在的集合
     70  * param2 data: x是S中某个子集的成员
     71  * result: 查找函数,确定S中x所属子集Si
     72  */
     73 static int findMFSet(PTree *S, TElemType data)
     74 {
     75     int i = 0;
     76     int j = 0;
     77     int loc = -1;
     78     for(i=1; i<=S->n; i++){
     79         if(S->node[i].data == data){
     80             loc = i;
     81             break;
     82         }
     83     }
     84     if(loc < 0){
     85         printf("数据data:%c在S集合中不存在!
    ", data);
     86         return -1;
     87     }
     88     for(j=i; S->node[j].parent>0; j=S->node[j].parent);
     89     return j;
     90 }
     91 
     92 //data_i和data_j所在的子集互不相交,
     93 static int mergeMFSet(PTree *S, TElemType data_i, TElemType data_j)
     94 {
     95     int loc_i = -1, loc_j = -1;
     96     if((loc_i=findMFSet(S, data_i)) < 0){
     97         return -1;
     98     }
     99     if((loc_j=findMFSet(S, data_j)) < 0){
    100         return -1;
    101     }
    102 
    103     if(S->node[loc_i].parent > S->node[loc_j].parent){
    104         //data_i所在子集的数目比data_j所在子集的数目少
    105         S->node[loc_j].parent += S->node[loc_i].parent;
    106         S->node[loc_i].parent = loc_j;
    107     }else{
    108         S->node[loc_i].parent += S->node[loc_j].parent;
    109         S->node[loc_j].parent = loc_i;
    110     }
    111     return 0;
    112 }
    113 
    114 //确定data所在子集,并交data所在index到根路径上所有结点都变成根的孩子结点。
    115 static int fixMFSet(PTree *S, TElemType data)
    116 {
    117     int index = -1;
    118     int parent = -1;
    119     int t = 0;
    120     int k = 0;
    121     for(t=1; t<=S->n; t++){
    122         if(S->node[t].data == data){
    123             index = t;
    124             break;
    125         }
    126     }
    127     if(index < 0)
    128         return ;
    129     for(parent=index; S->node[parent].parent>0; parent=S->node[parent].parent);
    130     for(k=index; k!=parent; k=t){
    131         t = S->node[k].parent;
    132         S->node[k].parent = parent;
    133     }
    134 }
    135 
    136 int main(int argc, char *argv[])
    137 {
    138     PTree S;
    139     initialMFSet(&S);
    140     printMFSet(&S);
    141 
    142 
    143     printf("创建等价类:
    ");
    144     char tmp[10] = {0};
    145     TElemType dataI, dataJ;
    146     while(1){
    147         memset(tmp, 0, sizeof(tmp));
    148         printf("输入一对数据,(0,0)表示结束:");
    149         scanf("%s", tmp);
    150         sscanf(tmp, "%c,%c", &dataI, &dataJ);
    151         if(mergeMFSet(&S, dataI, dataJ) < 0){
    152             break;
    153         }else{
    154             printMFSet(&S);
    155         }
    156     }
    157     printf("
    ");
    158 
    159     printf("现开始压缩路径, 输入要压缩的结点值: ");
    160     memset(tmp, 0, sizeof(tmp));
    161     scanf("%s", tmp);
    162     fixMFSet(&S, tmp[0]);
    163     printMFSet(&S);
    164     return 0;
    165 }
    树与等价类

    代码运行

    /home/lady/CLionProjects/untitled/cmake-build-debug/untitled
    构造一个由n个子集(每个子集只含单个成员xi)构成的集合S:
    输入n的值:9
    输入第1个子集的值:1
    输入第2个子集的值:2
    输入第3个子集的值:3
    输入第4个子集的值:4
    输入第5个子集的值:5
    输入第6个子集的值:6
    输入第7个子集的值:7
    输入第8个子集的值:8
    输入第9个子集的值:9
    
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -1)
    index 2: (data 2, parent -1)
    index 3: (data 3, parent -1)
    index 4: (data 4, parent -1)
    index 5: (data 5, parent -1)
    index 6: (data 6, parent -1)
    index 7: (data 7, parent -1)
    index 8: (data 8, parent -1)
    index 9: (data 9, parent -1)
    
    创建等价类:
    输入一对数据,(0,0)表示结束:1,2
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -2)
    index 2: (data 2, parent 1)
    index 3: (data 3, parent -1)
    index 4: (data 4, parent -1)
    index 5: (data 5, parent -1)
    index 6: (data 6, parent -1)
    index 7: (data 7, parent -1)
    index 8: (data 8, parent -1)
    index 9: (data 9, parent -1)
    
    输入一对数据,(0,0)表示结束:3,4
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -2)
    index 2: (data 2, parent 1)
    index 3: (data 3, parent -2)
    index 4: (data 4, parent 3)
    index 5: (data 5, parent -1)
    index 6: (data 6, parent -1)
    index 7: (data 7, parent -1)
    index 8: (data 8, parent -1)
    index 9: (data 9, parent -1)
    
    输入一对数据,(0,0)表示结束:5,6
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -2)
    index 2: (data 2, parent 1)
    index 3: (data 3, parent -2)
    index 4: (data 4, parent 3)
    index 5: (data 5, parent -2)
    index 6: (data 6, parent 5)
    index 7: (data 7, parent -1)
    index 8: (data 8, parent -1)
    index 9: (data 9, parent -1)
    
    输入一对数据,(0,0)表示结束:7,8
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -2)
    index 2: (data 2, parent 1)
    index 3: (data 3, parent -2)
    index 4: (data 4, parent 3)
    index 5: (data 5, parent -2)
    index 6: (data 6, parent 5)
    index 7: (data 7, parent -2)
    index 8: (data 8, parent 7)
    index 9: (data 9, parent -1)
    
    输入一对数据,(0,0)表示结束:1,3
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -4)
    index 2: (data 2, parent 1)
    index 3: (data 3, parent 1)
    index 4: (data 4, parent 3)
    index 5: (data 5, parent -2)
    index 6: (data 6, parent 5)
    index 7: (data 7, parent -2)
    index 8: (data 8, parent 7)
    index 9: (data 9, parent -1)
    
    输入一对数据,(0,0)表示结束:5,7
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -4)
    index 2: (data 2, parent 1)
    index 3: (data 3, parent 1)
    index 4: (data 4, parent 3)
    index 5: (data 5, parent -4)
    index 6: (data 6, parent 5)
    index 7: (data 7, parent 5)
    index 8: (data 8, parent 7)
    index 9: (data 9, parent -1)
    
    输入一对数据,(0,0)表示结束:1,5
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -8)
    index 2: (data 2, parent 1)
    index 3: (data 3, parent 1)
    index 4: (data 4, parent 3)
    index 5: (data 5, parent 1)
    index 6: (data 6, parent 5)
    index 7: (data 7, parent 5)
    index 8: (data 8, parent 7)
    index 9: (data 9, parent -1)
    
    输入一对数据,(0,0)表示结束:0,0
    数据data:0在S集合中不存在!
    
    现开始压缩路径, 输入要压缩的结点值: 8
    打印以树的双亲表示法表示的树:
    树的结点数: 9
    树的根的位置: 0
    index 0: (data  , parent -1208980472)
    index 1: (data 1, parent -8)
    index 2: (data 2, parent 1)
    index 3: (data 3, parent 1)
    index 4: (data 4, parent 3)
    index 5: (data 5, parent 1)
    index 6: (data 6, parent 5)
    index 7: (data 7, parent 1)
    index 8: (data 8, parent 1)
    index 9: (data 9, parent -1)
    
    
    Process finished with exit code 0
    示意图中的例子的代码实现

    2 回溯法与树的遍历

    3 树的计数

  • 相关阅读:
    LeetCode 1245. Tree Diameter
    LeetCode 1152. Analyze User Website Visit Pattern
    LeetCode 1223. Dice Roll Simulation
    LeetCode 912. Sort an Array
    LeetCode 993. Cousins in Binary Tree
    LeetCode 1047. Remove All Adjacent Duplicates In String
    LeetCode 390. Elimination Game
    LeetCode 1209. Remove All Adjacent Duplicates in String II
    LeetCode 797. All Paths From Source to Target
    LeetCode 1029. Two City Scheduling
  • 原文地址:https://www.cnblogs.com/aimmiao/p/9469947.html
Copyright © 2011-2022 走看看