树采用顺序数组方式存储,从下表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