Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
STD_Alg_KTURE_p1_large_font.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
272.96 Кб
Скачать

1St print: 5

A.preorder_rec(root)

A.preorder_rec(&n3)

A.preorder_rec(&n2)

call3 return3 call6 return 6

2Nd print: 9 3d print: 7

A.preorder_rec(null)

A.preorder_rec(null)

A.preorder_rec(null)

A.preorder_rec(null)

call4 return1 call5 return2 call7 return4 call8 return5

*/

//*************************

public void inorder()

{ System.out.println("inorder sequence of nodes:");

inorder_rec(root);

System.out.println(";");

}//inorder

protected void inorder_rec(TNode p)

{ if(p != null)

{ inorder_rec(p.left);

System.out.print(", " + p.data);

inorder_rec(p.right);

}//if

}//inoder_rec

/* tracing the call: A.inorder(). Given object BinaryTree A including objects n1, n2, n3 of TNode class.

#6000

A:  root Note: #6000 denotes the address of the node n1, etc.

5

#8000

#9000

#6000

n1:

null

9

null

null

7

null

#8000 #9000

n2: n3:

main()

After return8, it is printed: , 9, 5, 7

A.inorder()

call1 return8

call2 return7

A.inorder_rec(#6000)

2Nd print: 5

A.preorder_rec(root)

A.inorder_rec(#9000)

A.inorder_rec(#8000)

call3 return3 call6 return 6

1St print: 9 3d print: 7

A.inorder_rec(null)

A.inorder_rec(null)

A.inorder_rec(null)

A.inorder_rec(null)

call4 return1 call5 return2 call7 return4 call8 return5

*/

//**********************

public void postorder()

{ System.out.println("postorder sequence of nodes:");

postorder_rec(root);

System.out.println(";");

}//postorder

protected void postorder_rec(TNode p)

{ if(p != null) { postorder_rec(p.left);

postorder_rec(p.right);

System.out.print(", " + p.data);

}//if

}//postoder_rec

//*****************************

public int size()

{ return size_rec(root); }//size

protected int size_rec(TNode p)

{ if(p == null) return 0;

else return size_rec(p.left) + size_rec(p.right) + 1;

}// size_rec

//**********************

}//class BinaryTree

Note: Functions of this class are called by objects of other derived classes of binary trees.

Topic 12. Binary Search Tree (BST).

D

x

efinition: A binary search tree is a binary tree where data in each node is greater than its left son data and not greater than its right son data.

z

A: If A is BST then y < x z.

y

Example: Given a sequence of keys: 15, 12, 17, 11, 13, 17, 16. Add them one by one in that sequence to an empty BST.

Algorithm (recursive) of addItem(key) for binary search trees:

  1. Examine the tree

If it is empty then make a root and save key in it;

else if(key < root data) then examine the left subtree;

else examine the right subtree.

Note: a new key is always inserted in the root node of a new subtree.

15

root  BinarySearchTree A

12

17

11

13

16

17

Java code of the class BinarySearchTree

Prepared by Dr. Alex Ossyka

//////////////////////////////////////////////////////////////////////////////////////////////////

public class BinarySearchTree extends BinaryTree{

public BinarySearchTree()

{ super(); }//This class inherits the constructor of the BinaryTree class.

//*************************

public boolean search(int item)

{ return search_rec(item, root); }//search

protected boolean search_rec(int item, TNode p)

{ if(p == null)

return false;

if(p.data == item)

return true;

else if(p.data > item)

return search_rec(item, p.left);

else

return search_rec(item, p.right);

}//search_rec

//***************************************

public void addNode(int item)

{ root = addNode_rec(item, root); }//addNode

protected TNode addNode_rec(int item, TNode p)

{ if(p == null)

{ p = new TNode(item);

p.left = p.right = null;

}//if

else if(item < p.data)

p.left = addNode_rec(item, p.left);

else p.right = addNode_rec(item, p.right);

return p;

}//addNode_rec

//*************************

/* Deleting a node by using four member functions

public void deleteNode(int item)

{ root = deleteNode_rec(item, root); }//deleteNode

protected TNode deleteNode_rec(int item, TNode p)

{ if(item < p.data) p.left = deleteNode_rec(item, p.left);

else if(item > p.data) p.right = deleteNode_rec(item, p.right);

else p = delete_NodeFound(p);

return p;

}//deleteNode_rec

protected TNode delete_NodeFound(TNode p)

//It deletes the node referenced by p.

{ int info;

if(p.left == null) return p.right;

else if(p.right == null) return p.left;

else

{ info = getPredecessor(p.left);

p.data = info;

p.left = deleteNode_rec(info, p.left); //delete the predecessor node

return p;

}//else

}//delete_NodeFound

private int getPredecessor(TNode p) //returns data member of the rightmost node in tree

{ while(p.right != null)

p = p.right;

return p.data;

}//getPredecessor

*/

//*************************

//Deleting a tree node by using three member functions

public void deleteNode(int item)

{ root = deleteNode_rec(item, root); }//deleteNode

protected TNode deleteNode_rec(int item, TNode p)

{ if(item < p.data) p.left = deleteNode_rec(item, p.left);

else if(item > p.data) p.right = deleteNode_rec(item, p.right);

else p = delete_NodeFound(p);

return p;

}//deleteNode_rec

protected TNode delete_NodeFound(TNode p) //It deletes the node referenced by p.

{ if(p.left == null) return p.right

else if(p.right == null) return p.left;

else

{ TNode p1 = p;

while(p1.right != null)//searching for rightmost node in tree

p1 = p1.right;

p.data = p1.data; //assigning data member of the rightmost node

p.left = deleteNode_rec(p.data, p.left); //delete the preceding node

return p;

}//else

}//delete_NodeFound

}//class BinarySearchTree}

///////////////////////////////////////////////////////////////////////////

import binarytree.*;

//Dr. Alex Ossyka

public class BinaryTreeTest {

public static void main(String args[])

{

BinarySearchTree A = new BinarySearchTree();

A.addNode(15);

A.addNode(10);

A.addNode(7);

A.addNode(50);

A.addNode(12);

A.addNode(45);

if(A.search(50)) System.out.println("found");

else System.out.println("not found");

if(A.search(60)) System.out.println("found");

else System.out.println("not fount");

A.inorder();

A.preorder();

A.postorder();

int a = A.size();

System.out.println("The number of nodes in tree = " + a);

if(A.search(50))//checking the precondidion for deleteNode()

A.deleteNode(50);

else System.out.println("Item is not in tree. It cannot be deleted.");

A.preorder();

a = A.size();

System.out.println("The number of nodes in tree = " + a);

}//main

}//class BinaryTreeTest

Output of the program

found

not fount

inorder sequence of nodes:

, 7, 10, 12, 15, 45, 50;

preorder sequence of nodes:

, 15, 10, 7, 12, 50, 45;

postorder sequence of nodes:

, 7, 12, 10, 45, 50, 15;

The number of nodes in tree = 6

preorder sequence of nodes:

, 15, 10, 7, 12, 45;

The number of nodes in tree = 5

Binary search tree. Removing a node

Remove operation on binary search tree is more complicated, than add and search. Basically, in can be divided into two stages:

  • search for a node to remove;

  • if the node is found, run remove algorithm.

Remove algorithm in detail

Now, let's see more detailed description of a remove algorithm. First stage is identical to algorithm for search, except we should track the parent of the current node. Second part is more tricky. There are three cases, which are described below.

  1. Node to be removed has no children.

This case is quite simple. Algorithm sets corresponding link of the parent to NULL and disposes the node.

Example. Remove -4 from a BST.

  1. Node to be removed has one child.

It this case, node is cut from the tree and algorithm links single child (with it's subtree) directly to the parent of the removed node.

Example. Remove 18 from a BST.

  1. Node to be removed has two children.

This is the most complex case. To solve it, let us see one useful BST property first. We are going to use the idea, that the same set of values may be represented as different binary-search trees. For example those BSTs:

contains the same values {5, 19, 21, 25}. To transform first tree into second one, we can do following:

  • choose minimum element from the right subtree (19 in the example);

  • replace 5 by 19;

  • hang 5 as a left child.

The same approach can be utilized to remove a node, which has two children:

  • find a minimum value in the right subtree;

  • replace value of the node to be removed with found minimum. Now, right subtree contains a duplicate!

  • apply remove to the right subtree to remove a duplicate.

Notice, that the node with minimum value has no left child and, therefore, it's removal may result in first or second cases only.

Example. Remove 12 from a BST.

Find minimum element in the right subtree of the node to be removed. In current example it is 19.

Replace 12 with 19. Notice, that only values are replaced, not nodes. Now we have two nodes with the same value.

Remove 19 from the left subtree.

Finally, there is nothing special about the right subtree of a deleted node. We could do the same thing with the left subtree: just use the largest value in the left subtree. In our example we can overwrite the value 12 by 9 (the largest value in the left subtree here) and delete the node with 9 in the left subtree. Now deleting is reduced to case 1 or case 2.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]