实验目的——通过实验达到:
⑴ 理解和掌握树及二叉树的基本概念;
⑵ 理解和掌握二叉树的顺序存储结构、链式存储结构;
⑶ 理解和掌握采用二叉链式存储结构下二叉树的各种遍历操作的思想及其应用;
⑷ 加深对堆栈、队列的概念及其典型操作思想的理解;
⑸ 掌握典型二叉树操作算法的算法分析。
题目:二叉树的建立、遍历及其应用
设树结点的元素类型为char,实现以下二叉树的各种基本操作的程序:
① 建立不少于10个结点的二叉树T;
②用后序遍历方式输出树T的结点;
③用层次遍历方式输出树T的结点;
④输出树T的深度;
⑤输出树T的叶子结点和非叶子结点;
⑥主函数通过函数调用实现以上各项操作。
⑴ 所定义的数据结构:
class node{
char data;//值
node l=null;//左子树
node r=null;//右子树
//初始化
node(){
}
node(char c){
this.data=c;
}
node(char c,node l,node r){
this.data=c;
this.l=l;
this.r=r;
}
}
⑵ 主要操作算法思想或算法步骤:
package edu.dgut.experiment.two;
import java.util.LinkedList;
import java.util.Queue;
class node{
char data;//值
node l=null;//左子树
node r=null;//右子树
//初始化
node(){
}
node(char c){
this.data=c;
}
node(char c,node l,node r){
this.data=c;
this.l=l;
this.r=r;
}
}
public class Tree {
node root=null;
/**
* 根据数组创建二叉树
* @param c 字符数组
* @param i 下标
*/
public Tree(char[] c,int i){
createTree(root,c,i);
}
int i=0;
private node createTree(node root,char[] c,int i) {
root = new node();
if(i<c.length) {
if(c[i]=='\0') {
return root=null;
}else {
node node1 = new node('\0');
node node2 = new node('\0');
root.data=c[i];
root.l=createTree(node1, c, ++i);
root.r=createTree(node2, c, ++i);
}
}
return root;
}
/**
* 根据广义表创建二叉树
* @param expression 广义表
*/
public Tree(String expression) {
createTree(expression);
}
private void createTree(String expression) {
// 使用 LinkedList 来执行栈的功能
LinkedList<node> stack = new LinkedList<node>();
node newnode = null;
int flag = 0; //flag = 0: 创建左子树 flag = 1: 创建右子树
for (char ch: expression.toCharArray()) {
switch (ch) {
//可能存在孩子结点,父结点入栈
case '(':
stack.push(newnode);
flag = 0;
break;
//父结点的右孩子操作完毕,父结点出栈
case ')':
stack.pop();
break;
//父结点的左孩子操作完毕,操作父结点的右孩子,即变为flag=1
case ',':
flag = 1;
break;
//若为结点的值,将其加入二叉树中
default:
newnode = new node(ch, null, null);
if (root == null) {
root = newnode;
}
else {
if (flag == 0) {
node topNode = stack.peek();
topNode.l=newnode;
}
else {
node topnode = stack.peek();
topnode.r=newnode;
}
}
break;
}
}
}
/**
* 后序遍历输出
*/
public void postOrderTraverse() {
System.out.print("后序遍历:");
this.postOrderTraverse(this.root);
System.out.println();
}
private void postOrderTraverse(node root) {
if (root != null) {
this.postOrderTraverse(root.l);
this.postOrderTraverse(root.r);
System.out.print(root.data + " ");
}
}
/**
* 层序遍历输出
*/
public void LevelTraversal() {
System.out.print("层次遍历:");
//创建队列
Queue<node> queue = new LinkedList<>();
//判空,是否根节点入队
if (root == null) {
System.out.println("null");
return;
}else {
queue.add(this.root);
}
while (!queue.isEmpty()) {
//队列非空,出队,左右孩子入队
node node = queue.poll();
System.out.print(node.data + " ");
if (node.l!= null) {
queue.add(node.l);
}
if (node.r!= null) {
queue.add(node.r);
}
}
System.out.println();
}
public int getHeight() {
return this.getHeight(this.root);
}
private int getHeight(node root) {
if (root == null) {
//根结点为空,递归结束
return 0;
} else {
//左子树高度
int nl = this.getHeight(root.l);
//右子树高度
int nr = this.getHeight(root.r);
//取左右子树最高,再加上根结点
return nl > nr ? nl + 1 : nr + 1;
}
}
//输出树T的叶子结点和非叶子结点
public void leaf() {
System.out.print("叶子节点:");
leafNode(this.root);
System.out.println();
System.out.print("非叶子节点:");
notLeafNode(this.root);
}
private void leafNode(node root) {
if (root != null) {
if (root.l == null&&root.r==null) {
System.out.print(root.data+" ");
}
this.leafNode(root.l);
this.leafNode(root.r);
}
}
private void notLeafNode(node root) {
if (root != null) {
if (root.l!= null||root.r!=null) {
System.out.print(root.data+" ");
}
this.notLeafNode(root.l);
this.notLeafNode(root.r);
}
}
/**
* 测试主函数
* @param args
*/
public static void main(String[] args) {
//广义表
String s="(A(B(D(G,H),),C(E,F(I,J(K,)))))";
//根据广义表创建二叉树
Tree tree=new Tree(s);
//层序遍历
tree.LevelTraversal();
//后序遍历
tree.postOrderTraverse();
//深度
System.out.println("深度:"+tree.getHeight());
//输出树T的叶子结点和非叶子结点
tree.leaf();
}
}