栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构二叉排序树

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构二叉排序树

基于《数据结构Java语言描述》
定义 :二叉排序树(Binary Sort Tree)也称为二叉查找树,它或者是一棵空树,或具有以下性质的二叉树:
(1)、若它的左子树非空,则左子树上所有结点的值均小于根结点的值。
(2)、若它的右子树非空,则右子树上所有结点的值均大于根结点的值。
左、右子树也分别是一棵二叉排序树。

案例:
右边的二叉排序树中序遍历后,其结果是?

答:3 6 8 9 10 12 16 19 23 26 30 33

小结:二叉排序树的一个重要性质:若中序遍历一棵二叉树,可以得到一个结点值递增的有序序列。
总结:在根节点,比它小的数在左边,比它大的数在左边。

二叉排序树的查找算法思想:

  • 若二叉排序树为空,则查找失败。
  • 若二叉排序树非空,将给定关键字kx与根结点的关键字进行比较:
  • 若相等,则查找成功,结束查找;
    -若给定关键字kx小于根结点的关键字,则递归查找左子树;
  • 若给定关键字kx大于根结点的关键字,则递归查找右子树。
public static BiTNode searchNode(BiTNode t, T kx) {
// 若子树是空子树或子树根结点的关键字等于kx,返回t
if (t == null || t.data.key.equals(kx)) {
	return t;
} else if (kx.compareTo(t.data.key) < 0) {
// 关键字小于当前子树的根结点的关键字
return searchNode(t.lchild, kx); // 在左子树继续查找
} else {
return searchNode(t.rchild, kx); // 在右子树继续查找
}
}

基于《数据结构JAVA语言描述》给出一个有序数组{16, 8, 6, 3, 10, 9, 12, 26, 19, 23, 33, 30 }
BinarySortTree类

public class BinarySortTree {
	// 在二叉排序树中查找关键字为kx的结点,如果找到返回结点,否则返回null
	public static BiTNode searchNode(BiTNode t, Integer kx) {
		if (t == null || kx.equals(t.data.key)) {// 若子树是空子树或子树根结点的关键字等于kx,返回t
			return t;
		} else if (kx.compareTo((Integer) t.data.key) < 0) {// 关键字小于当前子树的根结点的关键字
			return searchNode(t.lchild, kx);// 在左子树继续查找
		} else {
			return searchNode(t.rchild, kx);// 在右子树继续查找
		}
	}

	// 在二叉排序树中插入关键字为kx的结点
	public static BiTNode insertNode(BiTNode t, Integer kx) {
		if (t == null) {// 空树的场合,返回根结点
			t = createNode(kx);
		} else {
			if (kx.compareTo((Integer) t.data.key) < 0) {// 添加的结点关键字小于当前子树的根结点的关键字
				if (t.lchild == null) {// 当前子树的左子树是null
					t.lchild = createNode(kx);
				} else {
					insertNode(t.lchild, kx); // 递归的向左子树添加
				}
			} else if (kx.compareTo((Integer) t.data.key) > 0) {// 添加的结点关键字大于当前子树的根结点的关键字
				if (t.rchild == null) {// 当前子树的右子树是null
					t.rchild = createNode(kx);
				} else {
					insertNode(t.rchild, kx); // 递归的向右子树添加
				}
			} else {// 添加的结点关键字在二叉树中已存在,无需插入
				System.out.println("kx已存在无需插入");
			}
		}
		return t;
	}

	// 创建结点
	public static BiTNode createNode(Integer kx) {
		RecT data = new RecT(kx);
		BiTNode node = new BiTNode(data, null, null);
		return node;
	}

	// 在二叉排序树中删除关键字为kx的结点
	//
	public static BiTNode deleteNode(BiTNode t, Integer kx) {
		if (t == null) {// 空树的场合,返回null
			System.out.println("该二叉树是一棵空树");
			return null;
		} else {
			// 1.找到要删除的结点 targetNode
			BiTNode targetNode = searchNode(t, kx);
			// 如果没有找到要删除的结点,返回null
			if (targetNode == null) {
				System.out.println("没有找到要删除的结点");
				return t;
			}
			// 2.找到targetNode的父结点parent
			BiTNode parent = searchParent(t, kx);
			// 3.1删除叶子结点
			if (targetNode.lchild == null && targetNode.rchild == null) {
				if (parent != null) {// targetNode有父结点的场合
					// 判断targetNode 是父结点的左子结点,还是右子结点
					if (parent.lchild != null && parent.lchild.data.key.equals(kx)) { // 是左子结点
						parent.lchild = null;
					} else if (parent.rchild != null && parent.rchild.data.key.equals(kx)) {// 是右子结点
						parent.rchild = null;
					}
				} else {// targetNode是根结点的场合
					t = null;
					return t;
				}
			} else if (targetNode.lchild != null && targetNode.rchild != null) { // 3.2删除有两棵子树的结点
				t = delRightTreeMin(t, targetNode);// targetNode右子树中最小的结点替换targetNode,并删除该结点。
			} else {// 3.3删除只有一棵子树的结点
				if (targetNode.lchild != null) {// targetNode有左子树的场合
					if (parent != null) {// targetNode有父结点的场合
						if (parent.lchild != null && parent.lchild.data.key.equals(kx)) {// targetNode是 parent的左子结点
							parent.lchild = targetNode.lchild;
						} else {// targetNode是 parent的右子结点
							parent.rchild = targetNode.lchild;
						}
					} else {// targetNode是根结点的场合
						t = targetNode.lchild;
					}
				} else { // targetNode有右子树的场合
					if (parent != null) {// targetNode有父结点的场合
						if (parent.lchild != null && parent.lchild.data.key.equals(kx)) {// targetNode是 parent的左子结点
							parent.lchild = targetNode.rchild;
						} else { // targetNode是 parent的右子结点
							parent.rchild = targetNode.rchild;
						}
					} else { // targetNode是根结点的场合
						t = targetNode.rchild;
					}
				}
			}
		}
		return t;
	}

	// 在二叉排序树中查找关键字为kx的父结点,如果没有找到,返回null,否则返回父结点
	public static BiTNode searchParent(BiTNode t, Integer kx) {
		BiTNode p = t;// 要查找的结点
		BiTNode f = null;// 要查找的结点的父结点
		while (p != null && !kx.equals(p.data.key)) {
			f = p;
			if (kx.compareTo((Integer) p.data.key) < 0) {
				p = p.lchild;
			} else {
				p = p.rchild;
			}
		}
		if (p == null) {// 没有找到关键字kx,返回null
			return null;
		} else {
			return f;// 找到了关键字kx,返回父结点
		}
	}

	// targetNode右子树中最小的结点替换targetNode,并删除该结点。返回删除结点后的树
	public static BiTNode delRightTreeMin(BiTNode t, BiTNode targetNode) {
		BiTNode p = targetNode.rchild;// P指向targetNode右子树
		while (p.lchild != null) {// P指向targetNode右子树最小结点
			p = p.lchild;
		}
		Integer min = (Integer) p.data.key;
		t = deleteNode(t, min);// 删除targetNode右子树最小结点
		targetNode.data.key = min;// targetNode结点关键字替换为最小值
		return t;
	}
}

BiTNode类

public class BiTNode{
	public RecT data;// 结点的数据元素
	public BiTNode lchild, rchild;// 结点的左右孩子

	public BiTNode(RecT data, BiTNode lchild, BiTNode rchild) {
		super();
		this.data = data;
		this.lchild = lchild;
		this.rchild = rchild;
	}
}

Test测试类

public class Test {

	public static void main(String[] args) {
		Integer[] keys = { 16, 8, 6, 3, 10, 9, 12, 26, 19, 23, 33, 30 };// 关键字序列
		BiTNode t = null;
		// 1.构建二叉排序树
		for (int i = 0; i < keys.length; i++) {
			t = BinarySortTree.insertNode(t, keys[i]);
		}
		// 2.中序遍历二叉排序树
		System.out.println("中序遍历二叉排序树~");
		infixOrderTree(t);
		// 3.1删除结点9
		t = BinarySortTree.deleteNode(t, new Integer(9));
		// 中序遍历删除关键字9后的二叉排序树
		System.out.println("删除关键字9后的二叉排序树~");
		infixOrderTree(t);
		// 3.2删除结点6
		t = BinarySortTree.deleteNode(t, new Integer(6));
		// 中序遍历删除关键字6后的二叉排序树
		System.out.println("删除关键字6后的二叉排序树~");
		infixOrderTree(t);
		// 3.3删除结点33
		t = BinarySortTree.deleteNode(t, new Integer(33));
		// 中序遍历删除关键字33后的二叉排序树
		System.out.println("删除关键字33后的二叉排序树~");
		infixOrderTree(t);
		// 3.4删除结点19
		t = BinarySortTree.deleteNode(t, new Integer(19));
		// 中序遍历删除关键字19后的二叉排序树
		System.out.println("删除关键字19后的二叉排序树~");
		infixOrderTree(t);
		// 3.5删除结点10
		t = BinarySortTree.deleteNode(t, new Integer(10));
		// 中序遍历删除关键字10后的二叉排序树
		System.out.println("删除关键字10后的二叉排序树~");
		infixOrderTree(t);
		// 3.6删除结点8
		t = BinarySortTree.deleteNode(t, new Integer(8));
		// 中序遍历删除关键字8后的二叉排序树
		System.out.println("删除关键字8后的二叉排序树~");
		infixOrderTree(t);
		// 4. 查找关键字为23的结点
		BiTNode node = BinarySortTree.searchNode(t, new Integer(23));
		System.out.println("结点的关键字为:" + node.data.key);
	}

	// 中序遍历二叉排序树
	public static void infixOrderTree(BiTNode t) {
		if (t == null) {// 空树的场合
			System.out.println("二叉排序树为空,不能遍历");
		} else {
			infixOrder(t);
			System.out.println();
		}
	}

	// 中序遍历
	public static void infixOrder(BiTNode t) {
		if (t.lchild != null) {// 递归遍历左子树
			infixOrder(t.lchild);
		}
		System.out.print(t.data.key + " ");// 输出关键字
		if (t.rchild != null) {// 递归遍历右子树
			infixOrder(t.rchild);
		}
	}
}

如有不对请指正!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/836522.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号