删除结点的时候考虑情况分三种 叶子节点 有一个子结点 有两个子节点
----
using System;
using System.Collections.Generic;
using System.Text;
namespace chapt10_01
{
//线索二叉搜索树
class Node
{
public Node lchild;
public Node rchild;
public int lthread=1;
public int rthread=1;
public int Value;
public Node(int v) { Value = v; }
}
class ThreadBinarySearchTree : chapt10_01.IThreadBinarySearchTree
{
private Node head;
//0thread 1node
public ThreadBinarySearchTree()
{
head = new Node(0);
head.lthread = 0;
head.lchild = head;
}
public void find(int element, ref Node parent, ref Node currentNode)
{ }
public void insert(int element) {
Node newNode = new Node(element);
Node currentNode,parent;
//empty
if (head.lthread == 0)
{
head.lthread = 1;
head.lchild = newNode;
newNode.lchild = head;
newNode.rchild = head;
newNode.lthread = 0;
newNode.rthread = 0;
}
else
{
currentNode = head.lchild;
parent = head;
while (currentNode != null)
{
parent = currentNode;
if (head.lchild == head)
{
parent = head;
}
else if (element == currentNode.Value)
{
Console.Write("{0} is exist.canot insert", element);
return;
}
else if (element < currentNode.Value && currentNode.lthread == 1)
currentNode = currentNode.lchild;
else if (element < currentNode.Value && currentNode.lthread == 0)
currentNode = null;
else if (element > currentNode.Value && currentNode.rthread == 1)
currentNode = currentNode.rchild;
else if (element > currentNode.Value && currentNode.rthread == 0)
currentNode = null;
}
newNode.lthread = 0;
newNode.rthread = 0;
if (parent == head)
{
head.lthread = 1;
head.lchild = newNode;
newNode.lchild = head;
newNode.rchild = head;
}
else if (element < parent.Value)
{
newNode.lchild = parent.lchild;
newNode.rchild = parent;
parent.lthread = 1;
parent.lchild = newNode;
}
else if (element > parent.Value)
{
newNode.lchild = parent;
newNode.rchild = parent.rchild;
parent.rthread = 1;
parent.rchild = newNode;
}
}
}
//找到中序后继
public Node Inorder_successor(ref Node currentNode)
{
//right is thred
if (currentNode.rthread == 0)
{
currentNode = currentNode.rchild;
}
else
{//有孩子的最左
currentNode = currentNode.rchild;
while (currentNode.lthread != 0)
{
currentNode = currentNode.lchild;
}
}
return currentNode;
}
//前驱
public Node Inorder_per(ref Node currentNode)
{
//Node parent;
//right is thred
if (currentNode.lthread == 0)
{
currentNode = currentNode.lchild;
}
else
{
currentNode = currentNode.lchild;
while (currentNode.rthread != 0)
{
//parent = currentNode;
currentNode = currentNode.rchild;
}
}
return currentNode;
}
public void Inorder_traversal()
{
if (head.lchild == head)
{
Console.WriteLine("Tree is empty");
return;
}
Node currentNode;
currentNode = head.lchild;
while (currentNode.lthread == 1)
{
currentNode = currentNode.lchild;
}
Console.Write(currentNode.Value + " ");
while (currentNode.rchild != head)
{
currentNode = Inorder_successor(ref currentNode);
Console.Write(currentNode.Value + " ");
}
}
public void Inorder_retraversal()
{
if (head.lchild == head)
{
Console.WriteLine("Tree is empty");
return;
}
Node currentNode;
currentNode = head.lchild;
while (currentNode.rthread == 1)
{
currentNode = currentNode.rchild;
}
Console.Write(currentNode.Value + " ");
while (currentNode.lchild != head)
{
currentNode = Inorder_per(ref currentNode);
Console.Write(currentNode.Value + " ");
}
}
public void remove(int element)
{
if (head.lchild == head)
{
Console.Write("tree is empty");
return;
}
//find del node & it's parent node
Node parent,currentNode,child=null;
currentNode = head.lchild;
parent = head;
while (currentNode.Value!=element&¤tNode != null)
{
parent = currentNode;
if (element < currentNode.Value && currentNode.lthread == 1)
currentNode = currentNode.lchild;
else if (element < currentNode.Value && currentNode.lthread == 0)
currentNode = null;
else if (element > currentNode.Value && currentNode.rthread == 1)
currentNode = currentNode.rchild;
else if (element > currentNode.Value && currentNode.rthread == 0)
currentNode = null;
}
if (currentNode == null)
{
Console.WriteLine("cannot find {0}", element);
return;
}
while (true)
{
//前驱和 后继
Node i_per;
Node i_suc;
//leaf
if (currentNode.lthread == currentNode.rthread && currentNode.lthread == 0)
{
if (parent == head)
{
head.lthread = 0;
head.lchild = head;
}
else if (currentNode == parent.lchild)
{
parent.lthread = 0;
parent.lchild = Inorder_per(ref currentNode);
}
else if (currentNode == parent.rchild)
{
parent.rthread = 0;
parent.rchild = Inorder_successor(ref currentNode);
}
break;
}
//case2 has only one child
else if ((currentNode.lthread == 0 && currentNode.rthread == 1)
|| (currentNode.lthread == 1 && currentNode.rthread == 0))
{
i_per = Inorder_per(ref currentNode);
i_suc = Inorder_successor(ref currentNode);
//has left child
if (currentNode.lthread == 1)
{
child = currentNode.lchild;
}
else if (currentNode.rthread == 1)
{
child = currentNode.rchild;
}
if (currentNode == parent.lchild)
{
parent.lchild = child;
}
else if (currentNode == parent.rchild)
{
parent.rchild = child;
}
//move
if (currentNode.rthread == 1)
{
i_suc.lchild = i_per;
i_suc.lthread = 0;
}
else if (currentNode.lthread == 1)
{
i_per.rchild = i_suc;
i_per.rthread = 0;
}
break;
}
else//case3 has two children
{
i_suc = currentNode;
Inorder_successor(ref i_suc);
//中序后继的父节点
parent = i_suc.rchild;
//兑换当前与中续后继的值
currentNode.Value = i_suc.Value;
currentNode = i_suc;
continue;
}
}
//free
currentNode = null;
}
static void Main(string[] args)
{
ThreadBinarySearchTree t = new ThreadBinarySearchTree();
t.insert(65);
t.insert(40);
t.insert(30);
t.insert(50);
t.insert(45);
t.insert(72);
t.insert(69);
t.insert(80);
t.Inorder_traversal();
Console.Write("\n");
Console.WriteLine("删除 40");
t.remove(40);
t.Inorder_traversal();
}
}
}
posted @ 2008-02-28 17:41 Humtong 阅读(116) 评论(0) 编辑
