简介
下面包括大量的二叉树的数据结构算法,包括各种遍历,深度计算,创建二叉树等等,且几乎都有递归和非递归的实现手段
Java 实现
// 结点
class Node {
int data;
Node left = null;
Node right = null;
}
// 二叉树
public class BinaryTree {
// 根结点
private Node root;
// 输入的数组
private int[] arr_in;
// 输出的数组
private int[] arr_out;
// 记录数组下标
private static int index;
// 初始化
public BinaryTree(int[] arr) {
root = new Node();
this.arr_in = arr;
arr_out = new int[arr.length];
index = 0;
}
// 根据先序遍历和中序遍历创建二叉树
public Node createByPreAndIn(int[] preArr, int[] inArr) {
if (preArr.length > 0) {
Node node = new Node();
node.data = preArr[0];
int i;
for (i = 0; preArr[0] != inArr[i]; i++) ;
// 中序左子树
int[] leftInArr = new int[i];
// 中序右子树
int[] rightInArr = new int[inArr.length - i - 1];
// 先序左子树
int[] leftPreArr = new int[i];
// 先序右子树
int[] rightPreArr = new int[inArr.length - i - 1];
System.arraycopy(inArr, 0, leftInArr, 0, leftInArr.length - 1);
System.arraycopy(inArr, i + 1, rightInArr, 0, rightInArr.length - 1);
System.arraycopy(preArr, 1, leftPreArr, 0, leftPreArr.length - 1);
System.arraycopy(preArr, i + 1, rightInArr, 0, rightPreArr.length - 1);
node.left = createByPreAndIn(leftPreArr, leftInArr);
node.right = createByPreAndIn(rightPreArr, rightInArr);
return node;
}
else
return null;
}
// 根据中序遍历和后序遍历创建二叉树
public Node createByInAndPost(int[] inArr, int[] postArr) {
if (inArr.length > 0) {
Node node = new Node();
node.data = postArr[postArr.length];
int i;
for (i = 0; postArr[postArr.length] != inArr[i]; i++) ;
// 中序左子树
int[] leftInArr = new int[i];
// 中序右子树
int[] rightInArr = new int[inArr.length - i - 1];
// 后序左子树
int[] leftPostArr = new int[i];
// 后序右子树
int[] rightPostArr = new int[inArr.length - i - 1];
System.arraycopy(inArr, 0, leftInArr, 0, leftInArr.length - 1);
System.arraycopy(inArr, i + 1, rightInArr, 0, rightInArr.length - 1);
System.arraycopy(postArr, 0, leftPostArr, 0, leftPostArr.length - 1);
System.arraycopy(postArr, i, rightPostArr, 0, rightPostArr.length - 1);
node.left = createByInAndPost(leftInArr, leftPostArr);
node.right = createByInAndPost(rightInArr, rightPostArr);
return node;
}
else
return null;
}
// 先序遍历二叉树(递归)根→左→右
public int[] preorderTraversalRecursion(Node r) {
if (r) {
arr_out[index++] = r.data;
preorderRecursion(r.left, index);
preorderRecursion(r.rigth, index);
}
if (index == arr_in.length)
index = 0;
return arr_out;
}
// 先序遍历二叉树(非递归)根→左→右
public int[] preorderTraversal(Node r) {
Stack stack = new Stack();
Node node = r;
while (!stack.empty() || node) {
if (node) {
stack.push(node);
// 根
arr_out[index++] = node.data;
// 左
node = node.left;
}
else {
Node top = stack.pop();
// 右
node = top.right;
}
}
index = 0;
return arr_out;
}
// 中序遍历二叉树(递归)左→根→右
public int[] inorderTraversalRecursion(Node r) {
if (r) {
inorderRecursion(r.left, index);
arr_out[index++] = r.data;
inorderRecursion(r.rigth, index);
}
if (index == arr_in.length)
index = 0;
return arr_out;
}
// 中序遍历二叉树(非递归)左→根→右
public int[] inorderTraversal(Node r) {
Stack stack = new Stack();
Node node = r;
while (!stack.empty() || node) {
if (node) {
stack.push(node);
// 左
node = node.left;
}
else {
Node top = stack.pop();
// 根
arr_out[index++] = top.data;
// 右
node = top.right;
}
}
index = 0;
return arr_out;
}
// 后序遍历二叉树(递归)左→右→根
public int[] postorderTraversalRecursion(Node r) {
if (r) {
postorderRecursion(r.left, index);
postorderRecursion(r.rigth, index);
arr_out[index++] = r.data;
}
if (index == arr_out.length)
index = 0;
return arr_out;
}
// 后序遍历二叉树(非递归)左→右→根
public int[] postorderTraversal(Node r) {
Stack stack = new Stack();
Node node = r;
Node top;
while (!stack.empty() || node) {
if (node) {
stack.push(node);
// 左
node = node.left;
}
else {
if (stack.peek().right != null && stack.peek().right != top)
// 右
node = stack.peek().right;
else {
top = stack.pop();
// 根
arr_out[index++] = top.data;
node = stack.peek();
}
}
}
index = 0;
return arr_out;
}
// 层次遍历二叉树(递归)
public int[] levelTraversalRecursion(ArrayList al) {
ArrayList arrayList = new ArrayList();
for(Node n : al) {
arr_out[index++] = n.data;
if (n.left)
arrayList.add(n.left);
if (n.right)
arrayList.add(n.right);
}
if(!arrayList.isEmpty())
levelTraversalRecursion(arrayList);
if(index == arr_out.length)
index = 0;
return arr_out;
}
// 层次遍历二叉树
public int[] levelTraversal(Node r) {
if(r == null)
return null;
else {
Queue queue = new LinkedList();
Node node = r;
queue.add(node);
while(!LinkedList.isEmpty()) {
Node top = queue.remove();
arr_out[index++] = top.data;
if (top.left)
queue.add(top.left);
if (top.right)
queue.add(top.right);
}
index = 0;
return arr_out;
}
}
// 先序复制二叉树(递归)根→左→右
public Node preorderCopyRecursion(Node r, Node n) {
if (r) {
n = new Node();
n = r.data;
preorderCopyRecursion(r.left, n.left);
preorderCopyRecursion(r.right, n.right);
}
else
n = null;
return n;
}
// 先序复制二叉树(非递归)根→左→右
public Node preorderCopy(Node r, Node n) {
Stack rStack = new Stack();
Stack nStack = new Stack();
Node rNode = r;
Node nNode = n;
while (rNode || !rStack.empty()) {
if (rNode) {
rStack.push(rNode);
nNode = new Node();
nStack.push(nNode);
// 根
nNode.data = rNode.data;
// 左
rNode = rNode.left;
nNode = nNode.left;
}
else {
Node rTop = rStack.pop();
Node nTop = nStack.pop();
// 右
rNode = rTop.right;
nNode = nTop.right;
}
}
return n;
}
// 中序复制二叉树(递归)左→根→右
public Node inorderCopyRecursion(Node r, Node n) {
if (r) {
inorderCopyRecursion(r.left, n.left);
n = new Node();
n = r.data;
inorderCopyRecursion(r.right, n.right);
}
else
n = null;
return n;
}
// 中序复制二叉树(非递归)左→根→右
public Node inorderCopy(Node r, Node n) {
Stack rStack = new Stack();
Stack nStack = new Stack();
Node rNode = r;
Node nNode = n;
while (rNode || !rStack.empty()) {
if (rNode) {
rStack.push(rNode);
nNode = new Node();
nStack.push(nNode);
// 左
rNode = rNode.left;
nNode = nNode.left;
}
else {
Node rTop = rStack.pop();
Node nTop = nStack.pop();
// 根
nTop.data = rTop.data;
// 右
rNode = rNode.right;
nNode = nNode.right;
}
}
return n;
}
// 后序复制二叉树(递归)左→右→根
public Node postorderCopyRecursion(Node r, Node n) {
if (r) {
postorderCopyRecursion(r.left, n.left);
postorderCopyRecursion(r.right, n.right);
n = new Node();
n = r.data;
}
else
n = null;
return n;
}
// 后序复制二叉树(非递归)左→右→根
public Node postorderCopy(Node r, Node n) {
Stack rStack = new Stack();
Stack nStack = new Stack();
Node rNode = r;
Node nNode = n;
Node rTop;
Node nTop;
while (rNode || !rStack.empty()) {
if (rNode) {
rStack.push(rNode);
rNode = new Node();
rStack.push(rNode);
// 左
rNode = rNode.left;
nNode = nNode.left;
}
else {
if (rStack.peek().right != null && rStack.peek().right != rTop) {
// 右
rNode = rNode.right;
nNode = nNode.right;
}
else {
rTop = rStack.pop();
nTop = nStack.pop();
// 根
nTop.data = rTop.data;
rNode = rStack.peek();
nNode = nStack.peek();
}
}
}
return n;
}
// 得到二叉树根结点
public Node getRoot() {
return root;
}
// 二叉树深度(递归)
public int getDepthRecursion(Node r) {
if (r) {
int m = getDepthRecursion(r.left);
int n = getDepthRecursion(r.right);
return (m>=n)?(m+1):(n+1);
}
else
return 0;
}
// 二叉树深度(非递归)
public int getDepth(Node r) {
Stack stack = new Stack();
Node node = r;
Node top;
int depth = 0;
int maxDepth = 0;
while(node || !stack.empty()) {
if (node) {
stack.push(node);
depth++;
if (depth > maxDepth)
maxDepth = depth;
node = node.left;
}
else {
if (stack.peek().right && stack.peek().right != top)
node = stack.peek().right();
else {
top = stack.pop();
depth--;
node = stack.peek();
}
}
}
return maxDepth;
}
// 得到二叉树结点的个数(递归)
public int getNodesNumber(Node r) {
if (r)
return getNodesNumber(r.left) + getNodesNumber(r.right) + 1;
else
return 0;
}
// 得到二叉树结点的个数(非递归)
public int getNodesNumber(Node r) {
Stack stack = new Stack();
Node node = r;
int count = 0;
if (node) {
stack.push(node);
count++;
node = node.left
}
else {
Node top = stack.pop();
node = top.right;
}
return count;
}
// 得到二叉树叶子结点的个数(递归)
public int getLeafCountRecursion(Node r) {
if (r.left == null && r.right == null)
return 1;
else
return getLeafCountRecursion(r.left) + getLeafCountRecursion(r.right);
}
// 得到二叉树叶子结点的个数(非递归)
public int getLeafCount(Node r) {
Stack stack = new Stack();
Node node = r;
int leaf = 0;
while (r || !stack.empty()) {
if (r.left != null || r.right != null) {
stack.push(node);
node = r.left;
}
else {
leaf++;
node = stack.pop().right;
}
}
return leaf;
}
// 得到二叉树非叶子结点的个数(递归)
public int getNonleafCountRecursion(Node r) {
// 左右两个结点都是 null,此结点必为叶子
if (r.left == null && r.right == null)
return 0;
else
return getNonleafCount(r.left) + getNonleafCount(r.right) + 1;
}
// 得到二叉树非叶子结点的个数(非递归)
public int getNonleafCount(Node r) {
Stack stack = new Stack();
Node node = r;
int nonleaf = 0;
while (node || !stack.empty()) {
if (node.left != null || node.right != null) {
stack.push(node);
nonleaf++;
node = node.left;
}
else
node = stack.pop().right;
}
return nonleaf;
}
}