二叉树的递归遍历:
先创建一个树结构类
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int v) {
value = v;
}
}
先,中,后序遍历
//先序遍历
public static void pre(Node head) {
if (head == null) {
return;
}
System.out.println(head.value);
pre(head.left);
pre(head.right);
}
//中序遍历
public static void in(Node head) {
if (head == null) {
return;
}
in(head.left);
System.out.println(head.value);
in(head.right);
}
//后序遍历
public static void pos(Node head) {
if (head == null) {
return;
}
pos(head.left);
pos(head.right);
System.out.println(head.value);
}
根据代码,我们可以看出二叉树的遍历顺序为:
先访问A,从头节点A出发,先递归左边B,访问B节点;继续递归-访问D节点;D节点递归,发现没有子节点,返回到D节点;然后再访问D节点的右节点,发现也没有字节点,又返回到D节点,再返回到B节点。
得出顺序为;
A-B-D-D-D-B-E-E-E-B-A-C-F-F-F-C-C-A
根据先序遍历顺序:ABDECF
中序遍历:DBEAFC
后序遍历:DEBFCA
我们可以看出,当第一次访问节点时就输出的是先序遍历,第二次访问节点再输出的是中序遍历,第三次访问节点再输出的后序遍历。
所以 System.out.println(head.value);输出语句的顺序就可以决定是先序,中序,还是后序遍历
二叉树的非递归调用:
在这里我们使用栈来实现
先序遍历
public static void pre(Node head) {
System.out.print("pre-order: ");
if (head != null) {//当二叉树存在意义才进行操作
Stack<Node> stack = new Stack<Node>();//创建一个栈来存储数据
stack.add(head);//首先将头节点进行压栈
while (!stack.isEmpty()) {//当栈里面有值,说明二叉树还没有遍历结束
head = stack.pop();//将值弹出
System.out.print(head.value + " ");
//这里是先先压右节点,再压左节点。
//因为栈是先进后出,最后输出的顺序是左节点,右节点
if (head.right != null) {
stack.push(head.right);//存在右将右节点压入栈
}
if (head.left != null) {
stack.push(head.left);//存在左节点则将左节点压入栈
}
}
}
System.out.println();
}
后序遍历:
//这里我们先遍历左孩子,再遍历右孩子。得到头-右-左。
//我们将它逆序就是左-右-头,这就是一个后序遍历。
//因为逆序的话,我们就需要两个栈才能完成
public static void pos1(Node head) {
System.out.print("pos-order: ");
if (head != null) {
Stack<Node> s1 = new Stack<Node>();
Stack<Node> s2 = new Stack<Node>();
s1.push(head);//一样先将头节点压栈
while (!s1.isEmpty()) {//栈里面有数据就循环
head = s1.pop();//弹出栈里面的数据
s2.push(head);//放到备用栈,用来逆序
//下面这些步骤和先序遍历一样,只是顺序不一样
if (head.left != null) {
s1.push(head.left);
}
if (head.right != null) {
s1.push(head.right);
}
}
while (!s2.isEmpty()) {
System.out.print(s2.pop().value + " ");
}
}
System.out.println();
}
中序遍历:
我们每次都先遍历左节点,并且遍历到第,直到它为空,再遍历右节点的左孩子。
类似这样子
public static void in(Node head) {
System.out.print("in-order: ");
if (head != null) {//二叉树有意义再进行操作
Stack<Node> stack = new Stack<Node>();//用来存放二叉树
while (!stack.isEmpty() || head != null) {
if (head != null) {//先将头节点最左侧的数据压栈
stack.push(head);
head = head.left;
} else {//当节点为空时,栈里面就弹出一个数据,
//并且head开始指向右节点,去遍历右节点中的左孩子
head = stack.pop();
System.out.print(head.value + " ");
head = head.right;
}
}
}
System.out.println();
}
问题描述,当输入一个能查到的数字时,再输入不能查到的数据时,
不能按照我们想要的结束循环,它会一直循环下去
/**
* 在数组{4,5,6,2,3,1,9,8,7,10,12,14,15}中查找元素
* (先打印输出所有元素,输入一个数,如果找到了则打印输出其位置,
* 没有找到则提示没有找到)
*/
public static void Test8(){
int count = 0;
int index = 0;
int arr[] = {4,5,6,2,3,1,9,8,7,10,12,14,15};
Scanner scanner = new Scanner(System.in);
System.out.println("数组中的数有:"+Arrays.toString(arr));
while(true){
System.out.println("请输入数字:");
int number = scanner.nextInt();
for (int i = 0; i < arr.length; i++) {
if(number==arr[i]){
System.out.println("能找到,它的下标为"+i);
count++;
}
}
if(count==0){
System.out.println("没有找到!");
break;
}
}
}
栈内操作为:
先获取头节点,压入栈内
问题所在:
当我们第一次输入正确的值时count++,此时count=1;当进行下一个循环时,count没有初始化,还是>0的数。所以后面无论再输入何数,count==0的条件都不会成立。我们在每次while循环的时候,都将count设置为0,这样就可以达到预期效果。
修改后的代码:
public static void Test8(){
int count = 0;
int index = 0;
int arr[] = {4,5,6,2,3,1,9,8,7,10,12,14,15};
Scanner scanner = new Scanner(System.in);
System.out.println("数组中的数有:"+Arrays.toString(arr));
while(true){
count = 0;
System.out.println("请输入数字:");
int number = scanner.nextInt();
for (int i = 0; i < arr.length; i++) {
if(number==arr[i]){
System.out.println("能找到,它的下标为"+i);
count++;
}
}
if(count==0){
System.out.println("没有找到!");
break;
}
}
}