1. 程式人生 > >Java資料結構:二叉排序樹的刪除操作

Java資料結構:二叉排序樹的刪除操作

嚶嚶嚶,今天補回昨天沒有寫的部落格。

二叉排序樹的刪除操作比較簡單,但是思想很全面,因此本人就寫一篇部落格紀念一下。

思想:四種類型也可以是三種

1,刪除結點p的度為2,即有左右子樹。

此時有兩種方法,第一種將結點的左子樹在中根遍歷下的最後一個結點放到p的位置。第二種是將p結點的右子樹在中根遍歷下的第一個結點放到p的位置。這裡本人根據之前的部落格二叉樹的中根遍歷就用了第二種方法。有first()方法,嚶嚶嚶。

2,單隻樹的根結點,且為葉子結點,度為1。

此時就需要將p的左子樹或右子樹(只有一個)替換p。so easy.

3,刪除結點p是度為1的葉子結點,有父母,是左孩子

此時需要將p的左孩子或者右孩子替換掉p。用p的孩子替換掉p。相信大家都會,類似於連結串列的插入。

4,刪除結點p是度為1的葉子結點,有父母,是右孩子。

此時需要將p的左孩子或者右孩子替換掉p。用p的孩子替換掉p。相信大家都會,類似於連結串列的插入。

上程式碼:

	public T remove(T key) {
		TriNode<T> p = this.searchNode(key); // 查詢關鍵字為key元素,若查詢成功,返回結點,否則返回null
		if (p != null && p.left != null && p.right != null) // 找到待刪除結點p,若p是2度結點
		{
			TriNode<T> insucc = this.first(p.right); // 尋找p在中根次序下的後繼結點insucc
			T temp = p.data; // 交換待刪除元素,作為返回值
			p.data = insucc.data; // 以後繼結點值替換p結點值
			insucc.data = temp;
			p = insucc; // 轉化為刪除insucc,刪除1、0度結點
		}

		if (p != null && p == this.root) // p是1度或葉子結點,刪除根結點,p.parent==null
		{
			if (this.root.left != null)
				this.root = p.left; // 以p的左孩子頂替作為新的根結點
			else
				this.root = p.right; // 以p的右孩子頂替作為新的根結點
			if (this.root != null)
				this.root.parent = null;
			return p.data; // 返回被刪除根結點元素
		}

		if (p != null && p == p.parent.left) // p是1度或葉子結點,p是父母的左孩子
			if (p.left != null) {
				p.parent.left = p.left; // 以p的左孩子頂替
				p.left.parent = p.parent; // p的左孩子的parent域指向p的父母
			} else {
				p.parent.left = p.right; // 以p的右孩子頂替
				if (p.right != null)
					p.right.parent = p.parent;
			}

		if (p != null && p == p.parent.right) // p是1度或葉子結點,p是父母的右孩子
			if (p.left != null) {
				p.parent.right = p.left; // 以p的左孩子頂替
				p.left.parent = p.parent;
			} else {
				p.parent.right = p.right; // 以p的右孩子頂替
				if (p.right != null)
					p.right.parent = p.parent;
			}
		return p != null ? p.data : null;
	}