标签:
#include "stdafx.h"
#include <string>
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef struct Node
{
int key; //键值
struct Node *left; //左节点
struct Node *right; //右节点
struct Node *father; //父节点
int times; //节点出现的次数
} Node, *pNode;
void creatBinarySearchTree(pNode &pBSTTree, int *ptr, int len);
void insertNode(pNode &pBSTTree, int value);
void mallocInitNode(pNode &pInsertNode, int value);
pNode findMinNode(pNode &pTree);
pNode findMaxNode(pNode &pTree);
pNode findPredecessor(pNode &pSearchNode);
pNode findSuccessor(pNode &pSearchNode);
void deleteNode(pNode& pdeleteNode);
void changeFatherChildNode(pNode& pdeleteNode, pNode& pNewChildNode);
int main()
{
int a[] = {15,15, 6, 18, 3, 7, 17, 20, 2, 4, 13, 9};
int len = sizeof(a) / sizeof(int);
pNode pBSTTree = NULL;
pNode pPreNode = NULL;
pNode pSuccessor = NULL;
/* 创建二叉查找树 */
creatBinarySearchTree(pBSTTree, a, len);
/* 寻找二叉查找树中的最大值 */
cout << "最小值的节点为:" << findMinNode(pBSTTree)->key << endl;
cout << "最大值的节点为:" << findMaxNode(pBSTTree)->key << endl;
/* 寻找某个节点的前驱节点 */
pPreNode = findPredecessor(pBSTTree->left->right);
if (NULL != pPreNode)
{
cout << "该节点的前驱节点为:" << pPreNode->key << endl;
}
else
{
cout << "该节点无前驱节点" << endl;
}
/* 寻找某个节点的后继节点 */
pSuccessor = findSuccessor(pBSTTree->left->left->left);
if (NULL != pPreNode)
{
cout << "该节点的后继节点为:" << pSuccessor->key << endl;
}
else
{
cout << "该节点无后继节点" << endl;
}
/* 删除某个节点 */
deleteNode(pBSTTree->right->right);
deleteNode(pBSTTree->left->left);
cout << "最小值的节点为:" << findMinNode(pBSTTree)->key << endl;
pSuccessor = findSuccessor(pBSTTree->left->left);
if (NULL != pPreNode)
{
cout << "该节点的后继节点为:" << pSuccessor->key << endl;
}
else
{
cout << "该节点无后继节点" << endl;
}
free(pBSTTree);
pBSTTree = NULL;
return 0;
}
/* 创建一个二叉查找树 */
void creatBinarySearchTree(pNode &pBSTTree, int *ptr, int len)
{
for (int i = 0; i < len; i++)
{
insertNode(pBSTTree, *(ptr + i));
}
}
/* 插入一个节点,复杂度为O(nlogn) */
void insertNode(pNode &pBSTTree, int value)
{
pNode pInsertNode;
/* 第一个节点,直接插入 */
if (NULL == pBSTTree)
{
mallocInitNode(pInsertNode, value);
pBSTTree = pInsertNode;
return;
}
/* 如果键值已经存在的话,只需要times++ */
if (value == pBSTTree->key)
{
pBSTTree->times++;
return;
}
/* 如果小于本节点的值,且该节点无左孩子 */
if ((NULL == pBSTTree->left) && (value < pBSTTree->key))
{
mallocInitNode(pInsertNode, value);
pInsertNode->father = pBSTTree;
pBSTTree->left = pInsertNode;
return;
}
/* 如果大于本节点的值,且该节点无右孩子 */
if ((NULL == pBSTTree->right) && (value > pBSTTree->key))
{
mallocInitNode(pInsertNode, value);
pInsertNode->father = pBSTTree;
pBSTTree->right = pInsertNode;
return;
}
/* 如果小于本节点的值,但是该节点已经有左孩子,那么就继续递归 */
if ((NULL != pBSTTree->left) && (value < pBSTTree->key))
{
insertNode(pBSTTree->left, value);
}
/* 如果大于本节点的值,但是该节点已经有右孩子,那么就继续递归 */
if ((NULL != pBSTTree->right) && (value > pBSTTree->key))
{
insertNode(pBSTTree->right, value);
}
}
/* 创建新节点并初始化 */
void mallocInitNode(pNode &pInsertNode, int value)
{
pInsertNode = (pNode)malloc(sizeof(Node));
pInsertNode->key = value;
pInsertNode->father = NULL;
pInsertNode->left = NULL;
pInsertNode->right = NULL;
pInsertNode->times = 1;
}
/* 寻找二叉树中最小的节点和最大的节点 */
pNode findMinNode(pNode &pTree)
{
pNode pTemp = pTree;
while (NULL != pTemp->left)
{
pTemp = pTemp->left;
}
return pTemp;
}
pNode findMaxNode(pNode &pTree)
{
pNode pTemp = pTree;
while (NULL != pTemp->right)
{
pTemp = pTemp->right;
}
return pTemp;
}
/* 找出前驱节点 */
pNode findPredecessor(pNode &pSearchNode)
{
/* 如果左子树存在的话,则返回左子树中最大的节点,即为比它小的之中的最大的节点 */
if (NULL != pSearchNode->left)
{
return findMaxNode(pSearchNode->left);
}
/* 如果左子树不存在的话,则需要往上找,直到找到目标节点是目标节点父亲节点的右孩子 */
pNode pTemp = pSearchNode;
while(pTemp != pTemp->father->right)
{
pTemp = pTemp->father;
}
return pTemp->father;
}
/* 找出后继节点 */
pNode findSuccessor(pNode &pSearchNode)
{
/* 如果右子树存在的话,则返回右子树中最小的节点,即为比它大的之中的最小的节点 */
if (NULL != pSearchNode->right)
{
return findMinNode(pSearchNode->right);
}
/* 如果左子树不存在的话,则需要往上找,直到找到目标节点是目标节点父亲节点的右孩子 */
pNode pTemp = pSearchNode;
while(pTemp != pTemp->father->left)
{
pTemp = pTemp->father;
}
return pTemp->father;
}
void deleteNode(pNode& pdeleteNode)
{
/* 1.判断该节点的个数,如果节点的个数大于或等于1,则直接将该节点的个数-1 */
if (1 < pdeleteNode->times)
{
pdeleteNode->times--;
return;
}
/* 2.如果该节点只有一个,那么考虑删除 */
/* 2.1 如果该节点没有孩子,则直接删除 */
pNode pTemp = NULL;
if ((NULL == pdeleteNode->left) && (NULL == pdeleteNode->right))
{
changeFatherChildNode(pdeleteNode, pTemp);
}
/* 2.2 如果该节点只有一个孩子,那么直接用该孩子代替该节点 */
else if ((NULL == pdeleteNode->left) && (NULL != pdeleteNode->right))
{
changeFatherChildNode(pdeleteNode, pdeleteNode->right);
}
else if ((NULL == pdeleteNode->right) && (NULL != pdeleteNode->left))
{
changeFatherChildNode(pdeleteNode, pdeleteNode->left);
}
/* 2.3 如果该节点有两个孩子,那么考虑用该节点的前驱或者后继来代替该节点。在此,我们选择用前驱代替该节点 */
else
{
pTemp = findPredecessor(pdeleteNode);
pNode pRightChild = pdeleteNode->right;
changeFatherChildNode(pdeleteNode, pTemp);
pTemp->right = pRightChild;
}
}
void changeFatherChildNode(pNode& pdeleteNode, pNode& pNewChildNode)
{
if (pdeleteNode == pdeleteNode->father->right)
{
pdeleteNode->father->right = pNewChildNode;
}
else
{
pdeleteNode->father->left = pNewChildNode;
}
}
代码运行结果:标签:
原文地址:http://www.cnblogs.com/xlchen/p/4433977.html