目录
基本概念
二叉树是一种很好的排序应用模式,因为在建立二叉树的同时,数据已经经过初步的比较,并按照二叉树的建立规则来存放数据。其规则如下:
-
第一个输入数据作为此二叉树的树根。
-
之后的数据以递归的方式与树根进行比较,小于树根置于左子树,大于树根置于右子树。
代码实现二叉排序树
创建节点类
首先创建一个节点类,这个节点包含数据Data,左孩子Left的引用,右孩子Right的引用。
public class Node
{
public int Data;
public Node Left;
public Node Right;
public Node(int data)
{
Data = data;
Left = null;
Right = null;
}
}
添加Add方法
然后是添加数据的操作。数据以递归的方式与树根进行比较,小于树根置于左子树,大于树根置于右子树。
public void Insert(int data)
{
_root = InsertRec(_root, data);
}
// 递归插入函数
private Node InsertRec(Node root, int data)
{
// 如果当前节点为空,创建一个新节点并返回
if (root == null)
{
root = new Node(data);
return root;
}
// 如果插入的数据小于当前节点的数据,递归插入到左子树
if (data < root.Data)
{
root.Left = InsertRec(root.Left, data);
}
// 如果插入的数据大于当前节点的数据,递归插入到右子树
else if (data > root.Data)
{
root.Right = InsertRec(root.Right, data);
}
return root;
}
中序遍历
从上面的规则我们知道,左子树内的值一定小于树根,而左子树的值一定大于树根。因此,只需要利用“中序遍历”方式就可以得到从小到大排序好的数据。如果想从大到小排序,则可将最后结果置于堆栈内再一次弹出(Pop)即可。
public void Inorder()
{
InorderRec(_root);
}
// 递归中序遍历函数
private void InorderRec(Node root)
{
if (root != null)
{
InorderRec(root.Left);
Console.Write(root.Data + " ");
InorderRec(root.Right);
}
}
前序遍历
public void Preorder()
{
PreorderRec(_root);
}
private void PreorderRec(Node root)
{
if (root != null)
{
Console.Write(root.Data + " ");
PreorderRec(root.Left);
PreorderRec(root.Right);
}
}
后续遍历
public void Postorder()
{
PostorderRec(_root);
}
private void PostorderRec(Node root)
{
if (root != null)
{
PostorderRec(root.Left);
PostorderRec(root.Right);
Console.Write(root.Data + " ");
}
}
层序遍历
public void LevelOrder()
{
LevelOrderRec(_root);
}
private void LevelOrderRec(Node root)
{
if (root == null)
{
return;
}
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(root);
while (queue.Count > 0)
{
Node currentNode = queue.Dequeue();
Console.Write(currentNode.Data + " ");
if (currentNode.Left != null)
{
queue.Enqueue(currentNode.Left);
}
if (currentNode.Right != null)
{
queue.Enqueue(currentNode.Right);
}
}
}
添加删除方法
public void Delete(int data)
{
_root = DeleteRec(_root, data);
}
// 递归删除函数
private Node DeleteRec(Node root, int data)
{
// 如果当前节点为空,直接返回
if (root == null)
{
return root;
}
// 如果要删除的数据小于当前节点的数据,递归删除左子树中的节点
if (data < root.Data)
{
root.Left = DeleteRec(root.Left, data);
}
// 如果要删除的数据大于当前节点的数据,递归删除右子树中的节点
else if (data > root.Data)
{
root.Right = DeleteRec(root.Right, data);
}
// 如果当前节点就是要删除的节点
else
{
// 如果当前节点只有右子树或没有子树,直接返回右子树
if (root.Left == null)
{
return root.Right;
}
// 如果当前节点只有左子树,直接返回左子树
else if (root.Right == null)
{
return root.Left;
}
// 如果当前节点有两个子树,找到右子树中的最小值节点,替换当前节点的值
root.Data = MinValue(root.Right);
// 删除右子树中的最小值节点
root.Right = DeleteRec(root.Right, root.Data);
}
return root;
}
// 查找二叉搜索树中的最小值节点
private int MinValue(Node root)
{
int minValue = root.Data;
while (root.Left != null)
{
minValue = root.Left.Data;
root = root.Left;
}
return minValue;
}
以下是完整的代码
public class Node
{
public int Data;
public Node Left;
public Node Right;
public Node(int data)
{
Data = data;
Left = null;
Right = null;
}
}
public class BinarySearchTree
{
private Node _root;
public BinarySearchTree()
{
_root = null;
}
public void Insert(int data)
{
_root = InsertRec(_root, data);
}
// 递归插入函数
private Node InsertRec(Node root, int data)
{
// 如果当前节点为空,创建一个新节点并返回
if (root == null)
{
root = new Node(data);
return root;
}
// 如果插入的数据小于当前节点的数据,递归插入到左子树
if (data < root.Data)
{
root.Left = InsertRec(root.Left, data);
}
// 如果插入的数据大于当前节点的数据,递归插入到右子树
else if (data > root.Data)
{
root.Right = InsertRec(root.Right, data);
}
return root;
}
public void Inorder()
{
InorderRec(_root);
}
// 递归中序遍历函数
private void InorderRec(Node root)
{
if (root != null)
{
InorderRec(root.Left);
Console.Write(root.Data + " ");
InorderRec(root.Right);
}
}
public void Delete(int data)
{
_root = DeleteRec(_root, data);
}
// 递归删除函数
private Node DeleteRec(Node root, int data)
{
// 如果当前节点为空,直接返回
if (root == null)
{
return root;
}
// 如果要删除的数据小于当前节点的数据,递归删除左子树中的节点
if (data < root.Data)
{
root.Left = DeleteRec(root.Left, data);
}
// 如果要删除的数据大于当前节点的数据,递归删除右子树中的节点
else if (data > root.Data)
{
root.Right = DeleteRec(root.Right, data);
}
// 如果当前节点就是要删除的节点
else
{
// 如果当前节点只有右子树或没有子树,直接返回右子树
if (root.Left == null)
{
return root.Right;
}
// 如果当前节点只有左子树,直接返回左子树
else if (root.Right == null)
{
return root.Left;
}
// 如果当前节点有两个子树,找到右子树中的最小值节点,替换当前节点的值
root.Data = MinValue(root.Right);
// 删除右子树中的最小值节点
root.Right = DeleteRec(root.Right, root.Data);
}
return root;
}
public void Preorder()
{
PreorderRec(_root);
}
private void PreorderRec(Node root)
{
if (root != null)
{
Console.Write(root.Data + " ");
PreorderRec(root.Left);
PreorderRec(root.Right);
}
}
public void Postorder()
{
PostorderRec(_root);
}
private void PostorderRec(Node root)
{
if (root != null)
{
PostorderRec(root.Left);
PostorderRec(root.Right);
Console.Write(root.Data + " ");
}
}
public void LevelOrder()
{
LevelOrderRec(_root);
}
private void LevelOrderRec(Node root)
{
if (root == null)
{
return;
}
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(root);
while (queue.Count > 0)
{
Node currentNode = queue.Dequeue();
Console.Write(currentNode.Data + " ");
if (currentNode.Left != null)
{
queue.Enqueue(currentNode.Left);
}
if (currentNode.Right != null)
{
queue.Enqueue(currentNode.Right);
}
}
}
// 查找二叉搜索树中的最小值节点
private int MinValue(Node root)
{
int minValue = root.Data;
while (root.Left != null)
{
minValue = root.Left.Data;
root = root.Left;
}
return minValue;
}
}