The following is the algorithm detailed process and its implementation. Since the algorithm is given in pseudo code, it is exempt from some text description.
/*******************************************
=================JJ Diary =====================
Author: jjdiaries (AH-hang)
Email: JJDiaries@gmail.com
Date: 2013-11-13
============================================
Binary lookup tree, supported operations include: Serach, MINIMUM,
MAXIMUM, predecessor, successor, INSERT, DELETE.
Theorem: For a two-fork lookup tree with a height of h, manipulate Serach, MINIMUM,
MAXIMUM, predecessor, successor run all the Time O (h)
*******************************************/
/*================JJ Journal =====================
Author: jjdiaries (AH)
mailbox: JJDiaries@gmail.com
Date: 2013-11-13
============================================*/
#include <stdio.h>
#include <stdlib.h>
# Include <string.h>
#define Wordlen
//Define a node, in addition to storing a key value, contains a data character array for storing a word
struct node{
int key;
Char Data[wordlen];
struct node *parent;
struct node *left;
struct node *right;
};
typedef struct node * tree;
The middle sequence of the
/*============================================
Tree traverses
Inorder_tree_walk (x)
if x!= NIL
then Inorder_tree_walk (left[x])
print Key[x]
Inorder_tree_walk (left[x])
============================================*/
void Inorder_tree_walk (tree T)
{
if (t!=null) {
Inorder_tree_walk (T->left);
printf ("key:%d words:%s\n", t->key,t->data);
Inorder_tree_walk (t->right);
}
}
/*============================================
Tree search, return the node containing the keyword K
Tree_search (x,k)//recursive version
If X=nil or K =key[x]
Then return x
If K<KEY[X]
Then return Tree_search (LEFT[X],K)
else return Tree_search (right[x],k)
Tree_search (X,K)//non-recursive version
While X!=nil and k!= Key[x]
Do if K<KEY[X]
Then x <--left[x]
else x <--right[x]
return x
============================================*/
Recursive version
struct node* tree_search (tree t,int k)
{
if (T==null | | k = = t->key)
return T;
if (K < T->key)
Return Tree_search (T->LEFT,K);
Else
Return Tree_search (T->RIGHT,K);
}
Non-recursive version
struct node* tree_search1 (tree t,int k)
{
while (T!=null && t->key!=k)
if (K < T->key)
t=t->left;
Else
t=t->right;
return T;
}
/*============================================
Returns the node with the smallest key value
Tree_minimum (x)
While Left[x]!=nil
Do x <--left[x]
return x
============================================*/
struct node* tree_minimum (tree T)
{
while (T->left!= NULL)
t=t->left;
return T;
}
/*============================================
Returns the node with the largest key value
Tree_maxmum (x)
While Right[x]!=nil
Do x <--right[x]
return x
============================================*/
struct node* tree_maxmum (tree T)
{
while (T->right!= NULL)
t=t->right;
return T;
}
/*============================================
Returns the subsequent node of a node under the sequence traversal
1 If the node X has a right sub node, the subsequent node is the smallest node in the right subtree.
2 If the node x does not have a right subtree, and X has a successor Y, then y is the lowest ancestor node of X
And Y's left son is also the ancestor of X.
Tree_successor (x)
If RIGHT[X]!= NIL
Return Tree_minimum (Right[x])
Y=P[X]
While Y!=nil and x=right[y]//If x=left[y], then x is followed by y, jumping out of the while loop, and returning directly to Y
Do x <--y
Y <--p[y]
Return y
============================================*/
struct node * tree_successor (struct node *t)
{
if (t->right!=null)
Return Tree_minimum (t->right);
struct node *y=t->parent;
while (y!=null && T = = y->right) {
T=y;
y=y->parent;
}
return y;
}
/*===========================================
Insert operation
Train of thought: Looking down from the root node to the insertion position, using the pointer x to track this search path, and pointing y to point X's parent node.
Tree_insert (T,z)
Y=nil
X=ROOT[T]
While x!= NIL//Until x is empty, this empty position is the position that you want to insert
Do Y<--x
If KEY[Z]<KEY[X]
Then x <--left[x]
else x <--right[x]
P[z]=y
If Y=nil
Then when the root[t]=z//tree T is empty
else if KEY[Z] < Key[y]
Then left[y]=z//less than Y is inserted on the left, larger than the right
else right[y]=z
============================================*/
void Tree_insert (Tree *pt,struct node *z)
{
if (*pt==null) {//tree is empty, Z is returned as the root node.
*pt=z;
Return
}
struct node *y=null;
struct node *x=*pt;
while (X!=null) {
Y=x;
if (Z->key < X->key)
x=x->left;
Else
x=x->right;
}
z->parent=y;
if (Z->key < Y->key)
y->left=z;
Else
y->right=z;
}
/*===============================================
Delete operation
Delete operations fall into three categories:
1 to delete the node Z has no children, you can only modify the parent node of Z for that child as nil
2 If you want to delete a node Z with only one child, then just connect the child of Z with the parent node of Z.
3 If you want to delete a node Z with two children, you need to delete the successor Y of Z, and then replace the contents of Z with the contents of Y.
Tree_delete (T,z)
If Left[z]=nil | | Right[z]=nil//Save the node to be deleted first in Y
Then y <--z
else y <--tree_successor (z)
If Left[y]!=nil//Keep Y's non-empty children in X
Then X <--left[y]
else x <--right[y]
If X!=nil
Then P[x]=p[y]//children who will delete the node are connected to the parent node where the node is to be deleted
If P[y]=nil//if the node to be deleted is the root node
Then Root[t] <--x
else if y=left[p[y]]//
Then Left[p[y]] <--x
else Right[p[y]] <--x
If Y!=z//In the third case, you need to replace the contents of Z with the contents of Y
Then Key[z] <--key[y]
Copy y ' s other data to Z
Return y
==============================================*/
struct node * tree_delete (Tree *pt,struct node *z)
{
struct node *delnode,*sonnode;
if (Z->left==null | | z->right = = NULL)//has a child or no child, the end of the node to be deleted Z itself
Delnode=z;
else//There are two children, then the node to be deleted is Z's successor node.
Delnode=tree_successor (z);
if (delnode->left!=null)
sonnode=delnode->left;
Else
sonnode=delnode->right;
if (sonnode!=null)
sonnode->parent=delnode->parent;
if (delnode->parent==null)
*pt=sonnode;
else if (Delnode->parent->left==delnode)
delnode->parent->left=sonnode;
Else
delnode->parent->right=sonnode;
if (delnode!=z) {
z->key=delnode->key;
strcpy (Z->data,delnode->data);
}
return delnode;
}
Initialize a tree
Tree init_tree (int key)
{
struct node * t;
t= (tree) malloc (sizeof (struct node));
if (t==null)
return NULL;
t->key=key;
t->parent=t->left=t->right=null;
return t;
}
Releasing resources
void Fini_tree (Tree T)
{
if (t!=null) {
Fini_tree (T->left);
Fini_tree (T->right);
printf ("Free node (%d,%s) now\n", t->key,t->data);
Free (T);
}
}
Test program
int main ()
{
Tree Mytree=init_tree (256);
if (mytree==null)
return 1;
strcpy (Mytree->data, "jjdiaries");
struct record{
int key;
Char Word[wordlen];
};
struct record records[]={{2, "Viidiot"},
{4, "Linux-code"},
{123, "Google"},
{345, "Baidu"},
{543, "NSFocus"}
};
int i;
struct node *tmp;
for (I=0;i<5;++i) {
tmp= (tree) malloc (sizeof (struct node));
if (tmp==null)
Continue
tmp->key=records[i].key;
strcpy (Tmp->data,records[i].word);
tmp->left=tmp->right=tmp->parent=null;
Tree_insert (&MYTREE,TMP);
}
Inorder_tree_walk (mytree);
struct node *del;
Del=tree_delete (&mytree,tree_search (mytree,345));
printf ("Delete node (%d,%s) \ n", del->key,del->data);
Free (DEL);
Inorder_tree_walk (mytree);
Fini_tree (mytree);
}