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 树的计数

  • 相关阅读:
    欧拉法求乘率
    利用连分数求乘率
    反乘率
    乘率
    别害怕暂时的迷茫
    别害怕心中的理想
    HDU6072 Logical Chain
    P3345 [ZJOI2015]幻想乡战略游戏
    P4449 于神之怒加强版
    [笔记] 拉格朗日插值法
  • 原文地址:https://www.cnblogs.com/aimmiao/p/9469947.html
Copyright © 2011-2022 走看看