标签:
//节点
typedef struct bsnode{
int data;
struct bstree *lchild;
struct bstree *rchild;
}bsnode,*bstree;
------------------------------------------------------------------------------------
创建二叉排序树:
1创建二叉树:
void createbstree(bstree &bt){ //调用插入函数逐个插入节点
int key;
scanf("%d",&key);
if(key!=‘ ‘){
insertnode(bt,key);
scanf("%d",&key);
}
}
2.插入节点:
bstree insertbsnode(bstree bt,char key){
bstree p=bt;
while(p){ //找到要插入的位置,当结束时p为空,pre为要插入节点的双亲
pre=p;
if(p->data==key)return bt;
else if(keydata) p=p->lchild;
else p=p->rchild;
}
q=(bstree)maliic(sizeof(bsnode));
q->data=key;
q->lchild=0;
q->rchild=0;
if(!bt) bt=q;
else{
if(keydata)
pre->lchild=q;
else
pre->rchild=q;
}
return bt;
}
3.删除树(调用删除函数逐个删除节点)
void deleteTree(BiTree T){
if(!T)
return OK;
else{
if(T->lchild)
deleteTree(T->firstchild);
if(T->lchild)
deleteTree(T->nextsibling);
free(T);
T=NULL;
}
}
4.删除节点:
bstree deletebsnode(bstree bt){
bstree p=bt;
while(p){
pre=p; //标记其父节点以便删除
if(key==p->data) break; //找到要删除的节点
else if(keydata)
p=p->lchild;
else
p=p->rchild;
}
if(!bt||!p) return bt; // 树为空或者没有找到
if(p->lchild==NULL||p->rchild==NULL) //非空但要删除的节点没有左/右子树/没有孩子
if(pre==NULL){ //要删除的节点为根节点
if(!p->child)
bt=p->rchild;
else
bt=p->lchild;
}
else{ //要删除的节点不为根节点
if(!p->lchild){
if(p==pre->lchild)
pre->lchild=p->rchild;
else
pre->rchild=p->rchild;
}
else{
if(p==pre->lchild)
pre->lchild=p->lchild;
else
pre->rchild=p->lchild;
}
}
else{ //要删除的节点左右字数都存在。此时找出左子树的最大值,及左子树的最右孩子/根节点,将其复制到要删除的节点上,然后删除该孩子
pre=p; //保留p指针指向要删除的节点,用俩个指针分别指向前驱及后继
q=pre->lchild;
while(q->rchild){ //找出左子树的最右孩子
pre=q;
q=pre->rchild;
}
p->data=q->data; //将左子树最右孩子或者左子数根节点的值赋予要删除的节点
if(pre==p) //左子树没有最右孩子
pre->lchild=q->lchild;
else //找到了最右孩子,此时最右孩子一定为其前驱的右孩子
pre->rchild=q->lchild;
}
}
-----------------------------------------------------------------------------------
二叉排序树的遍历(与二叉树遍历算法一样)
1.递归遍历
//先序遍历
void PreOrderTraverse(BsTree &T){
if(T){
visit(T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
return OK;
}
//中序遍历
void InOrderTraverse(BsTree &T){
if(T){
InOrderTraverse(T->lchild);
visit(T->data);
InOrderTraverse(T->lchild);
}
return OK;
}
//后序遍历
void PostOrderTraverse(BsTree &T){
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
visit(T->data);
}
}
2.非递归遍历,用栈辅助。
算法思想:把根节点及所有做孩子依次压入栈,再依次取出把其右孩子压入栈,再依次探查其左右孩子
//先序遍历
void PreOrderTraver(BsTree &T){
Stack S;
IniyStack(S);
BsTree p=T;
while(p||!emptyStack(S)){
if(p){
visit(p->data);
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
p=p->rchild;
}
}
return OK;
}
//中序遍历
void InOrderTraverse(Bstree &T){
Stcak S;
InitStack(S);
BsTree p=T;
while(p||!emptyStqck(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
visit(p->data);
p=p->rchild;
}
}
return OK;
}
//后序遍历
void PostOrderTraver(BsTree &T){
Stack S;
InitStack(S);
BsTree p=T;
while(p||!emptyStack(S)){
if(p){
push(S,p);
p=p->lchild;
}
else{
if(p->rchild==NULL||pre==p->rchild){
visit(T->data);
pre=p;
p=NULL;
}
else{
p=p->rchild;
}
}
}
return OK;
}
//层次遍历二叉树,借助队列
void LevelOrderTreaverse(BsTree &T){
Queue Q;
InitQueue(Q);
BsTree p=T;
Enqueu(Q,p);
while(!emptyQueue(Q)){
DeQueue(Q,p);
if(p){
visit(p->data);
EnQueue(Q,p->lchild);
EnQUeue(Q,p->rchild);
}
}
return OK;
}
---------------------------------------------------------------------------------
查找某个节点x
查找某个信息是否在二叉树中(先序递归遍历)
void searchch(BsTree T,char ch){
BsTree p=T;
if(p){
if(p->data==ch)
return p;
else{
searchch(T->lchild,ch);
searchch(T->rchild,ch);
}
}
}
---------------------------------------------------------------------------------
插入节点,删除节点,交换左右子树
1.插入节点
在遍历的基础上找到其父节点再插入。
2.删除节点
在遍历的基础上找该节点再删除。
3.交换左右子树
//递归法
void exchange(BsTree T){
BsTree item;
if(T){
exchange(T->lchild);
exchange(T->rchild);
item=T->lchild;
T->lchild=T->rchild;
T->rchild=item;
}
}
//非递归法
利用非递归遍历交换
------------------------------------------------------------------------------------
求节点个数/叶子节点个数,树的深度
1.树的结点个数
//递归求解
void NodeNum(BsTree T)
{
if(!T)
return 0;
else
return NodeNum(T->lchild)+NodeNum(T->rchild)+1;
}
//非递归求解
利用非递归遍历方法求解
---------------------------------
2.求叶子节点个数:
//递归求解
void leavenum(BsTree T){
if(T){
if(T->lchild==NULL&&T->rchild==NULL)
return 1;
else
return leavenum(T-lchild)+leavenum(T->rchild);
}
}
//非递归求解
利用非递归遍历求解
-----------------------------------
3.求二叉树的深度
void depth(BsTree T){
BsTree P=T;
int lh=0,rh=0;
if(!p)
return 0;
else{
lh=depth(T->lchild);
rh=depth(T->rchild);
return (lh>rh?lh:rh)+1;
}
}
---------------------------------------------------------------------------------------------
二叉排序树的基本操作
标签:
原文地址:http://www.cnblogs.com/yujon/p/5467599.html