#include <stdio.h>
#include <stdlib.h>
///二叉排序树,中序遍历,查找typedef int KeyType;
typedef struct BSTNode{KeyType key;struct BSTNode *lchild,*rchild;
}BSTNode,*BiTree;//二叉查找树核心
//非递归创建二叉查找树
int BST_Insert(BiTree& T,KeyType k)
{//子函数的传递 因为该函数是被下面函数引用的子函数 故引用与下方保持一致BiTree TreeNew= (BiTree)calloc(1,sizeof(BSTNode));TreeNew->key=k;//把值放入if(NULL==T){T=TreeNew;return 0;}BiTree p=T,parent;//用p来查找树while(p)//p是用来遍历的{parent=p;//parent用来存p的父亲 当p等于NULL时,parent存的刚好是NULLif(k>p->key){p=p->rchild;} else if(k<p->key){p=p->lchild;} else{return -1;//相等的元素不可以放入查找树,考研不会考相等元素放入问题}}//接下来判断放到父亲左边还是右边if(k>parent->key){parent->rchild=TreeNew;}else{//放到父亲左边parent->lchild=TreeNew;}return 0;
}//二叉排序树函数
void Creat_BST(BiTree& T,KeyType* str,int len)
{int i;for(i=0;i<len;i++){BST_Insert(T,str[i]);//把某个结点放入 二叉查找树;}
}//中序遍历有序输出(因为中序结果就相当于垂直投影 进而有序输出了排好序的树)
void InOrder(BiTree T)
{if(T!=NULL){InOrder(T->lchild);printf("%3d",T->key);InOrder(T->rchild);}
}BiTree BST_Insert(BiTree T,KeyType k,BiTree &parent)//parent是会变的因为相当于偏离的p
{parent=NULL;while (T!=NULL&&k!=T->key){parent=T;if(k>T->key){T=T->rchild;} else{T=T->lchild;}}return T;
}//递归方法删除树中结点
void DeleteNode(BiTree &root,KeyType x) //root是树根
{if(root==NULL){return;}if(root->key>x)//当前结点大于要删除的结点 往左子树去找{DeleteNode(root->lchild,x);} else if(root->key<x)//当前结点小于要删除的结点 往右子树去找{DeleteNode(root->rchild,x);} else{//找到了删除的结点 相等//刚好找到是最难的 如果是叶子结点直接删除需要补充完整 但如果是其它结点//删除后仍要保持树的完整性if(root->lchild==NULL)//左子树为空,右子树直接顶上去{BiTree tempNode=root;root=root->rchild;free(tempNode);}else if(root->rchild==NULL){BiTree tempNode=root;root=root->lchild;free(tempNode);}else{//两边都不为空//一般的删除策略是左子树的最大数据 或 右子树的最小数据//代替要删除的结点(这里采用查找左子树最大数据来代替(即左子树最右结点))BiTree tempNode=root->lchild;while (tempNode->rchild!=NULL)//向右找最大的{tempNode=tempNode->rchild;}root->key=tempNode->key;//tempNode对应的值替换到要删除的值的位置上DeleteNode(root->lchild,tempNode->key);//在左子树中找到tempNode的值,把其删除}}
}int main() {BiTree T=NULL;//树根KeyType str[7]={54,20,66,40,28,79,58};//将要进入二叉排序树的元素值Creat_BST(T,str,7);InOrder(T);//中序遍历二叉查找树是由小到大的printf("\n");BiTree search,parent;search = BST_Insert(T,40,parent);if(search){printf("find key %d\n",search->key);} else{printf("not find\n");}DeleteNode(T,40);//删除某个结点InOrder(T);printf("\n");return 0;
}