您的位置:首页 > 其它

【算法设计-二叉搜索树】二叉查找树的操作与实现

2015-05-16 10:17 344 查看
二叉查找树某个结点的左子树的值都比它小,其右子树的值比它大。

这里主要讲解下删除算法中的第三种情况

3.1



3.2



要实现的主要操作



代码实现

#include <iostream>

using namespace std;

// BST的结点

typedef struct node

{

int key;

struct node *lChild, *rChild,*parent;

}Node;

typedef struct BST

{

Node *root;

}BST;

void createBST(BST p);

// 在给定的BST中插入结点,其数据域为element, 使之称为新的BST

void Insert(BST *p, Node *z)

{

Node *y=NULL;

Node * x=p->root;

while(x!=NULL)

{

y=x;

if(z->key<x->key)

x=x->lChild;

else

x=x->rChild;

}

z->parent=y;

if(y==NULL)

p->root=z;

else if(z->key<y->key)

y->lChild=z;

else

y->rChild=z;

}

void PrintBST(Node *root,int depth)

{

Node *p1=root;

if(p1==NULL)

printf("这是一颗空树!\n");

else

{

int i;

if (p1->rChild)

PrintBST(p1->rChild, depth + 1);

for (i = 1; i <= depth; i++)

printf(" ");

printf("%d\n", p1->key);

if (p1->lChild)

PrintBST(p1->lChild, depth + 1);

}

}

void createBST(BST *p)

{

int t;

int depth = 0;

printf("\n请输入关键字(以-123结束建立平衡二叉树):");

scanf("%d", &t);

while (t != -123)

{

Node *z=new Node;

z->key=t;

z->lChild=z->rChild=z->parent=NULL;

Insert(p, z);

printf("\n请输入关键字(以-123结束建立平衡二叉树):");

scanf("%d", &t);

}

printf("\n****************************************************\n");

printf("*******************您创建的二叉树为*******************\n");

if (p)

PrintBST(p->root,depth);

else

printf("这是一棵空树!\n");

printf("********************二叉树创建完成*********************\n");

}

Node* search(Node *root, int key)

{

if (root == NULL)

{

printf("此树为空!\n");

return NULL;

}

else if (key == root->key)

{

printf("查找成功!,%d的地址是%p\n", key, root);

return root;

}

else if (key < root->key)

search(root->lChild, key);

else

search(root->rChild, key);

}

void preorderBST(Node* root)

{

if (root)

{

cout << root->key << " ";

preorderBST(root->lChild);

preorderBST(root->rChild);

}

}

//中序遍历(这个可以做为排序算法

void inorderBST(Node *root)

{

if (root)

{

inorderBST(root->lChild);

cout << root->key << " ";

inorderBST(root->rChild);

}

}

//后序遍历

void postrderBST(Node* root)

{

if (root)

{

postrderBST(root->lChild);

postrderBST(root->rChild);

cout << root->key << " ";

}

}

void Delete(BST* p,int key)

{

Node* p1=p->root;

//删除要分三种情况

while(p1->key!=key)

{

if(key>p1->key)

p1=p1->rChild;

else

p1=p1->lChild;

}

//第一种情况:如果z没有孩子结点,则只是简单的将它删除,并修改它的父节点。用NIL作为孩子来替换z(现在还没有考虑其为根节点)

if(p1->lChild==NULL&&p1->rChild==NULL)

{

if(p1==p->root)

{

printf("已经删除根节点!,此时树为空哦\n");

p->root=NULL;

return;

}

if(p1->key<p1->parent->key)

p1->parent->lChild=NULL;

else

p1->parent->rChild=NULL;

}

//第二种情况:如果只有一个孩子,则将这个孩子提升到树中z的位置上,并修改z的父节点,用z的孩子来替换z

if(p1->lChild!=NULL&&p1->rChild==NULL)

{

if(p1==p->root)

{

p->root=p1->lChild;

return;

}

if(p1->key<p1->parent->key)

{

p1->parent->lChild=p1->lChild;

p1->lChild->parent=p1->parent;

}

else

{

p1->parent->rChild=p1->lChild;

p1->lChild->parent=p1->parent;

}

}

if(p1->rChild!=NULL&&p1->lChild==NULL)

{

if(p1==p->root)

{

p->root=p1->rChild;

return;

}

if(p1->key<p1->parent->key)

{

p1->parent->lChild=p1->rChild;

p1->rChild->parent=p1->parent;

}

else

{

p1->parent->rChild=p1->rChild;

p1->rChild->parent=p1->parent;

}

}

//第三种情况(这个节点既有左子树也有右子树)

if(p1->lChild!=NULL&&p1->rChild!=NULL)

{

Node *y=p1->rChild;

if(y->lChild!=NULL)

{

while(y->lChild!=NULL)

y=y->lChild;

//先用y的右孩子替换y(如果y有右孩子x,就把x作为y的父节点r的左孩子,否则就将y的父节点r的左孩子置为空)

if(y->rChild!=NULL)

{

y->rChild->parent=y->parent;

y->parent->lChild=y->rChild;

}

else

{

y->parent->lChild=NULL;

}

//用y替换z

y->rChild=p1->rChild;

p1->rChild->parent=y;

y->lChild=p1->lChild;

p1->lChild->parent=y;

y->parent=p1->parent;

if(p1==p->root)

{

p->root=y;

}

else

{

if(p1->parent->key>p1->key)

p1->parent->lChild=y;

else

p1->parent->rChild=y;

}

}

else

{

y->lChild=p1->lChild;

p1->lChild->parent=y;

y->parent=p1->parent;

if(p1==p->root)

{

p->root=y;

}

else

{

if(p1->parent->key>p1->key)

p1->parent->lChild=y;

else

p1->parent->rChild=y;

}

}

}

}

void Maximum(Node* root)

{

Node* p1=root;

while(p1->rChild)

{

p1=p1->rChild;

}

printf("Maximum=%d",p1->key);

}

void Minmum(Node * root)

{

Node* p1=root;

while(p1->lChild)

{

p1=p1->lChild;

}

printf("Minimum=%d",p1->key);

}

void get_parent(Node *p)

{

if (p)

{

printf("%d->parent=%p",p->key,p->parent);

get_parent(p->lChild);

get_parent(p->rChild);

}

}

int main(void)

{

int ch;

BST *T=new BST;

T->root=NULL;

printf("请写入您要建立的BST树的所有结点值!\n");

createBST(T);

while (1)

{

printf("\n***************************************\n");

printf("*****按下列选项选择您要进行的操作******\n");

printf("*****1前序输出.************************\n");

printf("*****2.中序输出************************\n");

printf("*****3.后序输出************************\n");

printf("*****4.查找****************************\n");

printf("*****5.求最大值************************\n");

printf("*****6.求最小值************************\n");

printf("*****7.插入数值************************\n");

printf("*****8.获得父节点地址******************\n");

printf("*****9.删除数值************************\n");

printf("*****10.打印排序二叉树*****************\n");

printf("*****11.退出***************************\n");

printf("***************************************\n");

scanf("%d", &ch);

switch (ch)

{

case 1:

preorderBST(T->root); break;

case 2:

inorderBST(T->root); break;

case 3:

postrderBST(T->root);break;

case 4:

{

int m;

printf("您要查找的是多少:");

scanf("%d", &m);

search(T->root, m);

}

break;

case 5:

Maximum(T->root); break;

case 6:

Minmum(T->root);break;

case 7:

{

printf("您要插入多少:");

int key;

scanf("%d",&key);

Node *z=new Node;

z->key=key;

z->lChild=z->rChild=z->parent=NULL;

Insert(T,z);

}break;

case 8:

get_parent(T->root);

break;

case 9:

{

printf("您要删除多少:");

int key;

scanf("%d",&key);

Delete(T,key);

}

break;

case 10:

PrintBST(T->root,0);

break;

case 11:

return 0; break;

default:

break;

}

}

return 0;

}
代码展示大家可以自己运行,初始数据是4,2,1,3,5,9,7,6,比较容易测试。

删除操作详解

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: