设为首页 加入收藏

TOP

漫谈二叉搜索树的基本算法(三种思路实现查询操作)
2015-07-20 17:18:30 来源: 作者: 【 】 浏览:3
Tags:漫谈 搜索 基本 算法 思路 实现 查询 操作

前面我们说了二叉树前序中序后序遍历的递归非递归算法的实现,下面我们再来说说二叉搜索树~

二叉排序树分为静态查找(find)和动态查找(insert、delete) 二叉搜索树:一棵二叉树,可以为空;如果不为空,满足下列性质: 1.非空左子树的所有键值小于其根结点的键值。 2.非空右子树的所有键值大于其根结点的键值 3.左右子树都是二叉搜索树!! \
2.以上是二叉搜索树(也叫二叉排序树)的一些基本操作,此处我们先说一下二叉树的结点定义?? 代码中判断当前结点位置情况的辅助方法以及简单的 get 方法都在常数时间内可以完成,实现也相应非常简单。下面主要讨论 updateHeight ()、 updateSize ()、 sever()、setLChild(lc)、 getRChild(rc)的实现与时间复杂度。
1)<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPgo8c3Ryb25nPiAgICAvLyC4/NDCtbHHsL3hteO8sMbk1+bPyLXEuN+2yDwvc3Ryb25nPgo8c3Ryb25nPnB1YmxpYyB2b2lkIHVwZGF0ZUhlaWdodCgpIHs8L3N0cm9uZz4KPHN0cm9uZz4gICAgaW50IG5ld0ggPSAwOy8vINDCuN+2yLP1yry7r86qIDAsuN+2yLXI09rX89PS19PK97jftsi80yAxINbQtcS089XfPC9zdHJvbmc+CjxzdHJvbmc+ICAgIGlmIChoYXNMQ2hpbGQoKSk8L3N0cm9uZz4KPHN0cm9uZz4gICAgICAgIG5ld0ggPSBNYXRoLm1heChuZXdILCAxICYjNDM7IGdldExDaGlsZCgpLmdldEhlaWdodCgpKTsvL7e1u9jBvdXf1tC9z7TztcTSu7j2PC9zdHJvbmc+CjxzdHJvbmc+ICAgIGlmIChoYXNSQ2hpbGQoKSk8L3N0cm9uZz4KPHN0cm9uZz4gICAgICAgIG5ld0ggPSBNYXRoLm1heChuZXdILCAxICYjNDM7IGdldFJDaGlsZCgpLmdldEhlaWdodCgpKTs8L3N0cm9uZz4KPHN0cm9uZz4gICAgaWYgKG5ld0ggPT0gaGVpZ2h0KTwvc3Ryb25nPgo8c3Ryb25nPiAgICAgICAgcmV0dXJuOyAvLyC437bIw7vT0Leiyfqx5Luv1PLWsb3Tt7W72Dwvc3Ryb25nPgo8c3Ryb25nPiAgICBoZWlnaHQgPSBuZXdIOyAvLyC38dTyuPzQwrjftsg8L3N0cm9uZz4KPHN0cm9uZz4gICAgaWYgKGhhc1BhcmVudCgpKTwvc3Ryb25nPgo8c3Ryb25nPiAgICAgICAgZ2V0UGFyZW50KCkudXBkYXRlSGVpZ2h0KCk7IC8vILXduem4/NDC1+bPyLXEuN+2yDwvc3Ryb25nPgo8c3Ryb25nPn08L3N0cm9uZz4KPHN0cm9uZz51cGRhdGVIZWlnaHQgKCmjusj0tbHHsL3hteMgdiC1xLqi19O3osn6seS7r6Osvs3Q6NKqyrnTwyB1cGRhdGVIZWlnaHQKICgpt723qLj80MK1scewveG147ywxuTX5s/IveG147XEuN+2yKGjx+vXotLio6zTydPa0ru49r3hteO1xLjftsi3osn6seS7r6Osu+HTsM/stb3G5Nfmz8i94bXjtcS437bIo6zU2tXiwO/O0sPH1MrQ7daxvdO21MjOus694bXj1rTQ0NXi0ruy2df3oaPS8s6q1Nq2/rLmyvfW0MjOus7Su7j2veG147XEuN+2yKOstry1yNPaxuTX89PS19PK97XEuN+2yNbQtPPV37zTIDGjrLb41/PT0tfTyve1xLjftsjWu9Do0qq78cihuMO94bXj1/PT0rqi19O1xLjftsijrNa70OjSqqaoICgxKcqxvOSho7zMtvi00yB2ILP2t6LR2HBhcmVudCDS/dPDxObQ0M/yyc+jrNLAtM64/NDCuPfX5s/IveG147XEuN+2yLy0v8mho8jnufvU2snPyva5/bPM1tCjrLeiz9bEs7j2veG147XEuN+2yMO709C3osn6seS7r6Osy+O3qL/J0tTWsb3T1tXWuaGj19vJz8v5yvajrLWxttTSu7j2veG14yB2ILX308MgdXBkYXRlSGVpZ2h0CiAoKbe9t6jKsaOsyPQgdiC1xLLjyv3OqiBsZXZlbCh2KaOs1PLX7rbg1rvQ6NKquPzQwiBsZXZlbCh2KSYjNDM7MSC49r3hteO1xLjftsijrNLytMvL47eotcTKsbzkuLTU07bIIFQobikKID0gpq8gKGxldmVsKHYpKaGjPC9zdHJvbmc+CjxzdHJvbmc+ICAgIDKjqSA8L3N0cm9uZz4KPHN0cm9uZz4gICAgLy8KILj80MK1scewveG147ywxuTX5s/ItcTX08vvyv08L3N0cm9uZz4KPHN0cm9uZz5wdWJsaWMgdm9pZCB1cGRhdGVTaXplKCkgezwvc3Ryb25nPgo8c3Ryb25nPiAgICBzaXplID0gMTsgLy8KILP1yry7r86qIDEsveG147G+ye08L3N0cm9uZz4KPHN0cm9uZz4gICAgaWYgKGhhc0xDaGlsZCgpKTwvc3Ryb25nPgo8c3Ryb25nPiAgICAgICAgc2l6ZSAmIzQzOz0gZ2V0TENoaWxkKCkuZ2V0U2l6ZSgpOyAvLwogvNPJz9fz19PK97nmxKM8L3N0cm9uZz4KPHN0cm9uZz4gICAgaWYgKGhhc1JDaGlsZCgpKTwvc3Ryb25nPgo8c3Ryb25nPiAgICAgICAgc2l6ZSAmIzQzOz0gZ2V0UkNoaWxkKCkuZ2V0U2l6ZSgpOyAvLwogvNPJz9PS19PK97nmxKM8L3N0cm9uZz4KPHN0cm9uZz4gICAgaWYgKGhhc1BhcmVudCgpKTwvc3Ryb25nPgo8c3Ryb25nPiAgICAgICAgZ2V0UGFyZW50KCkudXBkYXRlU2l6ZSgpOyAvLwogtd256bj80MLX5s/ItcS55sSjPC9zdHJvbmc+CjxzdHJvbmc+fTwvc3Ryb25nPgo8c3Ryb25nPnVwZGF0ZVNpemUKICgpo7rNrNH5yOe5+73hteMgdiC1xLqi19O3osn6seS7r6Os06a4w7j80MK1scewveG149LUvLDG5Nfmz8i1xLnmxKOho9LyzqrU2rb+subK99bQyM66ztK7uPa94bXjtcS55sSjo6y2vLXI09rG5Nfz09LX08r3tcS55sSj1q66zbzTyc+94bXj19TJ7aOstvjX89PS19PK97XEuebEo9a70OjSqrvxyKG4w73htePX89PSuqLX07XEuebEo7y0v8m78bXDo6zWu9Do0qqmqCAoMSnKsbzkoaPS8rTLy+O3qLXEyrG85Li01NO2yCBUKG4pCiA9IKavIChsZXZlbCh2KSmhozxicj4KICAgIDOjqTwvc3Ryb25nPgo8c3Ryb25nPiAKICAgLy8gts+/qtPruLjH17XEudjPtTwvc3Ryb25nPgo8c3Ryb25nPnB1YmxpYwogdm9pZCBzZXZlcigpIHs8L3N0cm9uZz4KPHN0cm9uZz4gCiAgIGlmICghaGFzUGFyZW50KCkpPC9zdHJvbmc+CjxzdHJvbmc+IAogICAgICAgcmV0dXJuOzwvc3Ryb25nPgo8c3Ryb25nPiAKICAgaWYgKGlzTENoaWxkKCkpPC9zdHJvbmc+CjxzdHJvbmc+IAogICAgICAgcGFyZW50LmxDaGlsZCA9IG51bGw7PC9zdHJvbmc+CjxzdHJvbmc+IAogICBlbHNlPC9zdHJvbmc+CjxzdHJvbmc+IAogICAgICAgcGFyZW50LnJDaGlsZCA9IG51bGw7PC9zdHJvbmc+CjxzdHJvbmc+IAogICBwYXJlbnQudXBkYXRlSGVpZ2h0KCk7IC8vILj80MK4uL3hteO8sMbk1+bPyLjftsg8L3N0cm9uZz4KPHN0cm9uZz4gICAgcGFyZW50LnVwZGF0ZVNpemUoKTsgLy8guPzQwri4veG147ywxuTX5s/IuebEoyA8L3N0cm9uZz4KPHN0cm9uZz4gCiAgIHBhcmVudCA9IG51bGw7PC9zdHJvbmc+CjxzdHJvbmc+IH0gPC9zdHJvbmc+CjxzdHJvbmc+c2V2ZXIoKaO6x9C2z73hteMgdiDT67i4veG14yBwINauvOS1xLnYz7Who7jDy+O3qNDo0qrQ3rjEIHYg0+sgcCC1xNa41evT8qOs0OjSqrOjyv3KsbzkoaOz/bTL1q7N4tPJ09ogcCC94bXjtcS6otfTt6LJ+sHLseS7r6Os0vK0y9Do0qq199PDIHVwZGF0ZUhlaWdodAogKCm6zXVwZGF0ZVNpemUgKCnAtLj80MK4uL3hteMgcCC8sMbk1+bPyLXEuN+2yNPruebEo6GjxuTKsbzkuLTU07bIIFQobikKID0gpq8gKGxldmVsKHYpKaGjPGJyPgogICAgNKOpPC9zdHJvbmc+CjxzdHJvbmc+IAogICAvLyDJ6NbDtbHHsL3hteO1xNfzuqLX0yy3tbvY1K3X87qi19M8L3N0cm9uZz4KPHN0cm9uZz5wdWJsaWMKIEJpblRyZWVOb2RlIHNldExDaGlsZChCaW5UcmVlTm9kZSBsYykgezwvc3Ryb25nPgo8c3Ryb25nPiAKICAgQmluVHJlZU5vZGUgb2xkTEMgPSB0aGlzLmxDaGlsZDs8L3N0cm9uZz4KPHN0cm9uZz4gCiAgIGlmIChoYXNMQ2hpbGQoKSkgezwvc3Ryb25nPgo8c3Ryb25nPiAKICAgICAgIGxDaGlsZC5zZXZlcigpOzwvc3Ryb25nPgo8c3Ryb25nPiAKICAgfSAvLyC2z7+qtbHHsNfzuqLX09PrveG147XEudjPtTwvc3Ryb25nPgo8c3Ryb25nPiAKICAgaWYgKGxjICE9IG51bGwpIHs8L3N0cm9uZz4KPHN0cm9uZz4gCiAgICAgICBsYy5zZXZlcigpOyAvLyC2z7+qIGxjINPrxuS4uL3hteO1xLnYz7U8L3N0cm9uZz4KPHN0cm9uZz4gCiAgICAgICB0aGlzLmxDaGlsZCA9IGxjOyAvLyDIt7aouLjX07nYz7U8L3N0cm9uZz4KPHN0cm9uZz4gCiAgICAgICBsYy5wYXJlbnQgPSB0aGlzOzwvc3Ryb25nPgo8c3Ryb25nPiAKICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7IC8vILj80MK1scewveG147ywxuTX5s/IuN+2yDwvc3Ryb25nPgo8c3Ryb25nPiAKICAgICAgIHRoaXMudXBkYXRlU2l6ZSgpOyAvLyC4/NDCtbHHsL3hteO8sMbk1+bPyLnmxKM8L3N0cm9uZz4KPHN0cm9uZz4gCiAgIH08L3N0cm9uZz4KPHN0cm9uZz4gCiAgIHJldHVybiBvbGRMQzsgLy8gt7W72NSt1/O6otfTPC9zdHJvbmc+CjxzdHJvbmc+fTwvc3Ryb25nPgo8c3Ryb25nPjxicj4KPC9zdHJvbmc+CjxzdHJvbmc+IAogICAvLyDIodPSuqLX0zwvc3Ryb25nPgo8c3Ryb25nPnB1YmxpYwogQmluVHJlZU5vZGUgZ2V0UkNoaWxkKCkgezwvc3Ryb25nPgo8c3Ryb25nPiAKICAgcmV0dXJuIHJDaGlsZDs8L3N0cm9uZz4KPHN0cm9uZz59PC9zdHJvbmc+CjxzdHJvbmc+PGJyPgo8L3N0cm9uZz4KPHN0cm9uZz4gCiAgIC8vIMno1sO1scewveG147XE09K6otfTLLe1u9jUrdPSuqLX0zwvc3Ryb25nPgo8c3Ryb25nPnB1YmxpYwogQmluVHJlZU5vZGUgc2V0UkNoaWxkKEJpblRyZWVOb2RlIHJjKSB7PC9zdHJvbmc+CjxzdHJvbmc+IAogICBCaW5UcmVlTm9kZSBvbGRSQyA9IHRoaXMuckNoaWxkOzwvc3Ryb25nPgo8c3Ryb25nPiAKICAgaWYgKGhhc1JDaGlsZCgpKSB7PC9zdHJvbmc+CjxzdHJvbmc+IAogICAgICAgckNoaWxkLnNldmVyKCk7PC9zdHJvbmc+CjxzdHJvbmc+IAogICB9IC8vILbPv6q1scew09K6otfT0+u94bXjtcS52M+1PC9zdHJvbmc+CjxzdHJvbmc+IAogICBpZiAocmMgIT0gbnVsbCkgezwvc3Ryb25nPgo8c3Ryb25nPiAKICAgICAgIHJjLnNldmVyKCk7IC8vILbPv6ogbGMg0+vG5Li4veG147XEudjPtTwvc3Ryb25nPgo8c3Ryb25nPiAKICAgICAgIHRoaXMuckNoaWxkID0gcmM7IC8vIMi3tqi4uNfTudjPtTwvc3Ryb25nPgo8c3Ryb25nPiAKICAgICAgIHJjLnBhcmVudCA9IHRoaXM7PC9zdHJvbmc+CjxzdHJvbmc+IAogICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTsgLy8guPzQwrWxx7C94bXjvLDG5Nfmz8i437bIPC9zdHJvbmc+CjxzdHJvbmc+IAogICAgICAgdGhpcy51cGRhdGVTaXplKCk7IC8vILj80MK1scewveG147ywxuTX5s/IuebEozwvc3Ryb25nPgo8c3Ryb25nPiAKICAgfTwvc3Ryb25nPgo8c3Ryb25nPiAKICAgcmV0dXJuIG9sZFJDOyAvLyC3tbvY1K3T0rqi19M8L3N0cm9uZz4KPHN0cm9uZz59PC9zdHJvbmc+CjxzdHJvbmc+c2V0TENoaWxkKGxjKaGiIGdldFJDaGlsZChyYymjusG9uPbL47eotcS5psTcz+C21KOs0ru49srHyejWw73hteMgdiC1xNfzuqLX06Os0ru49srHyejWw73hteMgdiC1xNPSuqLX06Gjwb249svjt6i1xMq1z9bKx8DgJiMyMDI4NDu1xKOs0tQgc2V0TENoaWxkKCnOqsD9y7XD96GjytfPyKOsyOe5+yB2INPQ1/O6otfTIG9sZExDo6zU8tOmtbG199PDIG9sZExDLgogc2V2ZXIoKbbPv6ogdiDT68bk1/O6otfTtcS52M+1oaMKIMbktM6jrCC199PDIGxjLiBzZXZlcigpts+/qsbk0+u4uL3hteO1xLnYz7Who9fuuvOjrL2owaIgdiDT6yBsYyDWrrzktcS4uNfTudjPtaOssqK199PDIHYuCiB1cGRhdGVTaXplICgp0+sgdi51cGRhdGVIZWlnaHQgKCm4/NDCIHYgvLDG5Nfmz8i1xLnmxKPT67jftsihozwvc3Ryb25nPgo8c3Ryb25nPs/Cw+bKx9PDtPrC68q1z9a1xMr3uN+2yLrNsunRr8r30rbX073hteO1xLLZ1/ehozwvc3Ryb25nPgo8c3Ryb25nPjwvc3Ryb25nPjxwcmUgY2xhc3M9"brush:java;">public class BinSearchTreeTest01 { public Point root; //访问结点 public static void visitKey(Point p){ System.out.println(p.getKey() + " "); } //构造树 public static Point Tree(){ Point a = new Point('A', null, null); Point b = new Point('B', null, a); Point c = new Point('C', null, null); Point d = new Point('D', b, c); Point e = new Point('E', null, null); Point f = new Point('F', e, null); Point g = new Point('G', null, f); Point h = new Point('H', d, g); return h;// root } //求二叉树的高度 height = max(HL , HR) + 1 public static int height(Point p){ int HL , HR , MaxH; if(p != null){ HL = height(p.getLeftChild()); HR = height(p.getRightChild()); MaxH = Math.max(HL, HR); return MaxH + 1; } return 0; } //求二叉树的叶子结点 public static void OrderLeaves(Point p){ if(p != null){ if(p.getLeftChild() == null && p.getRightChild() == null) visitKey(p); OrderLeaves(p.getLeftChild()); OrderLeaves(p.getRightChild()); } } public static void main(String[] args) { System.out.println("二叉树的高度为:" + height(Tree())); System.out.print("二叉树的叶子结点为:"); OrderLeaves(Tree()); } } class Point{ private char key; private Point LeftChild , RightChild; public Point(char key , Point LeftChild , Point RightChild){ this.key = key; this.LeftChild = LeftChild; this.RightChild = RightChild; } public Point(char key){ this(key , null ,null); } public char getKey() { return key; } public void setKey(char key) { this.key = key; } public Point getLeftChild() { return LeftChild; } public void setLeftChild(Point leftChild) { LeftChild = leftChild; } public Point getRightChild() { return RightChild; } public void setRightChild(Point rightChild) { RightChild = rightChild; } } 3.下面开始今天的正题,二叉搜索树的查询,插入和删除操作 1)Find ?查找从根结点开始,如果树为空,返回NULL ?若搜索树非空,则根结点关键字和X进行比较,并进行不同处理: 1)若X小于根结点键值,只需要在左子树进行搜索; 2)若X大于根结点键值,在右子树进行搜索; 3)若两者比较结果相同,搜索完成,返回此结点。
import java.util.Scanner;

/**
 * 二叉搜索树的操作集锦
 * 
 * @author Administrator
 *
 */
class BinSearchTreeTest02 {
	public Point1 root;

	// 访问结点
	public static void visitKey(Point1 p) {
		System.out.println(p.getKey() + "  ");
	}

	// 构造树
	public static Point1 Tree() {
		Point1 m = new Point1(4, null, null);
		Point1 a = new Point1(6, m, null);
		Point1 b = new Point1(5, null, a);
		Point1 c = new Point1(14, null, null);
		Point1 d = new Point1(10, b, c);
		Point1 e = new Point1(24, null, null);
		Point1 f = new Point1(25, e, null);
		Point1 g = new Point1(20, null, f);
		Point1 h = new Point1(15, d, g);
		return h;// root
	}

	// 构造空树
	public static Point1 EmptyTree(int t) {
		Point1 a = new Point1(t, null, null);
		return a;
	}

	// *********************************查找操作****************************
	/**
	 * 二叉搜索树查找操作方法1
	 * 
	 * @param t
	 * @param node
	 * @return
	 */
	public static boolean contains(int t, Point1 node) {
		if (node == null)
			return false;// 结点为空,查找失败
		String st = Integer.toString(t);// 把要查找的结点转化为String类型
		int result = compareTo(st, node);
		if (result == 1) {
			return true;
		} else {
			return false;
		}
	}

	public static int compareTo(String a, Point1 p) {
		// String b = Integer.toString(p.getKey());
		// if(a.equals(b))和下面这行是等价的
		if (a.equals(p.getKey() + ""))
			return 1;
		int i = 0, j = 0;
		if (p.getLeftChild() != null) {
			i = compareTo(a, p.getLeftChild());
		}
		if (p.getRightChild() != null) {
			j = compareTo(a, p.getRightChild());
		}
		if (i == 1) {
			return i;
		} else if (j == 1) {
			return j;
		} else {
			return -1;
		}
	}

	/**
	 * 二叉搜索树查找操作方法2(递归算法) 尾递归的方式
	 * 
	 * @param t
	 * @param node
	 * @return
	 */
	public static Point1 contains2(int t, Point1 node) {
		if (node == null)
			return null;// 结点为空,查找失败
		if (t > node.getKey())
			return contains2(t, node.getRightChild());// 查找右子树
		else if (t < node.getKey())
			return contains2(t, node.getLeftChild());// 查找左子树
		else
			return node;
	}

	/**
	 * 二叉搜索树查找的搜索方法2的变形,非递归算法的效率更高 将尾递归改为迭代函数
	 * 
	 * @param args
	 */
	public static Point1 contains3(int t, Point1 node) {
		while (node != null) {
			if (t > node.getKey())
				node = node.getRightChild();
			else if (t < node.getKey())
				node = node.getLeftChild();
			else
				return node;
		}
		return null;
	}

	/**
	 * 二叉搜索树的最大元素 根据其性质可以得出二叉搜索树的最大元一定位于右子树的最右端,最小元则相反
	 * 
	 * @param args
	 */
	public static int findMax(Point1 point) {
		if (point != null) {
			while (point.getRightChild() != null) {
				point = point.getRightChild();
			}
		}
		return point.getKey();
	}

	public static int findMin(Point1 point) {
		if (point == null)
			return 0;// 先判断树是否为空
		else if (point.getLeftChild() == null)
			return point.getKey();// 在判断左子树是否为空
		else
			return findMin(point.getLeftChild());
	}

	public static void main(String[] args, Point1 p) {
		System.out.println("此二叉树的最大结点为:" + findMax(Tree()));
		System.out.println("此二叉树的最小结点为:" + findMin(Tree()));
		@SuppressWarnings("resource")
		Scanner scanner = new Scanner(System.in);
		System.out.println("输入一个结点,将判断是否是此二叉树的结点");
		int a = scanner.nextInt();
		if (contains2(a, Tree()) != null) 
			System.out.println(a + " 是此二叉树的结点"); 
		else 
			System.out.println(a + " 不是此二叉树的结点");	 
	}
}

class Point1 {
	private int key;
	private Point1 LeftChild, RightChild;

	public Point1(int key, Point1 LeftChild, Point1 RightChild) {
		this.key = key;
		this.LeftChild = LeftChild;
		this.RightChild = RightChild;
	}

	public Point1(int key) {
		this(key, null, null);
	}

	public int getKey() {
		return key;
	}

	public void setKey(char key) {
		this.key = key;
	}

	public Point1 getLeftChild() {
		return LeftChild;
	}

	public void setLeftChild(Point1 leftChild) {
		LeftChild = leftChild;
	}

	public Point1 getRightChild() {
		return RightChild;
	}

	public void setRightChild(Point1 rightChild) {
		RightChild = rightChild;
	}
}

(给出了三种不同的查找的思路,不过确实要比另外两种好实现一些,希望可以有所借鉴,插入和删除晚些时候放上)

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++构造函数语意学――默认构造函.. 下一篇 LeetCode―Word Break

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C/C++ 类模板与模板 (2025-12-27 01:49:52)
·C语言 模板化<templ (2025-12-27 01:49:49)
·C/C++模板类模板与函 (2025-12-27 01:49:46)
·如何理解c语言指针和 (2025-12-27 01:19:11)
·为什么C标准库没有链 (2025-12-27 01:19:08)