数据结构中的查找算法-动态查找表(2)

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)》

  查找不成功时

  《数据结构中的查找算法-动态查找表(2)》


     (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)》

      删除不成功:

   《数据结构中的查找算法-动态查找表(2)》



2,平衡二叉树:



3,B-和B+树:

 

    原文作者:查找算法
    原文地址: https://blog.csdn.net/chenxieyy/article/details/48247199
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞