数据结构课设(五)二叉排序树与平衡二叉树的实现

这篇具有很好参考价值的文章主要介绍了数据结构课设(五)二叉排序树与平衡二叉树的实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数据结构课设(五)二叉排序树与平衡二叉树的实现 C代码


一、问题描述

假定二叉排序树与平题所处理数据均为整型。分别采用二叉链表和顺序表作存储结构,实现对二叉衡二叉树的操作。具体要求如下:
(1)用二叉链表作存储结构:
①读入一个整数序列L(要求该整数序列从磁盘文件读取),生成一棵二叉排序树②对二叉排序树T作中序遍历,输出结果。③计算二叉排序树T查找成功的平均查找长度,输出结果。④输入元素x,查找二叉排序树T。若存在含x的结点,则删除该结点,并作中序遍历(执行操作②);否则输出信息“无x”。⑤用数列L,生成一棵平衡的二叉排序树BT。如果当插人新元素之后,发现当前的二叉排序树BT不是平衡的二叉排序树,则将它转换成平衡的二叉排序树BT.⑥计算平衡的二叉排序树BT的平均查找长度,输出结果。
(2)用顺序表作存储结构:
①读人一个整数序列L(要求该整数序列从磁盘文件读取),生成一棵二叉排序树T.②对二叉排序树T作中序遍历,输出结果。③计算二叉排序树T查找成功的平均查找长度,输出结果。④输人元素x,查找二叉排序树T. 若存在含x的结点,则删除该结点,并作中序遍历。

二、代码

经过分析,本题需要完成的需求是:分别以顺序表和二叉链表完成输入,中序遍历排序,查删结点,求平均查找长度的操作。

1.C代码

代码如下(示例):

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct Node
{
	int data;
	int height;
	Node *rchild,*lchild,*parent;
}BSTNode,*BSTree;

BSTNode *T;

void insertBST(int k)
{
	BSTNode *y=NULL;
	BSTNode *x=T;
	BSTNode *z;
	z=(BSTNode *)malloc(sizeof(Node));
	z->data=k;
	z->height=1;
	z->lchild=NULL;
	z->rchild=NULL;
	while(x!=NULL)
	{
		y=x;
		if(z->data<x->data)
		{
			x=x->lchild;
			z->height++;
		}
		else
		{
			x=x->rchild;
			z->height++;
		}
	}
	z->parent=y;
	if(y==NULL) T=z;
	else
	{
	if(z->data<y->data) y->lchild=z;
	else y->rchild=z;
	}
	}

void Inorder(BSTNode *u)
{
	if(u==NULL) return;
	Inorder(u->lchild);
	printf("%d ",u->data);
	Inorder(u->rchild);
}
double CalLength(BSTree *T)
{
	static double length=0;
	static int n=0;
	if(*T)
	{
		length+=(*T)->height;
		CalLength(&(*T)->lchild);
		n++;
		CalLength(&(*T)->rchild);
	}
	return length/n;
}
BSTree SearchDeleteBST(int  key)  //删除函数
{
	BSTree p=T,q=NULL,s,f;
    while(p!=NULL)   //查找要删除的点
    {
        if(p->data==key)
		break;
        q=p; //q指向要删结点的父母
        if(p->data>key)   p=p->lchild;
        else p=p->rchild;
    }
    if(p==NULL)
	return  T;    //查找失败
    if(p->lchild==NULL)     //p指向当前要删除的结点
    {
        if(q==NULL)   T=p->rchild;  
        else if(q->lchild==p)    q->lchild=p->rchild;  //p为q的左孩子
        else q->rchild=p->rchild; //p为q的右孩子
        free(p);
    }
	else
	{           //p的左孩子不为空
        f=p;
        s=p->lchild;
        while(s->rchild)   //左拐后向右走到底
        {
            f=s;
            s=s->rchild;
        }
        if(f==p)    f->lchild=s->lchild;  //重接f的左子树
        else    f->rchild=s->lchild;   //重接f的右子树
        p->data=s->data;
        free (s);
    }
    return  T;
}
int searchBST(BSTree T,int key,BSTree f,BSTree *p) //查找函数
{
    if(!T)
	{
		*p=f;
		return 0;
	}           //查找不成功
	else if(key==T->data)    
	{
		*p=T;
		return 1;
	} /*查找成功*/
	else if(key<T->data)   searchBST(T->lchild,key,T,p);   //在左子树中继续查找
	else  searchBST(T->rchild,key,T,p); //在右子树中继续查找
}
int main()
{
    int num;
    char ch;
    BSTree p=NULL;
	printf("输入L:");
    do
	{	
        scanf("%d",&num);
        insertBST(num);
        scanf("%c",&ch);
        if(ch=='\n') break;
    }while(ch!='\n');
    printf("中序遍历结果为:\n");
    Inorder(T); 
    printf("\n");
    printf("平均查找长度为:%3.1f",CalLength(&T));
    printf("\n");
    printf("输入查找元素,若该结点存在则删除该结点:");
    scanf("%d",&num); 
    if(searchBST(T,num,NULL,&p))
    {
        T=SearchDeleteBST(num);
        printf("\n删除成功,中序遍历输出:\n");
        Inorder(T);
    }
    else
        printf("没有找到该结点%d",num);
    return 0;
}
#include<stdio.h>
#include<stdlib.h>
#define LH 1
#define EH 0
#define RH -1
typedef struct Node
{
	int data;
	int BF;//平衡因子(balance factor)
	struct Node *lchild,*rchild;
}BSTNode,*BSTree;
void R_Rotate(BSTree *p)//以p为根节点的二叉排序树进行右旋转
{
	BSTree L;
	L=(*p)->lchild;
	(*p)->lchild=L->rchild;
	L->rchild=(*p);
	*p=L;//p指向新的根节点
}
void L_Rotate(BSTree *p)//以p为根节点的二叉排序树进行左旋转
{
	BSTree R;
	R=(*p)->rchild;
	(*p)->rchild=R->lchild;
	R->lchild=(*p);
	*p=R;
}
void LeftBalance(BSTree *T)
{
	BSTree L,Lr;
	L=(*T)->lchild;
	switch(L->BF)
	{
	  //检查T的左子树平衡度,并作相应的平衡处理
		case LH://新节点插入在T的左孩子的左子树上,做单右旋处理
		(*T)->BF=L->BF=EH;
		R_Rotate(T);
		break;
		case RH://新插入节点在T的左孩子的右子树上,做双旋处理
		Lr=L->rchild;
		switch(Lr->BF)
	    {
		    case LH:
		    (*T)->BF=RH;
		    L->BF=EH;
		    break;
		    case EH:
		    (*T)->BF=L->BF=EH;
		    break;
		    case RH:
		    (*T)->BF=EH;
		    L->BF=LH;
		    break;
	    }
		Lr->BF=EH;
	    L_Rotate(&(*T)->lchild);
	    R_Rotate(T);
	}
}
void RightBalance(BSTree *T)
{ 
	BSTree R,Rl;
	R=(*T)->rchild;
	switch(R->BF)
	{
	case RH://新节点插在T的右孩子的右子树上,要做单左旋处理
	        (*T)->BF=R->BF=EH;
	     L_Rotate(T);
	     break;
	case LH://新节点插在T的右孩子的左子树上,要做双旋处理
	    Rl=R->lchild;
	    switch(Rl->BF)
	    {
		    case LH:
		    (*T)->BF=EH;
		    R->BF=RH;
		    break;
		    case EH:
		    (*T)->BF=R->BF=EH;
		    break;
		    case RH:
		    (*T)->BF=LH;
		    R->BF=EH;
		    break;
	    }
	Rl->BF=EH;
	R_Rotate(&(*T)->rchild);
	L_Rotate(T);
 }
}

bool InsertAVL(BSTree *T,int e,bool *taller)//变量taller反应T长高与否
{
	if(!*T)
	{
		*T=(BSTree)malloc(sizeof(BSTNode));
		(*T)->data=e;
		(*T)->lchild=(*T)->rchild=NULL;
		(*T)->BF=EH;
		*taller=true;
	}
	else
	{
		if(e==(*T)->data)//不插入
		{
			*taller=false;
			return false; 
		}
		if(e<(*T)->data)
		{
			if(!InsertAVL(&(*T)->lchild,e,taller))//未插入
			  return false;
			if(*taller)//以插入左子树,且左子树变高
			{
				switch((*T)->BF)
				{
				    case LH://原本左子树比右子树高,需要做左平衡处理
				    LeftBalance(T);
				    *taller=false;
				    break;
				    case EH://原本左右子树等高,现因左子树增高而树增高
				    (*T)->BF=LH;
				    *taller=true;
				    break;
				    case RH://原本右子树比左子树高,现在左右子树等高
				    (*T)->BF=EH;
				    *taller=false;
				    break;
				}
		   }
    	}
		else
		{
			//应在T的右子树中搜寻
			if(!InsertAVL(&(*T)->rchild,e,taller))
			    return false;
			if(*taller)//插入右子树,且右子树长高
			{
				switch((*T)->BF)
				{
				      case LH://原本左子树比右子树高,现在左右子树等高
					(*T)->BF=EH;
				    *taller=false;
					break;
				      case EH://原本左右子树等高,现在右子树变高
				      (*T)->BF=RH;
				      *taller=true;
				      break;
				    case RH://原本右子树比左子树高,现在需做右平衡处理
				      RightBalance(T);
				      *taller=false;
				      break;
				}
		    }
	   } 
	}
	 return true;
}

bool Find(BSTree T,int key)
{
	if(!T)
	return false;
	else if(T->data==key)
	return true;
	else if(T->data<key)
	return Find(T->rchild,key);
	else
	return Find(T->lchild,key);
}
void Inorder(BSTree T)
{
	if(T)
	{
		printf("%d",T->data);
		if(T->lchild||T->rchild)
		{
			printf("(");
			Inorder(T->lchild);
			printf(",");
			Inorder(T->rchild);
			printf(")");
		}
	}
}
double CalAveLength(BSTree T,int A[],int num)
{
	double len=0;
	int i;
	BSTree rt;
	
	for(i=0;i<num;i++)
	{
		rt=T;
		for(;;)
		{
			len++;
			if (rt->data==A[i]) break;
			if(rt->data<A[i])
			rt=rt->rchild;
			else
			rt=rt->lchild;
		}
	}
	return (double)len/num;
}
int main()
{
	int i;
	int j;//插入数 
	int num;
	int A[]={3,2,1,4,5,6,7,10,9,8};
	BSTree T=NULL;
	bool taller;
	num=sizeof(A)/sizeof(int);
	for(i=0;i<sizeof(A)/sizeof(int);i++)
	InsertAVL(&T,A[i],&taller);
	Inorder(T);
	printf("\n");
	printf("插入结点值:");
	scanf("%d",&j);
	InsertAVL(&T,j,&taller);
	Inorder(T);
	printf("\n");
	printf("平均查找长度为:%3.1f",CalAveLength(T,A,num));
	return 0;

}

#include<stdio.h>
#include<stdlib.h>
#define N 100
typedef struct
{
	int *data;
	int dnum;
}BST;
float length;
void InsertBST(BST T,int i,int key)
{
	if(i<1||i>N) 
	printf("ERROR!\n");
	if(T.data[i]==0) 
	T.data[i]=key;
	else if(key<T.data[i]) 
	InsertBST(T,2*i,key);
	else InsertBST(T,2*i+1,key);
}

BST CreatBST(int *A,int num)
{
	BST T;
	int i,j;
	T.data=(int *)malloc(N*sizeof(int));
	for(j=0;j<N;j++)
	T.data[j]=0;
	T.dnum=0;
	for(i=0;i<num;i++)
	{
		InsertBST(T,1,A[i]);
		++T.dnum;
	}
	return T;
}

void Inorder(BST T,int i)
{
	if(T.data[i])
	{
		Inorder(T,2*i);
		printf("%d ",T.data[i]);
		Inorder(T,2*i+1);
	}
}

int search(BST T,int key,int i)
{
	length++;
	if(!T.data[i]) return 0;
	else if(key==T.data[i]) return i;
	else if(key<T.data[i]) search(T,key,2*i);
	else search(T,key,2*i+1);
}
BST DeleteBST(BST T,int key)
{
	BST q;
	int i;
	q.data=(int *)malloc(N*sizeof(int));
	for(i=0;i<N;i++) 
	q.data[i]=0;
	q.dnum=0;
	for(i=1;i<N&&T.dnum>0;i++)
	{
		if(T.data[i]==0||T.data[i]==key) continue;   
		InsertBST(q,1,T.data[i]);   
		--T.dnum;   
		++q.dnum;
	}
	delete T.data;
	return q;
}
int main()
{
	BST T;
	int A[N];
	char ch;
	int i=0;
	int num,j;
	printf("输入L:");
	do
	{
		scanf("%d",&num);
		A[i++]=num;
	    scanf("%c",&ch);
	    if(ch=='\n') break;
	}while(ch!='\n');
	
	T=CreatBST(A,i);
	printf("中序遍历结果:");
	Inorder(T,1);
	printf("\n");
	length=0;
	
	for(int s=0;s<T.dnum;s++)
	search(T,A[s],1);
	
	printf("平均查找长度:");
	
	float f;
	f=length/T.dnum;
	printf("%3.1f\n",f);
	printf("输入查找元素,若该节点存在,则删除该结点:");
	scanf("%d",&num);
	j=search(T,num,1);
	if(j)
	{
		T=DeleteBST(T,num);
		printf("删除成功,中序遍历结果:");
		Inorder(T,1);
		i--;
	} 
	else printf("没有找到该结点%d",num);
}


总结

构造二叉排序树。我们对于给定序列,取其第一个点为根结点,然后依次选择后续节点边比较边插入。如果比当前结点小,往该节点左子树移动比较,如果比当前结点大,则往该节点右子树移动比较。直到到一个待比较位置为空的位置,就是该节点的最终位置。
查找操作通过递归算法实现。思路很简单,仅需要从根节点开始比较就可以,比当前结点大就找左子树,小就找右子树直到找到为止。
删除操作相对于前面的查找与插入就复杂一些了。删除某元素需要维护二叉排序树的形状。文章来源地址https://www.toymoban.com/news/detail-520814.html

到了这里,关于数据结构课设(五)二叉排序树与平衡二叉树的实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构07:查找[C++][平衡二叉排序树AVL]

    图源:文心一言 考研笔记整理1w+字,小白友好、代码可跑,请小伙伴放心食用~~🥝🥝 第1版:查资料、写BUG、画导图、画配图~🧩🧩 参考用书: 王道考研《2024年 数据结构考研复习指导》 参考用书配套视频: 7.3_2 平衡二叉树_哔哩哔哩_bilibili 特别感谢:  Chat GPT老师、文心

    2024年02月11日
    浏览(37)
  • 学习高级数据结构:探索平衡树与图的高级算法

    🎉欢迎来到数据结构学习专栏~学习高级数据结构:探索平衡树与图的高级算法 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:数据结构学习 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技

    2024年02月09日
    浏览(33)
  • [数据结构] 树与二叉树

    树是由 (n(n geq 0)) 个节点组成的有限集。当 (n = 0) 时,称为空树。 任意一棵非空树应满足以下两点: (1)有且仅有一个特定的称为根的节点; (2)当 (n 1) 时,其余节点可分为 (m(m0)) 个互不相交的有限集 (T_1, T_2, dots, T_m) ,其中每个集合本身又是一棵树,称为根的

    2024年03月09日
    浏览(33)
  • 数据结构--树与二叉树

    树的定义 树是n(n =0)个节点的有限集。当n=0 时,称为空树 在任意一棵非空树中应满足 有且仅有一个特定的称为根的结点 当n1 时,其余节点可分为m(m0) 个互不相交的有限集T1,T2……Tm,其中每个集合本身又是一棵树,并且称为根的子树 树是一种逻辑结构,也是一种分层结构 树的

    2024年02月22日
    浏览(34)
  • 【数据结构】树与二叉树

    树是一种 非线性的数据结构 ,它是由n(n=0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 。它具有以下的特点: 有一个特殊的结点,称为根结点,根结点没有前驱结点 除根结点外,其余结点被分

    2024年02月11日
    浏览(36)
  • 【数据结构】树与二叉树(中)

    目录 前言: 一、顺序存储结构: 二、堆: 1.堆的性质: 2.堆的性质: 3.堆的实现: Ⅰ.堆的初始化:  Ⅱ.堆的插入(含向上调整):  Ⅲ.堆的删除(含向下调整算法): Ⅳ.取堆顶的数据: Ⅴ.堆中的数据个数: Ⅵ.堆的判空:  Ⅶ.堆的销毁: 总结:         上篇文章中,

    2024年02月16日
    浏览(36)
  • 数据结构_树与二叉树

    目录 1. 树的基本概念 1.1 树的定义 1.2 基本术语 1.3 树的性质 1.4 相关练习 2. 二叉树的概念 2.1 二叉树的概念及其主要特性 2.2 二叉树的存储结构 2.2.1 顺序存储结构 2.2.2 链式存储结构 2.3 相关练习 3. 二叉树的遍历和线索二叉树 3.1 二叉树的遍历 3.1.1 先序遍历 3.1.2 中序遍历 3.1

    2024年02月04日
    浏览(36)
  • 数据结构与算法——树与二叉树

    😊各位小伙伴久等了,本专栏新文章出炉了!!! 我又回来啦,接下来的时间里,我会持续把数据结构与算法专栏更新完。 👉树型结构👈 是一类重要的 ✍非线性数据结构 ,其中以树和二叉树最为常用,直观来看,树是以分支关系定义的层次结构。树型结构在客观世界中

    2024年02月11日
    浏览(32)
  • 【数据结构与算法】树与二叉树

    除了之前我们讲的栈、队列、链表等线性结构,数据结构中还有着一对多的 非线性结构 ——— 树 。 树是有 n 个结点组成的有限集,当n=0时为空树,在任意一颗非空树中,有且仅有一个 特定的根结点 ;当n1时,其余结点又可以分为一棵树,称为根的 子树 。 如下图所示: A为

    2023年04月09日
    浏览(38)
  • 数据结构:图文详解 树与二叉树(树与二叉树的概念和性质,存储,遍历)

    目录 一.树的概念 二.树中重要的概念 三.二叉树的概念 满二叉树 完全二叉树 四.二叉树的性质 五.二叉树的存储 六.二叉树的遍历 前序遍历 中序遍历  后序遍历  树是一种 非线性数据结构 ,它由节点和边组成。树的每个节点可以有零个或多个子节点,其中一个节点被指定为

    2024年02月04日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包