树的文本实现

树采用顺序数组方式存储,从下表0开始存储,i的左孩子是2 * i + 1,右孩子是2 * i + 2

  1 template<typename ElementType>
  2 std::ostream& operator << (std::ostream& out, const MySeqTree<ElementType>& item)
  3 {
  4     /*二叉树的文本输出*/
  5     int lay = item.getFinalIndex();        //获取最后一个结点在数组中的下标
  6     int j, d;        //循环变量
  7     int nhigh, gap;        //当前树的深度,计算结点间距的变量
  8     
  9     SqQueue<SqNode> queue(33);        //给队列设置长度,为33
 10     if (lay == -1)
 11     {
 12         out << "\t当前树为空" << endl;
 13         return out;
 14     }
 15     SqNode  SN, SN2;
 16     SN.dt = item.getNode(0);
 17     SN.index = 0;
 18     /*计算顺序存储的树的深度*/
 19     int depth, num = 1;
 20     for (depth = 0; num - 1<= lay; depth++)
 21         num *= 2;
 22     
 23     nhigh = depth;
 24 
 25     /*第一层结点进队列*/
 26     queue.enQueue(SN);
 27     SqNode end;                    //一个end结点
 28     end.dt = '#';
 29     queue.enQueue(end);                    //用‘#'代表层结束
 30 
 31     for (d = nhigh; d >= 1; d--)        //从第一层根开始输出到最后一层
 32     {
 33         //层循环开始
 34         for (gap = 1,  j = 0; j < d - 1; ++j)
 35             gap *= 2;                //计算2^(n-1)
 36         out << "\t";
 37         //输出结点数据的循环体
 38         for (;;)
 39         {
 40             //一层的结点数据输出开始
 41             queue.deQueue(SN);
 42             queue.enQueue(SN);
 43             if (SN.dt == end.dt)
 44                 break;                //如果是结束符号end,该层数据输出结束, 退出
 45             for (j = 0; j < 2 * gap - 2; ++j)        //输出2^(n + 1) - 2个空格
 46                 out << ' ';
 47             out << ((SN.dt != '0') ? SN.dt : ' ');        //输出数据或空格
 48             for (j = 0; j < 2 * gap + 1; ++j)
 49                 out << ' ';                            //输出2^(n + 1) + 1个空格
 50         }
 51 
 52         out << endl;            //一层的结点数据输出结束,回车
 53         if (d == 1) break;                //如果是最后一层,不用输出下面的链接字符
 54 
 55         out << "\t";
 56         /*第二步,输出每层结点与其子结点的第一行链接字符*/
 57         for (;;)
 58         {
 59             queue.deQueue(SN);
 60             queue.enQueue(SN);
 61             if (SN.dt == end.dt)
 62                 break;
 63             for (j = 0; j < (d != 2 ? gap : gap - 1); ++j)    //输出2^n个空格或2^n - 1(倒数第二层)个空格
 64                 out << " ";
 65             for (j = 0; j < gap - 3; ++j)
 66                 out << (SN.dt != '0' && (SN.index * 2 + 1 <= lay) && item.getNode(SN.index * 2 + 1) != '0' 
 67                 ? '_' : ' ');        //为左子结点连接符输出'_'或空格
 68             out << ((SN.dt != '0' && (SN.index * 2 + 1 <= lay) && item.getNode(SN.index * 2 + 1) != '0')
 69                 ? '/' : ' ');        //为左子结点连接符输出'/'或空格
 70             out << " ";            //输出一个空格
 71 
 72             out << ((SN.dt != '0' && (SN.index * 2 + 2 <= lay) && item.getNode(SN.index * 2 + 2) != '0')
 73                 ? '\\' : ' ');        //为右子结点连接符输出'\'或空格
 74 
 75             for (j = 0; j < gap - 3; ++j)
 76                 out << ((SN.dt != '0' && (SN.index * 2 + 2 <= lay) && item.getNode(SN.index * 2 + 2) != '0')
 77                 ? '_' : ' ');        //为右子结点连接符输出'_'或空格
 78 
 79             for (j = 0; j < (d != 2 ? gap + 3 : gap + 2); j++)
 80                 out << " ";                //输出2^n + 3个空格或2^n+ 2(倒数第二层)个空格
 81             
 82         }
 83         out << endl;
 84 
 85         /*第三步,输出每层结点与其子结点的第二行链接字符*/
 86         if (d != 2)
 87         {
 88             out << "\t";
 89             for (;;)
 90             {
 91                 queue.deQueue(SN);
 92                 queue.enQueue(SN);
 93                 if (SN.dt == end.dt)
 94                     break;
 95                 for (j = 0; j < gap - 1; ++j)    //输出2^n - 1个空格
 96                     out << " ";
 97 
 98                 out << (SN.dt != '0' && (SN.index * 2 + 1 <= lay) && item.getNode(SN.index * 2 + 1) != '0'
 99                     ? '/' : ' ');        //为左子结点连接符输出'_'或空格
100 
101                 for (j = 0; j < 2 * gap - 3; ++j)    //输出2^(n + 1) - 3个空格
102                     out << " ";
103 
104                 out << (SN.dt != '0' && (SN.index * 2 + 2 <= lay) && item.getNode(SN.index * 2 + 2) != '0'
105                     ? '\\' : ' ');        //为右子结点连接符输出'\'或空格
106 
107 
108                 for (j = 0; j < gap + 2; j++)
109                     out << " ";                //输出2^n+ 2个空格
110 
111             }
112             out << endl;
113         }
114             
115 
116             /*第四步,更新队列中的结点,即把队列中的结点换成下一层的结点*/
117             for (;;)
118             {
119                 /*上一层的循环结束后,队列中的结点回复到循环前的状况*/
120                 queue.deQueue(SN);
121                 if (SN.dt == end.dt)
122                     break;
123                 if (SN.index * 2 + 1 <= lay)
124                 {
125                     SN2.dt = item.getNode(SN.index * 2 + 1);
126                     SN2.index = SN.index * 2 + 1;
127                     queue.enQueue(SN2);
128                 }
129 
130                 if (SN.index * 2 + 2 <= lay)
131                 {
132                     SN2.dt = item.getNode(SN.index * 2 + 2);
133                     SN2.index = SN.index * 2 + 2;
134                     queue.enQueue(SN2);
135 
136                 }
137 
138             }
139             queue.enQueue(end);
140 
141         }
142 
143     return out;
144 }

效果图片:

树的文本实现       树的文本实现

参考文章:http://www.doc88.com/p-7136117098724.html

上一篇:leetcode hot 100-33. 搜索旋转排序数组


下一篇:Paxos Made Simple(译)