您的位置:首页 > 其它

二查排序树的基本操作(插入,删除,找前驱与后继)

2016-09-27 12:28 288 查看
// Binary-Search-Tree.cpp : Defines the entry point for the console application.
//最近要面试,想自己写写这类算法的代码,加深印象

#include "stdafx.h"
//参考算法导论的伪代码编写
//有错误的地方,恳请大家批评指正,thx;
typedef struct Node
{
int val;
Node* left;
Node* right;
Node* parent;
Node(int value) : val(value) , left(NULL), right(NULL),parent(NULL)
{

}
}Node;

//查找二叉搜索树中最小的元素
int FindMinValue(Node* head)
{
if(head == NULL)
return -1;
Node* p = head;
while(p->left)
p = p->left;
return p->val;
}

//查找二叉搜索树的最大元素
int FindMaxValue(Node* head)
{
if(head == NULL)
return -1;
Node* p = head;
while(p->right)
p = p->right;
return p->val;
}

//找当前节点的后继结点
/*
1、若当前节点有右子树,那么后继结点就是右子树最左的结点
2、若当前节点没有右子树, 那么后继结点:从当前节点往上延伸,找到某个结点p,p不是其父结点的右孩子。如果找不到结点p,则其没有后继结点
*/
Node* FindSucceed(Node* curNode)
{
if(curNode->right)
{
Node* p = curNode->right;
while(p->left)
p = p->left;
return p;
}
else
{
Node* cur = curNode;
Node* parent = curNode->parent;
while(parent && parent->right == cur)
{
cur = parent;
parent = cur->parent;
}
/*if(parent == NULL)
return NULL;
else
return parent;*/
return parent;
}
}

//找当前节点的前驱结点
/*
1、如果当前节点有左子树,那么前驱结点就是其左子树最右的结点
2、如果当前节点没有左子树,则前驱结点:从当前节点往上延伸,找到结点p,p不是其父结点的左孩子。如果找不到结点p,则该节点没有前驱结点;
*/
Node* FindPioneer(Node* curNode)
{
if(curNode->left)
{
Node* p = curNode->left;
while(p->right)
p = p->right;
return p;
}
else
{
Node* cur = curNode;
Node* parent = cur->parent;
while(parent && parent->left == cur)
{
cur = parent;
parent = cur->parent;
}
return parent;
}
}

//二叉树中插入结点
void InsertNode(Node* head, Node* node)
{
if(node == NULL)
return;
Node* parent = NULL;
Node* curNode = head;
while(curNode)
{
parent = curNode;
if(curNode->val > node->val)
curNode = curNode->left;
else
curNode = curNode->right;
}
node->parent = parent;
if(parent == NULL)
node = head;
else if(parent->val < node->val)
parent->right = node;
else
parent->left = node;
}

//二叉树中删除结点
/*
分三种情况讨论
1、如果删除结点没有左孩子也没有右孩子,则可以直接删除改结点,并让其父结点孩子指针为NULL;
2、如果删除结点只有一个孩子结点,则也可以直接删除该节点,并让其父结点的孩子指针指向删除结点的孩子;
3、如果删除结点有两个孩子结点,则先找到该节点的后继结点,后继结点的元素值取代删除结点的元素值,再删除后继结点,并让后继结点的父节点的孩子指针指向后继结点的孩子;
*/
void DeleteNode(Node* head, Node* node)
{
Node* y, *x;
if(node->left==NULL || node->right==NULL)
y = node;
else
y = FindSucceed(node);
if(y->left)
x = y->left;
else
x = y->right;
if(x)
{
x->parent = y->parent;
}
if(y->parent == NULL)
head = x;
else if(y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
if(y != node)
{
node->val  = y->val;
delete y;
}
}

int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐