using System.Collections;
using System.Collections.Generic;
using System.Text;
/// <summary>
/// 二分搜索树
/// </summary>
public class BST<T> where T : System.IComparable<T>
{
public class Node
{
public T data;
public Node left;
public Node right;
public Node(T data)
{
this.data = data;
left = null;
right = null;
}
}
private Node root;
private int _size;
public BST()
{
_size = 0;
root = null;
}
public int size()
{
return _size;
}
public bool isEnmpty()
{
return _size == 0;
}
public Node add(T data)
{
return root = add(root, data);
}
private Node add(Node node, T data)
{
if (node == null)
{
_size++;
return new Node(data);
}
if (data.CompareTo(node.data) < 0)
{
node.left = add(node.left, data);
}
else if (data.CompareTo(node.data) > 0)
{
node.right = add(node.right, data);
}
return node;
}
private void add2(T data)
{
if (root == null)
{
_size++;
root = new Node(data);
return;
}
var p = root;
while (p != null)
{
if (data.CompareTo(p.data) > 0)
{
if (p.right == null)
{
p.right = new Node(data);
_size++;
return;
}
p = p.right;
}
else if (data.CompareTo(p.data) < 0)
{
if (p.left == null)
{
p.left = new Node(data);
_size++;
return;
}
p = p.left;
}
else
{
return;
}
}
}
public bool Contains(T data)
{
return Contains(root, data);
}
private bool Contains(Node node, T data)
{
if (node == null)
{
return false;
}
if (data.CompareTo(node.data) == 0)
{
return true;
}
else if (data.CompareTo(node.data) < 0)
{
return Contains(node.left, data);
}
else
{
return Contains(node.right, data);
}
}
/// <summary>
/// 前序遍历
/// </summary>
public void preOcder()
{
preOcder(root);
}
private void preOcder(Node node)
{
if (node == null) return;
System.Console.WriteLine(node.data);
preOcder(node.left);
preOcder(node.right);
}
/// <summary>
/// 中序遍历
/// </summary>
private void inOrder()
{
inOrder(root);
}
private void inOrder(Node node)
{
if (node == null)
{
return;
}
inOrder(node.left);
System.Console.WriteLine(node.data);
inOrder(node.right);
}
/// <summary>
/// 后序遍历
/// </summary>
public void postOder()
{
postOder(root);
}
private void postOder(Node node)
{
if (node == null)
return;
postOder(node.left);
postOder(node.right);
System.Console.WriteLine(node.data);
}
/// <summary>
/// 非递归前序遍历 使用栈
/// </summary>
public void preOderNR()
{
Stack<Node> stack = new Stack<Node>();
stack.Push(root);
while (stack.Count != 0)
{
var curr = stack.Pop();
System.Console.WriteLine(curr.data);
if (curr.right != null)
stack.Push(curr.right);
if (curr.left != null)
stack.Push(curr.left);
}
}
/// <summary>
/// 层序遍历
/// /// </summary>
public void levelOrder()
{
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(root);
while (queue.Count != 0)
{
var curr = queue.Dequeue();
System.Console.WriteLine(curr.data);
if (curr.left != null)
queue.Enqueue(curr.left);
if (curr.right != null)
queue.Enqueue(curr.right);
}
}
public Node minNum()
{
if (_size == 0)
throw new System.Exception(" BSP is empty!");
return minNum(root);
}
private Node minNum(Node node)
{
if (node.left == null)
{
return node;
}
return minNum(node.left);
}
/// <summary>
/// 最大值
/// </summary>
/// <returns></returns>
public Node maxNum()
{
if (_size == 0)
throw new System.Exception(" BSP is empty!");
return maxNum(root);
}
private Node maxNum(Node node)
{
if (node.right == null)
{
return node;
}
return maxNum(node.right);
}
private void remove(T data)
{
root = remove(root, data);
}
/// <summary>
/// 删除以node为根的二分搜索树中 值为data的节点 递归因算
/// 返回删除节点后新的二分搜索树
/// </summary>
/// <param name="node"></param>
/// <param name="data"></param>
/// <returns></returns>
private Node remove(Node node, T data)
{
if (node == null) return null;
if (data.CompareTo(node.data) < 0)
{
node.left = remove(node.left, data);
return node;
}
else if (data.CompareTo(node.data) > 0)
{
node.right = remove(node.right, data);
return node;
}
else
{ //data== node.data
if (node.left == null)
{
Node rightnode = node.right;
node.right = null;
_size--;
return rightnode;
}
if (node.right == null)
{
Node leftNode = node.left;
leftNode.left = null;
_size--;
return leftNode;
}
/// <summary>
/// 待删除节点的左右子树均不为空
/// 找到比这个删除节点打的最小节点 即删除右子树的最小节点
/// 用这个节点顶替删除节点的位置
/// </summary>
/// <returns></returns>
Node successor = minNum(node.right);
successor.right = removeMin(node.right);
successor.left = node.left;
node.left = node.right = null;
return successor;
}
}
public T removeMin()
{
Node min = minNum();
root = removeMin(root);
return min.data;
}
/// <summary>
/// 删除 掉以node为根的二分搜索树中最小的节点
/// 但会删除节点以后 新的二分搜索树的跟
/// /// </summary>
/// <param name="node"></param>
/// <returns></returns>
private Node removeMin(Node node)
{
if (node.left == null)
{
Node rightNode = node.right;
node.right = null;
_size--;
return rightNode;
}
node.left = removeMin(node.left);
return node;
}
public T removeMax()
{
var max = maxNum();
System.Console.WriteLine("max :" + max);
root = removeMax(root);
return max.data;
}
private Node removeMax(Node node)
{
if (node.right == null)
{
Node leftNode = node.left;
node.left = null;
_size--;
return leftNode;
}
node.right = removeMax(node.right);
return node;
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
// stringBuilder.Append()
GenerateBSTString(root, 0, stringBuilder);
return stringBuilder.ToString();
}
private void GenerateBSTString(Node node, int depth, StringBuilder sb)
{
if (node == null)
{
sb.Append(generateDepthString(depth) + "null\n");
return;
}
sb.Append(generateDepthString(depth) + node.data + "\n");
GenerateBSTString(node.left, depth + 1, sb);
GenerateBSTString(node.right, depth + 1, sb);
// depth++;
}
private string generateDepthString(int depth)
{
StringBuilder stringBuilder = new StringBuilder();
for (var i = 0; i < depth; i++)
{
stringBuilder.Append(" -");
}
return stringBuilder.ToString();
}
}
static void TestBST()
{
int[] array = new int[] { 5, 4, 6, 7, 9, 2 };
BST<int> bST = new BST<int>();
for (var i = 0; i < array.Length; i++)
{
bST.add(array[i]);
}
// System.Console.WriteLine(bST.ToString());
var max = bST.removeMax();
var min = bST.removeMin();
System.Console.WriteLine("max :" + max + " min" + min);
// System.Console.WriteLine(bST.ToString());
}