1.头文件
#include<stdio.h>
#include <malloc.h>
typedef int State;
struct TreeNode
{
State data;
int num;
TreeNode * leftNode;
TreeNode * rightNode;
};
TreeNode * CreateTreeNode(State d)
{
TreeNode * head =(TreeNode*)malloc(sizeof(TreeNode));
head->data=d;
head->num=1;
head->leftNode=NULL;
head->rightNode=NULL;
return head;
}
2.源文件
// DP.cpp : 定义控制台应用程序的入口点。
//
/************************************************************************/
/*
二叉排序树,旨在解决排序,查找,删除操作
70 105 115 104 67 46 99 111 109
@Author xie_cc QQ:767959265
*/
/************************************************************************/
#include"BiSearchTree.h"
/*创建排序二叉树,不允许有相同的节点*/
TreeNode * BulidBiSearchTree(int len)
{
State temp;
scanf("%d",&temp);
TreeNode * root=CreateTreeNode(temp);
TreeNode * pre=root;
for (int i=1;i<len;i++)
{
scanf("%d",&temp);
TreeNode * cur=CreateTreeNode(temp);
while (pre)//pre 1
{
if (pre->data<temp)
{
if (pre->rightNode==NULL)
{
pre->rightNode=cur;
break;
}
else{
pre=pre->rightNode;
}
}
else if (pre->data>temp)
{
if (pre->leftNode==NULL)
{
pre->leftNode=cur;
break;
}
else{
pre=pre->leftNode;
}
}else
{/*如果相等 pre->data==temp*/
pre->num+=1;
break;
}
}
pre=root;
}
return root;
}
void TraversBiTree(TreeNode * p)
{
if (p==NULL)
{
return;
}
TraversBiTree(p->leftNode);
int n = p->num;
while(n--){
printf("%d ",p->data);
}//打印重复数据这里可以用循环
TraversBiTree(p->rightNode);
}
void InsertBiTreeNode(TreeNode * root,State key)
{
TreeNode * pre=root;
TreeNode *tnode=CreateTreeNode(key);
while(pre){
if (pre->data==key)
{
pre->num++;
break;
}
else if (pre->data<key)
{
if (pre->rightNode==NULL)
{
pre->rightNode=tnode;
break;
}else
{
pre=pre->rightNode;
}
}
else{
if (pre->leftNode==NULL)
{
pre->leftNode=tnode;
break;
}else
{
pre=pre->leftNode;
}
}
}
}
/*查找排序二叉树中存在的结点,返回该结点的指针*/
TreeNode* SearchBiTree(TreeNode * p,State key)
{
if (p)
{
if (p->data==key)
{
return p;
}
else if (p->data<key)
{
SearchBiTree(p->rightNode,key);
}
else{
SearchBiTree(p->leftNode,key);
}
}
else
{
return NULL;
}
}
int VirtualDeleteTreeNode(TreeNode *root,State key)
{
TreeNode*p=SearchBiTree(root,key);
if (p)
{
p->num--;
return 1;
}
return 0;
}
//不用递归的搜索,root为parents节点返回
TreeNode * SearchBiTreeNode(TreeNode ** root,State key)
{
TreeNode * pre=*root;
while(pre){
if (pre->data==key)
{
break;
}
else if (pre->data<key)
{
*root=pre;
pre=pre->rightNode;
}
else{
*root=pre;
pre=pre->leftNode;
}
}
return pre;
}
//删除操作有可能删除根节点,所以返回一个新的根节点
int DeleteTreeNode(TreeNode *root,State key)
{
TreeNode * temp=NULL;
TreeNode * p;
p=SearchBiTreeNode(&root,key);
if (p==NULL)
{
return 0;//找不到该元素,返回0
}
//1.处理叶子节点
if (p->leftNode==NULL && p->rightNode==NULL)
{
//root为当前节点的父指针
if (root->leftNode==p)
{
root->leftNode=NULL;
}
else{
root->rightNode=NULL;
}
free(p);
return 1;
}
//2.处理只有左节点
if (p->rightNode==NULL)
{
temp=p->leftNode;
//先复制数据
p->data=p->leftNode->data;
p->num=p->leftNode->num;
//然后迁移指针
p->leftNode=p->leftNode->leftNode;
p->rightNode=p->leftNode->rightNode;
free(temp);
return 1;
}
//3.处理只有右节点,让当前节点的右子树指向右子树的右子树,左子树指向右子树的左子树。
if (p->leftNode==NULL)
{
temp=p->rightNode;
p->data=p->rightNode->data;
p->num=p->rightNode->num;
p->leftNode=p->rightNode->leftNode;
p->rightNode=p->rightNode->rightNode;
free(temp);
return 1;
}
//4.处理左右节点都有(直接前驱或者直接后继,这里只选直接前驱)
TreeNode * pre;
temp=p;
p=p->leftNode;
if (p->rightNode==NULL)
{
temp->leftNode=p->leftNode;
temp->data=p->data;
temp->num=p->num;
free(p);
}
else{
while(p->rightNode!=NULL){
pre=p;
p=p->rightNode;
}
temp->data=p->data;
temp->num=p->num;
pre->rightNode=NULL;
free(p);
}
return 1;
}
int main(int argc,char* argv[])
{
int n;
printf("please input a number N ,follow to input N number: ");
scanf("%d",&n);
TreeNode *root=BulidBiSearchTree(n);
TraversBiTree(root);
printf("\nplease input a number to search: ");
scanf("%d",&n);
TreeNode *node=SearchBiTree(root,n);
printf(node?"find it\n":"not find\n");
printf("please input a number to insert: ");
scanf("%d",&n);
InsertBiTreeNode(root,n);
TraversBiTree(root);
printf("\n");
printf("please input a number need to delete (virtual) : ");
scanf("%d",&n);
VirtualDeleteTreeNode(root,n);
TraversBiTree(root);
printf("\n");
printf("please input a number need to delete: ");
scanf("%d",&n);
DeleteTreeNode(root,n);
TraversBiTree(root);
getchar();
getchar();
return 0;
}