/**
头文件、宏定义与自测主函数
**/
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<stack>
#define MAXSIZE 11
#define ERROR -1
#define NotFound 0;
using namespace std;
typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
//层次遍历,用于自测
void LevelorderTraversal(BinTree BT){
if(!BT)
return;
//队列,简化起见这里没有应用循环队列
BinTree q[1000];
int front = 0;
int rear = 1;
//根结点入队
q[0] = BT;
//计数变量用于判断本层是否遍历完
//已经遍历结点个数
int _count = 0;
//下层结点总数,初始为根节点1
int nextCount = 1;
//工作指针
BinTree temp;
//队列不为空
while(front<rear){
//计数
_count++;
//出队
temp = q[front++];
printf("%d ",temp->Data);
//左右子孩子入队
if(temp->Left)
q[rear++] = temp->Left;
if(temp->Right)
q[rear++] = temp->Right;
//判断本层结点是否遍历完
if(_count==nextCount){
cout<<endl;
//计数器清零
_count=0;
//计算下层结点数量
nextCount = rear-front;
}
}
}
int main(){
int tree_array[]={5,8 ,6, 2 ,4, 1 ,0 ,10, 9, 7};
int d[]={5 ,7 ,0 ,10 ,3};
BinTree f = NULL;
for(int i = 0 ; i<10 ;i++){
f = Insert(f,tree_array[i]);
}
int k = 2;
LevelorderTraversal(f);
for(int i = 0 ;i <5 ;i++){
f = Delete(f,d[i]);
cout<<"=========="<<i+1<<"=========: "<<d[i]<<endl;
LevelorderTraversal(f);
}
return 0;
}
查找类函数
//查找
Position Find( BinTree BST, ElementType X ){
if(!BST)
return NULL;
if(BST->Data==X)
return BST;
//往左边找
BinTree outL = Find(BST->Left,X);
//往右边找
BinTree outR = Find(BST->Right,X);
return outL?outL:outR;
}
//查找最大
Position FindMax(BinTree BST){
if(!BST)
return NULL;
//最右边的结点
if(!BST->Right)
return BST;
//往右找即可
return FindMax(BST->Right);
}
//查找最小
Position FindMin(BinTree BST){
if(!BST)
return NULL;
//最左边的结点
if(!BST->Left)
return BST;
//往左找即可
return FindMin(BST->Left);
}
插入函数,注意递归的设计
//向二叉排序树中插入,递归
BinTree Insert(BinTree BST, ElementType X){
if(!BST){
//新建一个结点
BinTree t = (BinTree)malloc(sizeof(struct TNode));
t->Left = t->Right = NULL;
t->Data = X;
BST = t;
}//缩小问题规模,转向考虑左右子树
else if(BST->Data>X)
BST->Left = Insert(BST->Left,X);
else if(BST->Data<X)
BST->Right = Insert(BST->Right,X);
//若等号成立元素存在,不用处理
return BST;
}
//向二叉排序树中插入,非递归
BinTree Insert(BinTree BST, ElementType X){
//先新建一个结点
BinTree t = (BinTree)malloc(sizeof(struct TNode));
t->Left = t->Right = NULL;
t->Data = X;
//为空则直接返回新结点指针
if(!BST)
return t;
//否则找到合适的位置
BinTree work = BST;
//记录待插入位置的双亲
BinTree parent = BST;
while(work){
//维护双亲
parent = work;
if(work->Data>X)
//待插入位置
work = work->Left;
else if(work->Data<X)
work = work->Right;
else//存在相同值则不插入
return BST;
}
//待插入结点为双亲的左/右孩子
if(parent->Data>X)
parent->Left = t;
else
parent->Right = t;
return BST;
}
删除函数,有三种情况。待删除结点:
1.为叶子结点:直接删除
2.为单分支结点:用子树的根取代待删除结点
3.为双分支结点:与有序后继(中序遍历的后继即右子树中最小/左的结点)交换元素,转换为删除后继所在结点即第1或第2种情况
//删除二叉排序树结点,递归
BinTree Delete( BinTree BST, ElementType X ){
if(!BST)
printf("Not Found\n");
else if(BST->Data==X){
//1.左右双分支结点
if(BST->Left&&BST->Right){
//右子树中最小(左)为后继
BinTree rear = FindMin(BST->Right);
//不涉及待删除结点元素值的操作,交换过程可简化成单向赋值
BST->Data = rear->Data;
//在右子树中删除后继
BST->Right = Delete(BST->Right,rear->Data);
//2.单支与叶子可归纳如下,删除叶子时下式中BST赋值为空即删除了叶子
}else
BST = BST->Left?BST->Left:BST->Right;
//递归
}else{
if(BST->Data>X)
BST->Left = Delete(BST->Left,X);
else
BST->Right = Delete(BST->Right,X);
}
return BST;
}