写这篇文章前,我把我之前写的二叉排序树的代码改了许多回,终于改好了。
话不多说,上代码。
首先是一些前期准备如下:
#include"stdio.h"
#include"stdlib.h"
#define StackInitSize 100
#define Maxsize 100
typedef void Status;
typedef int TElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree,BSTNode;
typedef BiTree SElemType;
typedef struct Stack{
SElemType *top;
SElemType *base;
int size;
}Stack;
bool EmptyStack(Stack S){
if(S.base==S.top)
return true;
return false;
}
Status Pop(Stack &S,SElemType &e){
if (EmptyStack(S))return;
e=*S.top;
S.top--;
}
Status Push(Stack &S,SElemType e){
if(S.top-S.base>=99)return;
S.top++;
*(S.top)=e;
}
Status InitStack(Stack &S){
S.base=S.top=(SElemType *)malloc(StackInitSize*sizeof(SElemType));
if(!S.base)
return;
S.size=StackInitSize;
}
void InitBiTree(BiTree &BT){
BT=(BiTNode*)malloc(sizeof(BiTNode));
BT=NULL;
}
接着开始进入正题,以下是相关函数:
1.二叉排序树的搜索
BiTree Search_BST(BiTree BT,int key){//递归搜索二叉排序树
if(BT==NULL)return NULL;
if(key<BT->data) return Search_BST(BT->lchild,key);
else if(key>BT->data) return Search_BST(BT->rchild,key);
else return BT;
}
BiTree Search_BST2(BiTree BT,int key,BiTree *parent){//非递归搜索二叉排序树
BiTNode *p=BT;
while(p!=NULL){
if(key<p->data) {*parent=p;p=p->lchild;}
else if(key>p->data) {*parent=p;p=p->rchild;}
else return p;
}
return NULL;
}
2.二叉排序树的插入
void Insert_BST(BiTree &BT,int key){
BiTree p=(BiTree)malloc(sizeof(BiTree)); //初始化插入节点
if(p==NULL) return;
p->data=key;
p->lchild=p->rchild=NULL;
if(BT==NULL){//空树时,直接作为根节点
BT=p;
return;
}
//是否存在,已存在则返回,不插入
if (Search_BST(BT,key) != NULL) return;
BiTree tnode=BT,parent=NULL; //进行插入,首先找到要插入的位置的父节点
while(tnode){
parent=tnode;
if(key<tnode->data)tnode=tnode->lchild;//到最后tnode会为NULL,parent会保存着父节点
else tnode=tnode->rchild;
}
if(key<parent->data) parent->lchild=p;
else parent->rchild=p;
}
3.二叉排序树的构造
void CreateBST(BiTree &BT, int a[], int n)
{
int i;
for (i = 0; i < n; i++)
{
Insert_BST(BT, a[i]);
}
}
4.二叉排序树的删除的辅助函数
void Delete_BT(BiTree &BT){
BiTree p=BT;
if(p->lchild&&!p->rchild){
BT=p->lchild;
free(p);
}
else if(!p->lchild&&p->rchild){
BT=p->rchild;
free(p);
}
}
BiTree SearchMin(BiTree BT)//递归
{
if (BT == NULL)
return NULL;
if (BT->lchild == NULL)
return BT;
else //一直往左孩子找,直到没有左孩子的结点
return SearchMin(BT->lchild);
}
BiTree SearchMax(BiTree BT)//非递归
{
if (BT == NULL)
return NULL;
BiTree p=BT;
while(p->rchild){
p=p->rchild;
}
return p;
}
注意:这里SearchMax其实也可以写成递归的形式,对比SearchMin就会了。
5.二叉排序树的删除
(1)以前驱替代
p的前驱:p的左子树中key最大的结点
void DeleteBSTNode_pre(BiTree &BT, int key)//以前驱替代
{
BiTree pre,parent;
BiTree p =Search_BST2(BT,key,&parent);
if(p==BT){
Delete_BT(BT);
return;
}
if(!p->lchild&&!p->rchild) {//lchild,rchild都不存在
if(p->data<parent->data) parent->lchild=NULL;
else parent->rchild=NULL;
}
else if(!p->lchild&&p->rchild) {//rchild存在
if(p->data<parent->data) parent->lchild=p->rchild;//p的data小于parent 的,故后写lchild
else parent->rchild=p->rchild;//p的data大于parent 的,故后写rchild
}
else if(p->lchild&&!p->rchild) {//lchild存在
if(p->data<parent->data) parent->lchild=p->lchild;
else parent->rchild=p->lchild;
}
else{//lchild,rchild都存在
pre=SearchMax(p->lchild);
if(pre==p->lchild) {//说明pre结点没有右孩子
p->data=pre->data;
p->lchild=pre->lchild;
}
else{
p->data=pre->data;
DeleteBSTNode_pre(p->lchild,pre->data);
}
}
}
(2)以后继替代
p的后继:p的右子树中key最小的结点
void DeleteBSTNode_pos(BiTree &BT, int key)//以后继替代
{
BiTree pos,parent;
BiTree p =Search_BST2(BT,key,&parent);
if(p==BT){
Delete_BT(BT);
return;
}
if(!p->lchild&&!p->rchild) {//lchild,rchild都不存在
if(p->data<parent->data) parent->lchild=NULL;
else parent->rchild=NULL;
}
else if(!p->lchild&&p->rchild) {//rchild存在
if(p->data<parent->data) parent->lchild=p->rchild;//p的data小于parent 的,故后写lchild
else parent->rchild=p->rchild;//p的data大于parent 的,故后写rchild
}
else if(p->lchild&&!p->rchild) {//lchild存在
if(p->data<parent->data) parent->lchild=p->lchild;
else parent->rchild=p->lchild;
}
else{//lchild,rchild都存在
pos=SearchMin(p->rchild);
if(pos==p->rchild) {//说明pos结点没有左孩子
p->data=pos->data;
p->rchild=pos->rchild;
}
else{
p->data=pos->data;
DeleteBSTNode_pos(p->rchild,pos->data);
}
}
}
6.中序遍历
(1)递归版
void InOrder(BiTree BT){// 中序递归遍历
if(BT){//BT不为空时执行以下语句
InOrder(BT->lchild);
printf("%d ",BT->data);
InOrder(BT->rchild);
}
}
(2)非递归版
//中序非递归遍历二叉树
Status NRInOrder(BiTree BT,Stack &S)
{
BiTNode *p;
p=BT;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
printf("%d ",p->data);
p=p->rchild;
}
}
}
7.测试数据
8.用来理解删除单分支结点时的情况的
9.完整代码
#include"stdio.h"
#include"stdlib.h"
#define StackInitSize 100
#define Maxsize 100
typedef void Status;
typedef int TElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree,BSTNode;
typedef BiTree SElemType;
typedef struct Stack{
SElemType *top;
SElemType *base;
int size;
}Stack;
bool EmptyStack(Stack S){
if(S.base==S.top)
return true;
return false;
}
Status Pop(Stack &S,SElemType &e){
if (EmptyStack(S))return;
e=*S.top;
S.top--;
}
Status Push(Stack &S,SElemType e){
if(S.top-S.base>=99)return;
S.top++;
*(S.top)=e;
}
Status InitStack(Stack &S){
S.base=S.top=(SElemType *)malloc(StackInitSize*sizeof(SElemType));
if(!S.base)
return;
S.size=StackInitSize;
}
void InitBiTree(BiTree &BT){
BT=(BiTNode*)malloc(sizeof(BiTNode));
BT=NULL;
}
BiTree Search_BST(BiTree BT,int key){//递归搜索二叉排序树
if(BT==NULL)return NULL;
if(key<BT->data) return Search_BST(BT->lchild,key);
else if(key>BT->data) return Search_BST(BT->rchild,key);
else return BT;
}
BiTree Search_BST2(BiTree BT,int key,BiTree *parent){//非递归搜索二叉排序树
BiTNode *p=BT;
while(p!=NULL){
if(key<p->data) {*parent=p;p=p->lchild;}
else if(key>p->data) {*parent=p;p=p->rchild;}
else return p;
}
return NULL;
}
void Insert_BST(BiTree &BT,int key){
BiTree p=(BiTree)malloc(sizeof(BiTree)); //初始化插入节点
if(p==NULL) return;
p->data=key;
p->lchild=p->rchild=NULL;
if(BT==NULL){//空树时,直接作为根节点
BT=p;
return;
}
//是否存在,已存在则返回,不插入
if (Search_BST(BT,key) != NULL) return;
BiTree tnode=BT,parent=NULL; //进行插入,首先找到要插入的位置的父节点
while(tnode){
parent=tnode;
if(key<tnode->data)tnode=tnode->lchild;//到最后tnode会为NULL,parent会保存着父节点
else tnode=tnode->rchild;
}
if(key<parent->data) parent->lchild=p;
else parent->rchild=p;
}
void Delete_BT(BiTree &BT){
BiTree p=BT;
if(p->lchild&&!p->rchild){
BT=p->lchild;
free(p);
}
else if(!p->lchild&&p->rchild){
BT=p->rchild;
free(p);
}
}
BiTree SearchMin(BiTree BT)//递归
{
if (BT == NULL)
return NULL;
if (BT->lchild == NULL)
return BT;
else //一直往左孩子找,直到没有左孩子的结点
return SearchMin(BT->lchild);
}
BiTree SearchMax(BiTree BT)//非递归
{
if (BT == NULL)
return NULL;
BiTree p=BT;
while(p->rchild){
p=p->rchild;
}
return p;
}
void CreateBST(BiTree &BT, int a[], int n)
{
int i;
for (i = 0; i < n; i++)
{
Insert_BST(BT, a[i]);
}
}
void DeleteBSTNode_pre(BiTree &BT, int key)//以前驱替代
{
BiTree pre,parent;
BiTree p =Search_BST2(BT,key,&parent);
if(p==BT){
Delete_BT(BT);
return;
}
if(!p->lchild&&!p->rchild) {//lchild,rchild都不存在
if(p->data<parent->data) parent->lchild=NULL;
else parent->rchild=NULL;
}
else if(!p->lchild&&p->rchild) {//rchild存在
if(p->data<parent->data) parent->lchild=p->rchild;//p的data小于parent 的,故后写lchild
else parent->rchild=p->rchild;//p的data大于parent 的,故后写rchild
}
else if(p->lchild&&!p->rchild) {//lchild存在
if(p->data<parent->data) parent->lchild=p->lchild;
else parent->rchild=p->lchild;
}
else{//lchild,rchild都存在
pre=SearchMax(p->lchild);
if(pre==p->lchild) {//说明pre结点没有右孩子
p->data=pre->data;
p->lchild=pre->lchild;
}
else{
p->data=pre->data;
DeleteBSTNode_pre(p->lchild,pre->data);
}
}
}
void DeleteBSTNode_pos(BiTree &BT, int key)//以后继替代
{
BiTree pos,parent;
BiTree p =Search_BST2(BT,key,&parent);
if(p==BT){
Delete_BT(BT);
return;
}
if(!p->lchild&&!p->rchild) {//lchild,rchild都不存在
if(p->data<parent->data) parent->lchild=NULL;
else parent->rchild=NULL;
}
else if(!p->lchild&&p->rchild) {//rchild存在
if(p->data<parent->data) parent->lchild=p->rchild;//p的data小于parent 的,故后写lchild
else parent->rchild=p->rchild;//p的data大于parent 的,故后写rchild
}
else if(p->lchild&&!p->rchild) {//lchild存在
if(p->data<parent->data) parent->lchild=p->lchild;
else parent->rchild=p->lchild;
}
else{//lchild,rchild都存在
pos=SearchMin(p->rchild);
if(pos==p->rchild) {//说明pos结点没有左孩子
p->data=pos->data;
p->rchild=pos->rchild;
}
else{
p->data=pos->data;
DeleteBSTNode_pos(p->rchild,pos->data);
}
}
}
void InOrder(BiTree BT){// 中序递归遍历
if(BT){//BT不为空时执行以下语句
InOrder(BT->lchild);
printf("%d ",BT->data);
InOrder(BT->rchild);
}
}
//!EmptyQueue(Q)
//!EmptyStack(S)
//中序非递归遍历二叉树
Status NRInOrder(BiTree BT,Stack &S)
{
BiTNode *p;
p=BT;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
printf("%d ",p->data);
p=p->rchild;
}
}
}
int main(){
BiTree BT;
Stack S;
InitStack(S);
InitBiTree(BT);
int arr[] = { 10,6,11,4,7,13,3,5,8,12};
CreateBST(BT,arr,10);
printf("\n中序遍历的结果为:\n");//中序遍历的结果应该为递增顺序
InOrder(BT);
DeleteBSTNode_pre(BT,4);
printf("\n中序遍历的结果为:\n");
InOrder(BT);
return 0;
}
//{10,6,12,4,8,11,14,5,7,13} 二叉排序树1
//{10,6,11,4,7,13,3,5,8,12} 二叉排序树2
//{10,8,6,4,2} 删除根节点10 试试看
总体代码就是这样了,我进行过多次测试,应该没有什么大问题了。
如果有什么写的不好的地方请指正,谢谢大家!