前文提到树与二叉树,二叉树及其子类作为常用的数据结构还是要多提一提。树的遍历方式主要分为深度优先及广度优先。而深度优先又分为中序遍历、后序遍历和前序遍历,加上广度优先也就是层次遍历,这里手写一下这四种遍历的实现。然后作为实习进行一次二叉树的图形化控制台输出好了。
1.深度优先遍历
1.1前序遍历:
public void preOrder(Node node)
{
System.out.println(node.val); //先将根节点存入list
//如果左子树不为空继续往左找,在递归调用方法的时候一直会将子树的根存入list,这就做到了先遍历根节点
if(node.leftChild != null)
{
preOrder(node.leftChild);
}
//无论走到哪一层,只要当前节点左子树为空,那么就可以在右子树上遍历,保证了根左右的遍历顺序
if(node.rightChild != null)
{
preOrder(node.rightChild);
}
}
2.中序遍历
private void lterator(Node node){
if (node.leftChild!=null) {
lterator(node.leftChild);
}
System.out.println(node.val);
if (node.rightChild!=null) {
lterator(node.rightChild);
}
}
3.后序遍历:
public void afterOrder(Node node)
{
//如果左子树不为空继续往左找,在递归调用方法的时候一直会将子树的根存入list,这就做到了先遍历根节点
if(node.leftChild != null)
{
preOrder(node.leftChild);
}
//无论走到哪一层,只要当前节点左子树为空,那么就可以在右子树上遍历,保证了根左右的遍历顺序
if(node.rightChild != null)
{
preOrder(node.rightChild);
}
System.out.println(node.val); //将根节点输出
}
???,看起来这三种深度遍历的方法都差不多嘛,区别无非是查找后序节点与获取节点值之间的顺序区别?虽然我也是这么想的,但是并不完全如此。至少在二叉查找树(任一节点的左节点始终小于右节点)的情况下,中序遍历根据遍历的方向可以获取从小到大或从大到小的元素集,而且时间复杂度仅为O(log(n))。而后序遍历也有他的优点,因为在处理节点之前已经缺点处理过了该节点的左右两子节点,所以后序遍历适用于删除所有节点这一类的操作。
2,广度优先遍历:
public ArrayDeque<Node> levelOrderTraversal() {
if (root == null) {
System.out.println("empty tree");
return null;
}
ArrayDeque<Node> queue = new ArrayDeque<>();
ArrayDeque<Node> result = new ArrayDeque<>();
queue.add(root);
while (queue.isEmpty() == false) {
Node node = queue.remove();
result.push(node);
if (node.leftChild != null) {
queue.add(node.leftChild);
}
if (node.rightChild != null) {
queue.add(node.rightChild);
}
}
return result;
}
如上所示,广度优先情况下,会先遍历该层所有的左右节点,将其放入队列中,然后进行循环,在处理掉队列中所有元素(也就是该层所有的子节点)之后,才会遍历下一层。
那么我们可以使用这个广度优先遍历的方法遍历树并图形化输出到控制台,emmm想要显示的好看意外的难,反正意思是这个意思,等我看其他几种树的时候回优化一下:
@Override
public String toString() {
ArrayDeque<Node> elements=levelOrderTraversal();
if (elements==null){
return null;
}
int height=elements.getFirst().height;
String[] lines=new String[height+1];
int[] rightCounts=new int[height+1];
// StringBuilder sb=new StringBuilder();
while (!elements.isEmpty()){
Node temp=elements.pollLast();
if (lines[temp.height]==null){
lines[temp.height]=getInterval(height+temp.right)+ temp.val;
rightCounts[temp.height]=temp.right;
}
else {
lines[temp.height]=lines[temp.height]+getInterval(temp.right-rightCounts[temp.height])+ temp.val;
}
}
String result="";
for (String string:lines){
result+=string+"\r\n";
}
return result;
}
String getInterval(int number){
if (number<=0){
return "";
}else {
StringBuilder sb=new StringBuilder();
for (int i=1;i<=number;i++){
sb.append(" ");
}
return sb.toString();
}
}