1,二叉排序树:
(1)查找算法
- 查找成功时,其比较次数为该结点所在的的层次数;查找不成功时,比较次数不超过树的高度。
- 二叉排序树的平均查找长度与树的形态有关,当先后插入的关键字有序时,构成的二叉树就蜕变成了单支树,树的深度为n,其平均查找长度为(n+1)/2。在随机情况下,二叉排序树的平均查找长度和logn是等数量级的。
代码如下:
#include "StdAfx.h"
#include<stdio.h>
#include<malloc.h>
#define STACK_INCREMENT 10
#define STACK_INIT_SIZE 100
#define MAXSIZE 50
//二叉排序树的链式存储结构
typedef struct BiTNode
{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//二叉排序树查找
bool SearchBST(BiTree T,int key,BiTree f,BiTree&p)
{
if(!T)
{
p=f;
return false;
}
else if(T->data==key)
{
p=T;
return true;
}
else if(T->data<key)
return SearchBST(T->rchild,key,T,p);
else
return SearchBST(T->lchild,key,T,p);
}
void CreatBST(BiTree &T,int e)
{
BiTree p,s,q;
if(!SearchBST(T,e,NULL,p))
{//找到带插入的位置。一定是找到的结点位置或者是带插入结点的父结点
s=(BiTree)malloc(sizeof(BiTNode));
s->data=e;
s->lchild=NULL;
s->rchild=NULL;
if(!p)T=s;
//else if(e==p->data)//当待排序列中有相同的元素时,将其放在相同元素的右孩子位置。原来的右子树放在其右节点域。
//{
// q=p->rchild;
// p->rchild=s;
// s->rchild=q;
//}
else if(e<p->data)
p->lchild=s;
else
p->rchild=s;
}
}
void main()
{
int length;
int key;
int bst[MAXSIZE];
BiTree BST,p;
BST=(BiTree)malloc(sizeof(BiTNode));
BST=NULL;
printf("***************************\n");
printf(" 二叉排序树查找算法 \n");
printf("***************************\n");
printf("请输入需要查找的序列的个数N (N<%d):",MAXSIZE);
scanf("%d",&length);
printf("\n");
printf("请输入需要查找的序列的关键字:\n");
for(int i=0;i<length;i++)
scanf("%d",&bst[i]);
printf("\n");
printf("请输入待查关键字:");
scanf("%d",&key);
printf("\n");
for(int i=0;i<length;i++)
CreatBST(BST,bst[i]);
printf("输出查找结果:");
if(SearchBST(BST,key,NULL,q))
printf("查找成功\n");
else
printf("查找不成功\n");
printf("\n");
free(BST);
}
运行结果示意图:
查找成功
查找不成功时
(2)删除算法
代码如下:
#include "StdAfx.h"
#include<stdio.h>
#include<malloc.h>
#define STACK_INCREMENT 10
#define STACK_INIT_SIZE 100
#define MAXSIZE 50
//二叉排序树的链式存储结构
typedef struct BiTNode
{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//栈的顺序存储结构
typedef struct
{
BiTree *base;
BiTree *top;
int stacksize;
}Sqstack;
//初始化一个栈,用于二叉树的中序遍历
void InitStack(Sqstack&S)
{
S.base=(BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTNode));
if(!S.base)
exit(0);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
bool Delete(BiTree&p)
{
BiTree q,s;//BiTree 是个类型,是个指针类型,这里声明了两个指针。
if(p->lchild)//左子树存在(这里包括了左右子树都存在的情形),就用删除结点的直接前驱代替它
{
q=p;
s=p->lchild;
while(s->rchild)
{
q=s;
s=s->rchild;
}
p->data=s->data;
if(q!=p)
q->rchild=s->lchild;
else
q->lchild=s->lchild;
free(s);
}
else if(p->rchild)//如果左子树不存在,并且右子树存在,就用删除结点的直接后驱代替它
{
q=p;
s=p->rchild;
while(s->lchild)
{
q=s;
s=s->lchild;
}
p->data=s->data;
if(q!=p)
q->lchild=s->rchild;
else
q->rchild=s->rchild;
free(s);
}
else //如果左右子树都不存在,那么是叶子结点,这里需要将p的值设为空,因为,
{///如果直接free掉,那么它的父结点左右指针域是不确定的,在后续操作中,无法访问父结点的左右指针域的,这是要出问题的。
s=p;
p=NULL;
free(s);
}
return true;
}
bool DeleteBST(BiTree&T,int key)//有问题
{
if(!T)
return false;
else if(T->data ==key)
{
return Delete(T);
}
else if(T->data>key)
{
return DeleteBST(T->lchild,key);
}
else
{
return DeleteBST(T->rchild,key);
}
}
//二叉排序树查找
bool SearchBST(BiTree T,int key,BiTree f,BiTree&p)
{
if(!T)
{
p=f;
return false;
}
else if(T->data==key)
{
p=T;
return true;
}
else if(T->data<key)
return SearchBST(T->rchild,key,T,p);
else
return SearchBST(T->lchild,key,T,p);
}
void CreatBST(BiTree &T,int e)
{
BiTree p,s,q;
if(!SearchBST(T,e,NULL,p))
{//找到带插入的位置。
s=(BiTree)malloc(sizeof(BiTNode));
s->data=e;
s->lchild=NULL;
s->rchild=NULL;
if(!p)T=s;
else if(e<p->data)
p->lchild=s;
else
p->rchild=s;
}
}
//中序遍历二叉排序树
void InOrderTravese(BiTree T)
{
BiTree p;
Sqstack Sqt;
InitStack(Sqt);
p=T;
while(p||Sqt.base!=Sqt.top)
{
if(p)
{
if(Sqt.top-Sqt.base>=Sqt.stacksize)
{
Sqt.base=(BiTree*)realloc(Sqt.base,(Sqt.stacksize+STACK_INCREMENT)*sizeof(BiTNode));
if(!Sqt.base)
exit(OVERFLOW);
Sqt.top=Sqt.base+Sqt.stacksize;
Sqt.stacksize+=STACK_INCREMENT;
}
*Sqt.top++=p;
p=p->lchild;
}
else
{
p=*--Sqt.top;
printf("%d ",p->data);
p=p->rchild;
}
}
printf("\n");
}
void main()
{
int length;
int key;
int bst[MAXSIZE];
BiTree BST,q;
BST=(BiTree)malloc(sizeof(BiTNode));
BST=NULL;
printf("***************************\n");
printf(" 二叉排序树删除算法 \n");
printf("***************************\n");
printf("请输入需要查找的序列的个数N (N<%d):",MAXSIZE);
scanf("%d",&length);
printf("\n");
printf("请输入需要查找的序列的关键字:\n");
for(int i=0;i<length;i++)
scanf("%d",&bst[i]);
printf("\n");
printf("请输入需要删除的关键字:");
scanf("%d",&key);
printf("\n");
for(int i=0;i<length;i++)
CreatBST(BST,bst[i]);
printf("输出删除结果:");
if(DeleteBST(BST,key))
{
printf("删除成功\n");
printf("\n");
printf("输出删除关键字key后的序列为:\n");
InOrderTravese(BST);
}
else
printf("该序列中没有该关键字,删除不成功\n");
printf("\n");
free(BST);
}
运行结果如下
删除成功
删除不成功:
2,平衡二叉树:
3,B-和B+树: