广工数据结构实验报告平衡二叉树

数据结构实验报告

题目:平衡二叉树

学 院 专 业 年级班别

学 号

学生姓名 指导教师

2015年7月1日

1.题目:采用字符类型为整型类型和链式存储结构,实现抽象数据类型BTree。 ADT BTree{

数据对象:D={ai | ai∈ElemSet, i=1,2,...,n, n≥0 }

数据关系:R1={ |ai-1, ai∈D, i=2,...,n }

基本操作:

Adj_balance(T)

操作结果:创建平衡二叉树。

InsertAVL(T,search,taller)

初始条件:二叉树T已存在。

操作结果:增加新结点。

SetAVL(T,search,taller)

初始条件:二叉树T已存在。

操作结果:在平衡二叉树上增加新结点并调平衡。

DeleteAVL(T,search,shorter)

初始条件:二叉树T已存在。

操作结果:删除结点。

} ADT BTree

2.存储结构定义

公用头文件DS0.h:

#include

#include

树的内部变量

typedef struct BTNode

{

int data;

int bf; //平衡因子

struct BTNode *lchild,*rchild;//左、右孩子

}BTNode,*BTree;

/*需要的函数声明*/

void Right_Balance(BTree &p);

void Left_Balance(BTree &p);

void Left_Root_Balance(BTree &T);

void Right_Root_Balance(BTree &T);

bool InsertAVL(BTree &T,int i,bool &taller);

void PrintBT(BTree T);

void Left_Root_Balance_det(BTree &p,int &shorter);

void Right_Root_Balance_det(BTree &p,int &shorter);

void Delete(BTree q,BTree &r,int &shorter);

int DeleteAVL(BTree &p,int x,int &shorter);

void Adj_balance(BTree &T);

bool SetAVL(BTree &T,int i,bool &taller);

bool Insert_Balance_AVL(BTree &T,int i,bool &taller);

int menu( );

3. 算法设计

/*对以*p为根的二叉排序树作右旋处理*/

void Right_Balance(BTree &p)

{

BTree lc;

lc =p->lchild; //lc指向的*p左子树根结点

p->lchild = lc->rchild; //rc的右子树挂接为*p的左子树

lc->rchild = p;

p = lc; //p指向新的结点

}

/*对以*p为根的二叉排序树作左旋处理*/

void Left_Balance(BTree &p)

{

BTree rc;

rc = p->rchild; //指向的*p右子树根结点

p->rchild = rc->lchild; //rc左子树挂接到*p的右子树

rc->lchild = p;

p = rc; //p指向新的结点

}

/*对以指针T所指结点为根的二叉树作左平衡旋转处理*/

void Left_Root_Balance(BTree &T)

{

BTree lc,rd;

lc = T->lchild; //指向*T的左子树根结点

switch(lc->bf) //检查*T的左子树的平衡度,并作相应平衡处理 {

case 1: //新结点插入在*T的左孩子的左子树上,要作单右旋处理

T->bf = lc->bf = 0;

Right_Balance(T);

break;

case -1: //新结点插入在*T的左孩子的右子树上,要作双旋处理

rd = lc->rchild; //rd指向*T的左孩子的右子树根

switch(rd->bf) //修改*T及其左孩子的平衡因子

{

case 1:

T->bf = -1;

lc->bf = 0;

break;

case 0:

T->bf = lc->bf = 0;

break;

case -1:

T->bf = 0;

lc->bf = 1;

break;

}

rd->bf = 0;

Left_Balance(T->lchild); //对*T的左子树作左旋平衡处理

Right_Balance(T); //对*T作右旋平衡处理

}

}

/*对以指针T所指结点为根的二叉树作右平衡旋转处理*/

void Right_Root_Balance(BTree &T)

{

BTree rc,ld;

rc = T->rchild; //指向*T的左子树根结点

switch(rc->bf) //检查*T的右子树的平衡度,并作相应平衡处理 {

case -1: //新结点插入在*T的右孩子的右子树上,要作单左旋处理

T->bf = rc->bf =0;

Left_Balance(T); break;

case 1: //新结点插入在*T的右孩子的左子树上,要作双旋处理

ld = rc->lchild; //ld指向*T的右孩子的左子树根

switch(ld->bf) //修改*T及其右孩子的平衡因子

{

case 1:

T->bf = 0;

rc->bf = -1;

break;

case 0:

T->bf = rc->bf =0;

break;

case -1:

T->bf = 1;

rc->bf = 0;

break;

}

ld->bf = 0;

Right_Balance(T->rchild);//对*T的右子树作左旋平衡处理

Left_Balance(T); //对*T作左旋平衡处理

}

}

/*插入结点i,若T中存在和i相同关键字的结点,则插入一个数据元素为i的新结点,并返回1,否则返回0*/

bool InsertAVL(BTree &T,int i,bool &taller)

{

if(!T)//插入新结点,树“长高”,置taller为true

{

T = (BTree)malloc(sizeof(BTNode));

T->data = i;

T->lchild = T->rchild =NULL;

T->bf = 0;

taller = true;

}

else

{

if(i==T->data) //树中已存在和有相同关键字的结点 {

taller = 0;

printf("已存在相同关键字的结点\n");

return 0;

}

if(idata) //应继续在*T的左子树中进行搜索 {

if(!InsertAVL(T->lchild,i,taller))

return 0;

}

else //应继续在*T的右子树中进行搜索

{

if(!InsertAVL(T->rchild,i,taller))

return 0;

}

}

return 1;

}

/*输出二叉树*/

void PrintBT(BTree T)

{

if(T)

{

printf("%d",T->data);

if(T->lchild||T->rchild)

{

printf("(");

PrintBT(T->lchild);

printf(",");

PrintBT(T->rchild);

printf(")");

}

}

}

/*删除结点时左平衡旋转处理*/

void Left_Root_Balance_det(BTree &p,int &shorter)

{

BTree p1,p2;

if(p->bf==1) //p结点的左子树高,删除结点后p的bf减,树变矮

{

p->bf=0;

shorter=1;

}

else if(p->bf==0)//p结点左、右子树等高,删除结点后p的bf减,树高不变 {

p->bf=-1;

shorter=0;

}

else //p结点的右子树高

{

p1=p->rchild;//p1指向p的右子树

if(p1->bf==0)//p1结点左、右子树等高,删除结点后p的bf为-2,进行左旋处理,树高不变

{

Left_Balance(p);

p1->bf=1;

p->bf=-1;

shorter=0;

}

else if(p1->bf==-1)//p1的右子树高,左旋处理后,树变矮

{

Left_Balance(p);

p1->bf=p->bf=0;

shorter=1;

}

else //p1的左子树高,进行双旋处理(先右旋后左旋),树变矮 {

p2=p1->lchild;

p1->lchild=p2->rchild;

p2->rchild=p1;

p->rchild=p2->lchild;

p2->lchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

else if(p2->bf==-1)

{

p->bf=1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=-1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

/*删除结点时右平衡旋转处理*/

void Right_Root_Balance_det(BTree &p,int &shorter)

{

BTree p1,p2;

if(p->bf==-1)

{

p->bf=0;

shorter=1;

}

else if(p->bf==0)

{

p->bf=1;

shorter=0;

}

else

{

p1=p->lchild;

if(p1->bf==0)

{

Right_Balance(p);

p1->bf=-1;

p->bf=1;

shorter=0;

}

else if(p1->bf==1)

Right_Balance(p);

p1->bf=p->bf=0;

shorter=1;

}

else

{

p2=p1->rchild;

p1->rchild=p2->lchild;

p2->lchild=p1;

p->lchild=p2->rchild;

p2->rchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

else if(p2->bf==1)

{

p->bf=-1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

/*删除结点*/

void Delete(BTree q,BTree &r,int &shorter)

{

if(r->rchild==NULL)

{

q->data=r->data;

q=r;

r=r->lchild;

free(q);

shorter=1;

}

{

Delete(q,r->rchild,shorter);

if(shorter==1)

Right_Root_Balance_det(r,shorter);

}

}

/*二叉树的删除操作*/

int DeleteAVL(BTree &p,int x,int &shorter)

{

int k;

BTree q;

if(p==NULL)

{

printf("不存在要删除的关键字!!\n");

return 0;

}

else if(x

data)//在p的左子树中进行删除

{

k=DeleteAVL(p->lchild,x,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

return k;

}

else if(x>p->data)//在p的右子树中进行删除

{

k=DeleteAVL(p->rchild,x,shorter);

if(shorter==1)

Right_Root_Balance_det(p,shorter);

return k;

}

else

{

q=p;

if(p->rchild==NULL) //右子树空则只需重接它的左子树

{

p=p->lchild;

free(q);

shorter=1;

}

else if(p->lchild==NULL)//左子树空则只需重接它的右子树

{

p=p->rchild;

free(q);

shorter=1;

}

else//左右子树均不空

{

Delete(q,q->lchild,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

p=q;

}

return 1;

}

}

/*调平二叉树具体方法*/

bool SetAVL(BTree &T,int i,bool &taller)

{

if(!T)//插入新结点,树“长高”,置taller为true

{

T = (BTree)malloc(sizeof(BTNode));

T->data = i;

T->lchild = T->rchild =NULL;

T->bf = 0;

taller = true;

}

else

{

if(i==T->data) //树中已存在和有相同关键字的结点 {

taller = false;

printf("已存在相同关键字的结点\n");

return 0;

}

if(idata) //应继续在*T的左子树中进行搜索 {

if(!SetAVL(T->lchild,i,taller))

return 0;

if(taller) //已插入到*T的左子树中且左子树“长高”

switch(T->bf) //检查*T的平衡度

{

case 1: //原本左子树比右子树高,需要作左平衡处理

Left_Root_Balance(T);

taller = false;

break;

case 0: //原本左子树、右子等高,现因左子树增高而使树增高

T->bf = 1;

taller = true;

break;

case -1: //原本右子树比左子树高,现左、右子树等高

T->bf = 0;

taller = false;

break;

}

}

else //应继续在*T的右子树中进行搜索

{

if(!SetAVL(T->rchild,i,taller))

return 0;

if(taller) //已插入到*T的右子树中且右子树“长高”

switch(T->bf) //检查*T的平衡度

{

case 1: //原本左子树比右子树高,现左、右子树等高

T->bf = 0;

taller = false;

break;

case 0: //原本左子树、右子等高,现因右子树增高而使树增高

T->bf = -1;

taller = true;

break;

case -1: //原本右子树比左子树高,需要作右平衡处理

Right_Root_Balance(T);

taller = false;

break;

}

}

return 1;

}

}

/*二叉树调平操作*/

void Adj_balance(BTree &T)

{

int i;

bool taller=false;

T = NULL;

printf("\n请输入关键字(以-1结束建立平衡二叉树):");

scanf("%d",&i);

getchar();

while(i != -1)

{

SetAVL(T,i,taller);

printf("\n请输入关键字(以-1结束建立平衡二叉树):");

scanf("%d",&i);

getchar();

taller=false;

}

printf("平衡二叉树创建结束.\n");

if(T)

PrintBT(T);

else

printf("这是一棵空树.\n");

}

/*菜单函数*/

int menu( )

{

int m;

printf("..........................2015年7月1日......................\n\n");

printf(" 平衡二叉树\n");

printf(" ________________________________\n\n"); printf(" 1 创建平衡二叉树\n");

printf(" 2 在平衡二叉树上增加新结点并调衡\n"); printf(" 3 在平衡二叉树上删除一个结点并调衡\n"); printf(" 0 退出\n");

printf(" ________________________________\n\n"); printf(" 请输入所选功能0-3\n");

scanf("%d",&m);

return m;

}

4.测试

/*主函数*/

void main()

{

int input,search;

bool taller=0;

int shorter=0;

BTree T;

T=(BTree)malloc(sizeof(BTNode));

T=NULL;

while(1)

{

printf("\n请选择需要的二叉树操作\n");

input=menu( );

switch(input)

{

case 1:

Adj_balance(T);

break;

case 2:

printf("请输入你要增加的关键字");

scanf("%d",&search);

getchar();

SetAVL(T,search,taller);

PrintBT(T);

break;

case 3:

printf("请输入你要删除的关键字");

scanf("%d",&search);

getchar();

DeleteAVL(T,search,shorter);

PrintBT(T);

break;

case 0:

break;

default:

printf("输入错误,请重新选择。");

break;

}

if(input == 0)

break;

printf("按任意键继续.");

getchar();

}

}

测试截图:

1.界面:

2.创建平衡二叉树:

3.增加节点并调衡:

4.删除节点并调衡:

5. 思考与小结

在平衡二叉树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是,则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

#include

#include

typedef struct BTNode

{

int data;

int bf; //平衡因子

struct BTNode *lchild,*rchild;//左、右孩子

}BTNode,*BTree;

/*对以*p为根的二叉排序树作右旋处理*/

void Right_Balance(BTree &p)

{

BTree lc;

lc =p->lchild; //lc指向的*p左子树根结点

p->lchild = lc->rchild; //rc的右子树挂接为*p的左子树

lc->rchild = p;

p = lc; //p指向新的结点

}

/*对以*p为根的二叉排序树作左旋处理*/

void Left_Balance(BTree &p)

{

BTree rc;

rc = p->rchild; //指向的*p右子树根结点

p->rchild = rc->lchild; //rc左子树挂接到*p的右子树

rc->lchild = p;

p = rc; //p指向新的结点

}

/*对以指针T所指结点为根的二叉树作左平衡旋转处理*/

void Left_Root_Balance(BTree &T)

{

BTree lc,rd;

lc = T->lchild; //指向*T的左子树根结点

switch(lc->bf) //检查*T的左子树的平衡度,并作相应平衡处理 {

case 1: //新结点插入在*T的左孩子的左子树上,要作单右旋处理

T->bf = lc->bf = 0;

Right_Balance(T);

break;

case -1: //新结点插入在*T的左孩子的右子树上,要作双旋处理

rd = lc->rchild; //rd指向*T的左孩子的右子树根

switch(rd->bf) //修改*T及其左孩子的平衡因子

case 1:

T->bf = -1;

lc->bf = 0;

break;

case 0:

T->bf = lc->bf = 0;

break;

case -1:

T->bf = 0;

lc->bf = 1;

break;

}

rd->bf = 0;

Left_Balance(T->lchild); //对*T的左子树作左旋平衡处理

Right_Balance(T); //对*T作右旋平衡处理

}

}

/*对以指针T所指结点为根的二叉树作右平衡旋转处理*/

void Right_Root_Balance(BTree &T)

{

BTree rc,ld;

rc = T->rchild; //指向*T的左子树根结点

switch(rc->bf) //检查*T的右子树的平衡度,并作相应平衡处理 {

case -1: //新结点插入在*T的右孩子的右子树上,要作单左旋处理

T->bf = rc->bf =0;

Left_Balance(T); break;

case 1: //新结点插入在*T的右孩子的左子树上,要作双旋处理

ld = rc->lchild; //ld指向*T的右孩子的左子树根

switch(ld->bf) //修改*T及其右孩子的平衡因子

{

case 1:

T->bf = 0;

rc->bf = -1;

break;

case 0:

T->bf = rc->bf =0;

break;

case -1:

T->bf = 1;

rc->bf = 0;

break;

}

ld->bf = 0;

Right_Balance(T->rchild);//对*T的右子树作左旋平衡处理

Left_Balance(T); //对*T作左旋平衡处理

}

}

/*插入结点i,若T中存在和i相同关键字的结点,则插入一个数据元素为i的新结点,并返回1,否则返回0*/

bool InsertAVL(BTree &T,int i,bool &taller)

{

if(!T)//插入新结点,树“长高”,置taller为true

{

T = (BTree)malloc(sizeof(BTNode));

T->data = i;

T->lchild = T->rchild =NULL;

T->bf = 0;

taller = 1;

}

else

{

if(i==T->data) //树中已存在和有相同关键字的结点 {

taller = 0;

printf("已存在相同关键字的结点\n");

return 0;

}

if(idata) //应继续在*T的左子树中进行搜索 {

if(!InsertAVL(T->lchild,i,taller))

return 0;

}

else //应继续在*T的右子树中进行搜索

{

if(!InsertAVL(T->rchild,i,taller))

return 0;

}

}

return 1;

}

/*输出平衡二叉树*/

void PrintBT(BTree T)

{

{

printf("%d",T->data);

if(T->lchild||T->rchild)

{

printf("(");

PrintBT(T->lchild);

printf(",");

PrintBT(T->rchild);

printf(")");

}

}

}

/*删除结点时左平衡旋转处理*/

void Left_Root_Balance_det(BTree &p,int &shorter)

{

BTree p1,p2;

if(p->bf==1) //p结点的左子树高,删除结点后p的bf减,树变矮

{

p->bf=0;

shorter=1;

}

else if(p->bf==0)//p结点左、右子树等高,删除结点后p的bf减,树高不变 {

p->bf=-1;

shorter=0;

}

else //p结点的右子树高

{

p1=p->rchild;//p1指向p的右子树

if(p1->bf==0)//p1结点左、右子树等高,删除结点后p的bf为-2,进行左旋处理,树高不变

{

Left_Balance(p);

p1->bf=1;

p->bf=-1;

shorter=0;

}

else if(p1->bf==-1)//p1的右子树高,左旋处理后,树变矮

{

Left_Balance(p);

p1->bf=p->bf=0;

shorter=1;

else //p1的左子树高,进行双旋处理(先右旋后左旋),树变矮 {

p2=p1->lchild;

p1->lchild=p2->rchild;

p2->rchild=p1;

p->rchild=p2->lchild;

p2->lchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

else if(p2->bf==-1)

{

p->bf=1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=-1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

/*删除结点时右平衡旋转处理*/

void Right_Root_Balance_det(BTree &p,int &shorter)

{

BTree p1,p2;

if(p->bf==-1)

{

p->bf=0;

shorter=1;

}

else if(p->bf==0)

{

p->bf=1;

shorter=0;

}

else

{

p1=p->lchild;

if(p1->bf==0)

{

Right_Balance(p);

p1->bf=-1;

p->bf=1;

shorter=0;

}

else if(p1->bf==1)

{

Right_Balance(p);

p1->bf=p->bf=0;

shorter=1;

}

else

{

p2=p1->rchild;

p1->rchild=p2->lchild;

p2->lchild=p1;

p->lchild=p2->rchild;

p2->rchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

else if(p2->bf==1)

{

p->bf=-1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

/*删除结点*/

void Delete(BTree q,BTree &r,int &shorter)

{

if(r->rchild==NULL)

{

q->data=r->data;

q=r;

r=r->lchild;

free(q);

shorter=1;

}

else

{

Delete(q,r->rchild,shorter);

if(shorter==1)

Right_Root_Balance_det(r,shorter);

}

}

/*二叉树的删除操作*/

int DeleteAVL(BTree &p,int x,int &shorter)

{

int k;

BTree q;

if(p==NULL)

{

printf("不存在要删除的关键字!!\n");

return 0;

}

else if(x

data)//在p的左子树中进行删除

{

k=DeleteAVL(p->lchild,x,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

return k;

}

else if(x>p->data)//在p的右子树中进行删除

{

k=DeleteAVL(p->rchild,x,shorter);

if(shorter==1)

Right_Root_Balance_det(p,shorter);

return k;

}

else

{

q=p;

if(p->rchild==NULL) //右子树空则只需重接它的左子树

{

p=p->lchild;

free(q);

shorter=1;

}

else if(p->lchild==NULL)//左子树空则只需重接它的右子树

{

p=p->rchild;

free(q);

shorter=1;

}

else//左右子树均不空

{

Delete(q,q->lchild,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

p=q;

}

return 1;

}

}

/*调平二叉树具体方法*/

bool SetAVL(BTree &T,int i,bool &taller)

{

if(!T)//插入新结点,树“长高”,置taller为true

{

T = (BTree)malloc(sizeof(BTNode));

T->data = i;

T->lchild = T->rchild =NULL;

T->bf = 0;

taller = 1;

}

else

{

if(i==T->data) //树中已存在和有相同关键字的结点 {

taller = false;

printf("已存在相同关键字的结点\n");

return 0;

}

if(idata) //应继续在*T的左子树中进行搜索 {

if(!SetAVL(T->lchild,i,taller))

return 0;

if(taller) //已插入到*T的左子树中且左子树“长高”

switch(T->bf) //检查*T的平衡度

{

case 1: //原本左子树比右子树高,需要作左平衡处理

Left_Root_Balance(T);

taller = false;

break;

case 0: //原本左子树、右子等高,现因左子树增高而使树增高

T->bf = 1;

taller = 1;

break;

case -1: //原本右子树比左子树高,现左、右子树等高

T->bf = 0;

taller = false;

break;

}

}

else //应继续在*T的右子树中进行搜索

{

if(!SetAVL(T->rchild,i,taller))

return 0;

if(taller) //已插入到*T的右子树中且右子树“长高”

switch(T->bf) //检查*T的平衡度

{

case 1: //原本左子树比右子树高,现左、右子树等高

T->bf = 0;

taller = false;

break;

case 0: //原本左子树、右子等高,现因右子树增高而使树增高

T->bf = -1;

taller = 1;

break;

case -1: //原本右子树比左子树高,需要作右平衡处理

Right_Root_Balance(T);

taller = 0;

break;

}

}

return 1;

}

}

/*二叉树调平操作*/

void Adj_balance(BTree &T)

{

int i;

bool taller=0;

T = NULL;

printf("\n请输入关键字(以-1结束建立平衡二叉树):");

scanf("%d",&i);

getchar();

while(i != -1)

{

SetAVL(T,i,taller);

printf("\n请输入关键字(以-1结束建立平衡二叉树):");

scanf("%d",&i);

getchar();

taller=0;

}

printf("平衡二叉树创建结束.\n");

if(T)

PrintBT(T);

else

printf("这是一棵空树.\n");

}

/*菜单函数*/

int menu( )

{

int m;

printf("..........................2015年7月1日......................\n\n");

printf(" 平衡二叉树\n");

printf(" ________________________________\n\n"); printf(" 1 创建平衡二叉树\n");

printf(" 2 在平衡二叉树上增加新结点并调平衡\n"); printf(" 3 删除一个结点\n");

printf(" 0 退出\n");

printf(" ________________________________\n\n"); printf(" 请输入所选功能0-3\n");

scanf("%d",&m);

return m;

}

/*主函数*/

void main()

{

int input,search;

bool taller=0;

int shorter=0;

BTree T;

T=(BTree)malloc(sizeof(BTNode));

T=NULL;

while(1)

{

printf("\n请选择需要的二叉树操作\n"); input=menu( );

switch(input)

{

case 1:

Adj_balance(T);

break;

case 2:

printf("请输入你要增加的关键字"); scanf("%d",&search);

getchar();

SetAVL(T,search,taller); PrintBT(T);

break;

case 3:

printf("请输入你要删除的关键字"); scanf("%d",&search);

getchar();

DeleteAVL(T,search,shorter); PrintBT(T);

break;

case 0:

break;

default:

printf("输入错误,请重新选择。"); break;

}

if(input == 0)

break;

printf("按任意键继续."); getchar();

}

}

数据结构实验报告

题目:平衡二叉树

学 院 专 业 年级班别

学 号

学生姓名 指导教师

2015年7月1日

1.题目:采用字符类型为整型类型和链式存储结构,实现抽象数据类型BTree。 ADT BTree{

数据对象:D={ai | ai∈ElemSet, i=1,2,...,n, n≥0 }

数据关系:R1={ |ai-1, ai∈D, i=2,...,n }

基本操作:

Adj_balance(T)

操作结果:创建平衡二叉树。

InsertAVL(T,search,taller)

初始条件:二叉树T已存在。

操作结果:增加新结点。

SetAVL(T,search,taller)

初始条件:二叉树T已存在。

操作结果:在平衡二叉树上增加新结点并调平衡。

DeleteAVL(T,search,shorter)

初始条件:二叉树T已存在。

操作结果:删除结点。

} ADT BTree

2.存储结构定义

公用头文件DS0.h:

#include

#include

树的内部变量

typedef struct BTNode

{

int data;

int bf; //平衡因子

struct BTNode *lchild,*rchild;//左、右孩子

}BTNode,*BTree;

/*需要的函数声明*/

void Right_Balance(BTree &p);

void Left_Balance(BTree &p);

void Left_Root_Balance(BTree &T);

void Right_Root_Balance(BTree &T);

bool InsertAVL(BTree &T,int i,bool &taller);

void PrintBT(BTree T);

void Left_Root_Balance_det(BTree &p,int &shorter);

void Right_Root_Balance_det(BTree &p,int &shorter);

void Delete(BTree q,BTree &r,int &shorter);

int DeleteAVL(BTree &p,int x,int &shorter);

void Adj_balance(BTree &T);

bool SetAVL(BTree &T,int i,bool &taller);

bool Insert_Balance_AVL(BTree &T,int i,bool &taller);

int menu( );

3. 算法设计

/*对以*p为根的二叉排序树作右旋处理*/

void Right_Balance(BTree &p)

{

BTree lc;

lc =p->lchild; //lc指向的*p左子树根结点

p->lchild = lc->rchild; //rc的右子树挂接为*p的左子树

lc->rchild = p;

p = lc; //p指向新的结点

}

/*对以*p为根的二叉排序树作左旋处理*/

void Left_Balance(BTree &p)

{

BTree rc;

rc = p->rchild; //指向的*p右子树根结点

p->rchild = rc->lchild; //rc左子树挂接到*p的右子树

rc->lchild = p;

p = rc; //p指向新的结点

}

/*对以指针T所指结点为根的二叉树作左平衡旋转处理*/

void Left_Root_Balance(BTree &T)

{

BTree lc,rd;

lc = T->lchild; //指向*T的左子树根结点

switch(lc->bf) //检查*T的左子树的平衡度,并作相应平衡处理 {

case 1: //新结点插入在*T的左孩子的左子树上,要作单右旋处理

T->bf = lc->bf = 0;

Right_Balance(T);

break;

case -1: //新结点插入在*T的左孩子的右子树上,要作双旋处理

rd = lc->rchild; //rd指向*T的左孩子的右子树根

switch(rd->bf) //修改*T及其左孩子的平衡因子

{

case 1:

T->bf = -1;

lc->bf = 0;

break;

case 0:

T->bf = lc->bf = 0;

break;

case -1:

T->bf = 0;

lc->bf = 1;

break;

}

rd->bf = 0;

Left_Balance(T->lchild); //对*T的左子树作左旋平衡处理

Right_Balance(T); //对*T作右旋平衡处理

}

}

/*对以指针T所指结点为根的二叉树作右平衡旋转处理*/

void Right_Root_Balance(BTree &T)

{

BTree rc,ld;

rc = T->rchild; //指向*T的左子树根结点

switch(rc->bf) //检查*T的右子树的平衡度,并作相应平衡处理 {

case -1: //新结点插入在*T的右孩子的右子树上,要作单左旋处理

T->bf = rc->bf =0;

Left_Balance(T); break;

case 1: //新结点插入在*T的右孩子的左子树上,要作双旋处理

ld = rc->lchild; //ld指向*T的右孩子的左子树根

switch(ld->bf) //修改*T及其右孩子的平衡因子

{

case 1:

T->bf = 0;

rc->bf = -1;

break;

case 0:

T->bf = rc->bf =0;

break;

case -1:

T->bf = 1;

rc->bf = 0;

break;

}

ld->bf = 0;

Right_Balance(T->rchild);//对*T的右子树作左旋平衡处理

Left_Balance(T); //对*T作左旋平衡处理

}

}

/*插入结点i,若T中存在和i相同关键字的结点,则插入一个数据元素为i的新结点,并返回1,否则返回0*/

bool InsertAVL(BTree &T,int i,bool &taller)

{

if(!T)//插入新结点,树“长高”,置taller为true

{

T = (BTree)malloc(sizeof(BTNode));

T->data = i;

T->lchild = T->rchild =NULL;

T->bf = 0;

taller = true;

}

else

{

if(i==T->data) //树中已存在和有相同关键字的结点 {

taller = 0;

printf("已存在相同关键字的结点\n");

return 0;

}

if(idata) //应继续在*T的左子树中进行搜索 {

if(!InsertAVL(T->lchild,i,taller))

return 0;

}

else //应继续在*T的右子树中进行搜索

{

if(!InsertAVL(T->rchild,i,taller))

return 0;

}

}

return 1;

}

/*输出二叉树*/

void PrintBT(BTree T)

{

if(T)

{

printf("%d",T->data);

if(T->lchild||T->rchild)

{

printf("(");

PrintBT(T->lchild);

printf(",");

PrintBT(T->rchild);

printf(")");

}

}

}

/*删除结点时左平衡旋转处理*/

void Left_Root_Balance_det(BTree &p,int &shorter)

{

BTree p1,p2;

if(p->bf==1) //p结点的左子树高,删除结点后p的bf减,树变矮

{

p->bf=0;

shorter=1;

}

else if(p->bf==0)//p结点左、右子树等高,删除结点后p的bf减,树高不变 {

p->bf=-1;

shorter=0;

}

else //p结点的右子树高

{

p1=p->rchild;//p1指向p的右子树

if(p1->bf==0)//p1结点左、右子树等高,删除结点后p的bf为-2,进行左旋处理,树高不变

{

Left_Balance(p);

p1->bf=1;

p->bf=-1;

shorter=0;

}

else if(p1->bf==-1)//p1的右子树高,左旋处理后,树变矮

{

Left_Balance(p);

p1->bf=p->bf=0;

shorter=1;

}

else //p1的左子树高,进行双旋处理(先右旋后左旋),树变矮 {

p2=p1->lchild;

p1->lchild=p2->rchild;

p2->rchild=p1;

p->rchild=p2->lchild;

p2->lchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

else if(p2->bf==-1)

{

p->bf=1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=-1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

/*删除结点时右平衡旋转处理*/

void Right_Root_Balance_det(BTree &p,int &shorter)

{

BTree p1,p2;

if(p->bf==-1)

{

p->bf=0;

shorter=1;

}

else if(p->bf==0)

{

p->bf=1;

shorter=0;

}

else

{

p1=p->lchild;

if(p1->bf==0)

{

Right_Balance(p);

p1->bf=-1;

p->bf=1;

shorter=0;

}

else if(p1->bf==1)

Right_Balance(p);

p1->bf=p->bf=0;

shorter=1;

}

else

{

p2=p1->rchild;

p1->rchild=p2->lchild;

p2->lchild=p1;

p->lchild=p2->rchild;

p2->rchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

else if(p2->bf==1)

{

p->bf=-1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

/*删除结点*/

void Delete(BTree q,BTree &r,int &shorter)

{

if(r->rchild==NULL)

{

q->data=r->data;

q=r;

r=r->lchild;

free(q);

shorter=1;

}

{

Delete(q,r->rchild,shorter);

if(shorter==1)

Right_Root_Balance_det(r,shorter);

}

}

/*二叉树的删除操作*/

int DeleteAVL(BTree &p,int x,int &shorter)

{

int k;

BTree q;

if(p==NULL)

{

printf("不存在要删除的关键字!!\n");

return 0;

}

else if(x

data)//在p的左子树中进行删除

{

k=DeleteAVL(p->lchild,x,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

return k;

}

else if(x>p->data)//在p的右子树中进行删除

{

k=DeleteAVL(p->rchild,x,shorter);

if(shorter==1)

Right_Root_Balance_det(p,shorter);

return k;

}

else

{

q=p;

if(p->rchild==NULL) //右子树空则只需重接它的左子树

{

p=p->lchild;

free(q);

shorter=1;

}

else if(p->lchild==NULL)//左子树空则只需重接它的右子树

{

p=p->rchild;

free(q);

shorter=1;

}

else//左右子树均不空

{

Delete(q,q->lchild,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

p=q;

}

return 1;

}

}

/*调平二叉树具体方法*/

bool SetAVL(BTree &T,int i,bool &taller)

{

if(!T)//插入新结点,树“长高”,置taller为true

{

T = (BTree)malloc(sizeof(BTNode));

T->data = i;

T->lchild = T->rchild =NULL;

T->bf = 0;

taller = true;

}

else

{

if(i==T->data) //树中已存在和有相同关键字的结点 {

taller = false;

printf("已存在相同关键字的结点\n");

return 0;

}

if(idata) //应继续在*T的左子树中进行搜索 {

if(!SetAVL(T->lchild,i,taller))

return 0;

if(taller) //已插入到*T的左子树中且左子树“长高”

switch(T->bf) //检查*T的平衡度

{

case 1: //原本左子树比右子树高,需要作左平衡处理

Left_Root_Balance(T);

taller = false;

break;

case 0: //原本左子树、右子等高,现因左子树增高而使树增高

T->bf = 1;

taller = true;

break;

case -1: //原本右子树比左子树高,现左、右子树等高

T->bf = 0;

taller = false;

break;

}

}

else //应继续在*T的右子树中进行搜索

{

if(!SetAVL(T->rchild,i,taller))

return 0;

if(taller) //已插入到*T的右子树中且右子树“长高”

switch(T->bf) //检查*T的平衡度

{

case 1: //原本左子树比右子树高,现左、右子树等高

T->bf = 0;

taller = false;

break;

case 0: //原本左子树、右子等高,现因右子树增高而使树增高

T->bf = -1;

taller = true;

break;

case -1: //原本右子树比左子树高,需要作右平衡处理

Right_Root_Balance(T);

taller = false;

break;

}

}

return 1;

}

}

/*二叉树调平操作*/

void Adj_balance(BTree &T)

{

int i;

bool taller=false;

T = NULL;

printf("\n请输入关键字(以-1结束建立平衡二叉树):");

scanf("%d",&i);

getchar();

while(i != -1)

{

SetAVL(T,i,taller);

printf("\n请输入关键字(以-1结束建立平衡二叉树):");

scanf("%d",&i);

getchar();

taller=false;

}

printf("平衡二叉树创建结束.\n");

if(T)

PrintBT(T);

else

printf("这是一棵空树.\n");

}

/*菜单函数*/

int menu( )

{

int m;

printf("..........................2015年7月1日......................\n\n");

printf(" 平衡二叉树\n");

printf(" ________________________________\n\n"); printf(" 1 创建平衡二叉树\n");

printf(" 2 在平衡二叉树上增加新结点并调衡\n"); printf(" 3 在平衡二叉树上删除一个结点并调衡\n"); printf(" 0 退出\n");

printf(" ________________________________\n\n"); printf(" 请输入所选功能0-3\n");

scanf("%d",&m);

return m;

}

4.测试

/*主函数*/

void main()

{

int input,search;

bool taller=0;

int shorter=0;

BTree T;

T=(BTree)malloc(sizeof(BTNode));

T=NULL;

while(1)

{

printf("\n请选择需要的二叉树操作\n");

input=menu( );

switch(input)

{

case 1:

Adj_balance(T);

break;

case 2:

printf("请输入你要增加的关键字");

scanf("%d",&search);

getchar();

SetAVL(T,search,taller);

PrintBT(T);

break;

case 3:

printf("请输入你要删除的关键字");

scanf("%d",&search);

getchar();

DeleteAVL(T,search,shorter);

PrintBT(T);

break;

case 0:

break;

default:

printf("输入错误,请重新选择。");

break;

}

if(input == 0)

break;

printf("按任意键继续.");

getchar();

}

}

测试截图:

1.界面:

2.创建平衡二叉树:

3.增加节点并调衡:

4.删除节点并调衡:

5. 思考与小结

在平衡二叉树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是,则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

#include

#include

typedef struct BTNode

{

int data;

int bf; //平衡因子

struct BTNode *lchild,*rchild;//左、右孩子

}BTNode,*BTree;

/*对以*p为根的二叉排序树作右旋处理*/

void Right_Balance(BTree &p)

{

BTree lc;

lc =p->lchild; //lc指向的*p左子树根结点

p->lchild = lc->rchild; //rc的右子树挂接为*p的左子树

lc->rchild = p;

p = lc; //p指向新的结点

}

/*对以*p为根的二叉排序树作左旋处理*/

void Left_Balance(BTree &p)

{

BTree rc;

rc = p->rchild; //指向的*p右子树根结点

p->rchild = rc->lchild; //rc左子树挂接到*p的右子树

rc->lchild = p;

p = rc; //p指向新的结点

}

/*对以指针T所指结点为根的二叉树作左平衡旋转处理*/

void Left_Root_Balance(BTree &T)

{

BTree lc,rd;

lc = T->lchild; //指向*T的左子树根结点

switch(lc->bf) //检查*T的左子树的平衡度,并作相应平衡处理 {

case 1: //新结点插入在*T的左孩子的左子树上,要作单右旋处理

T->bf = lc->bf = 0;

Right_Balance(T);

break;

case -1: //新结点插入在*T的左孩子的右子树上,要作双旋处理

rd = lc->rchild; //rd指向*T的左孩子的右子树根

switch(rd->bf) //修改*T及其左孩子的平衡因子

case 1:

T->bf = -1;

lc->bf = 0;

break;

case 0:

T->bf = lc->bf = 0;

break;

case -1:

T->bf = 0;

lc->bf = 1;

break;

}

rd->bf = 0;

Left_Balance(T->lchild); //对*T的左子树作左旋平衡处理

Right_Balance(T); //对*T作右旋平衡处理

}

}

/*对以指针T所指结点为根的二叉树作右平衡旋转处理*/

void Right_Root_Balance(BTree &T)

{

BTree rc,ld;

rc = T->rchild; //指向*T的左子树根结点

switch(rc->bf) //检查*T的右子树的平衡度,并作相应平衡处理 {

case -1: //新结点插入在*T的右孩子的右子树上,要作单左旋处理

T->bf = rc->bf =0;

Left_Balance(T); break;

case 1: //新结点插入在*T的右孩子的左子树上,要作双旋处理

ld = rc->lchild; //ld指向*T的右孩子的左子树根

switch(ld->bf) //修改*T及其右孩子的平衡因子

{

case 1:

T->bf = 0;

rc->bf = -1;

break;

case 0:

T->bf = rc->bf =0;

break;

case -1:

T->bf = 1;

rc->bf = 0;

break;

}

ld->bf = 0;

Right_Balance(T->rchild);//对*T的右子树作左旋平衡处理

Left_Balance(T); //对*T作左旋平衡处理

}

}

/*插入结点i,若T中存在和i相同关键字的结点,则插入一个数据元素为i的新结点,并返回1,否则返回0*/

bool InsertAVL(BTree &T,int i,bool &taller)

{

if(!T)//插入新结点,树“长高”,置taller为true

{

T = (BTree)malloc(sizeof(BTNode));

T->data = i;

T->lchild = T->rchild =NULL;

T->bf = 0;

taller = 1;

}

else

{

if(i==T->data) //树中已存在和有相同关键字的结点 {

taller = 0;

printf("已存在相同关键字的结点\n");

return 0;

}

if(idata) //应继续在*T的左子树中进行搜索 {

if(!InsertAVL(T->lchild,i,taller))

return 0;

}

else //应继续在*T的右子树中进行搜索

{

if(!InsertAVL(T->rchild,i,taller))

return 0;

}

}

return 1;

}

/*输出平衡二叉树*/

void PrintBT(BTree T)

{

{

printf("%d",T->data);

if(T->lchild||T->rchild)

{

printf("(");

PrintBT(T->lchild);

printf(",");

PrintBT(T->rchild);

printf(")");

}

}

}

/*删除结点时左平衡旋转处理*/

void Left_Root_Balance_det(BTree &p,int &shorter)

{

BTree p1,p2;

if(p->bf==1) //p结点的左子树高,删除结点后p的bf减,树变矮

{

p->bf=0;

shorter=1;

}

else if(p->bf==0)//p结点左、右子树等高,删除结点后p的bf减,树高不变 {

p->bf=-1;

shorter=0;

}

else //p结点的右子树高

{

p1=p->rchild;//p1指向p的右子树

if(p1->bf==0)//p1结点左、右子树等高,删除结点后p的bf为-2,进行左旋处理,树高不变

{

Left_Balance(p);

p1->bf=1;

p->bf=-1;

shorter=0;

}

else if(p1->bf==-1)//p1的右子树高,左旋处理后,树变矮

{

Left_Balance(p);

p1->bf=p->bf=0;

shorter=1;

else //p1的左子树高,进行双旋处理(先右旋后左旋),树变矮 {

p2=p1->lchild;

p1->lchild=p2->rchild;

p2->rchild=p1;

p->rchild=p2->lchild;

p2->lchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

else if(p2->bf==-1)

{

p->bf=1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=-1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

/*删除结点时右平衡旋转处理*/

void Right_Root_Balance_det(BTree &p,int &shorter)

{

BTree p1,p2;

if(p->bf==-1)

{

p->bf=0;

shorter=1;

}

else if(p->bf==0)

{

p->bf=1;

shorter=0;

}

else

{

p1=p->lchild;

if(p1->bf==0)

{

Right_Balance(p);

p1->bf=-1;

p->bf=1;

shorter=0;

}

else if(p1->bf==1)

{

Right_Balance(p);

p1->bf=p->bf=0;

shorter=1;

}

else

{

p2=p1->rchild;

p1->rchild=p2->lchild;

p2->lchild=p1;

p->lchild=p2->rchild;

p2->rchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

else if(p2->bf==1)

{

p->bf=-1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

/*删除结点*/

void Delete(BTree q,BTree &r,int &shorter)

{

if(r->rchild==NULL)

{

q->data=r->data;

q=r;

r=r->lchild;

free(q);

shorter=1;

}

else

{

Delete(q,r->rchild,shorter);

if(shorter==1)

Right_Root_Balance_det(r,shorter);

}

}

/*二叉树的删除操作*/

int DeleteAVL(BTree &p,int x,int &shorter)

{

int k;

BTree q;

if(p==NULL)

{

printf("不存在要删除的关键字!!\n");

return 0;

}

else if(x

data)//在p的左子树中进行删除

{

k=DeleteAVL(p->lchild,x,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

return k;

}

else if(x>p->data)//在p的右子树中进行删除

{

k=DeleteAVL(p->rchild,x,shorter);

if(shorter==1)

Right_Root_Balance_det(p,shorter);

return k;

}

else

{

q=p;

if(p->rchild==NULL) //右子树空则只需重接它的左子树

{

p=p->lchild;

free(q);

shorter=1;

}

else if(p->lchild==NULL)//左子树空则只需重接它的右子树

{

p=p->rchild;

free(q);

shorter=1;

}

else//左右子树均不空

{

Delete(q,q->lchild,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

p=q;

}

return 1;

}

}

/*调平二叉树具体方法*/

bool SetAVL(BTree &T,int i,bool &taller)

{

if(!T)//插入新结点,树“长高”,置taller为true

{

T = (BTree)malloc(sizeof(BTNode));

T->data = i;

T->lchild = T->rchild =NULL;

T->bf = 0;

taller = 1;

}

else

{

if(i==T->data) //树中已存在和有相同关键字的结点 {

taller = false;

printf("已存在相同关键字的结点\n");

return 0;

}

if(idata) //应继续在*T的左子树中进行搜索 {

if(!SetAVL(T->lchild,i,taller))

return 0;

if(taller) //已插入到*T的左子树中且左子树“长高”

switch(T->bf) //检查*T的平衡度

{

case 1: //原本左子树比右子树高,需要作左平衡处理

Left_Root_Balance(T);

taller = false;

break;

case 0: //原本左子树、右子等高,现因左子树增高而使树增高

T->bf = 1;

taller = 1;

break;

case -1: //原本右子树比左子树高,现左、右子树等高

T->bf = 0;

taller = false;

break;

}

}

else //应继续在*T的右子树中进行搜索

{

if(!SetAVL(T->rchild,i,taller))

return 0;

if(taller) //已插入到*T的右子树中且右子树“长高”

switch(T->bf) //检查*T的平衡度

{

case 1: //原本左子树比右子树高,现左、右子树等高

T->bf = 0;

taller = false;

break;

case 0: //原本左子树、右子等高,现因右子树增高而使树增高

T->bf = -1;

taller = 1;

break;

case -1: //原本右子树比左子树高,需要作右平衡处理

Right_Root_Balance(T);

taller = 0;

break;

}

}

return 1;

}

}

/*二叉树调平操作*/

void Adj_balance(BTree &T)

{

int i;

bool taller=0;

T = NULL;

printf("\n请输入关键字(以-1结束建立平衡二叉树):");

scanf("%d",&i);

getchar();

while(i != -1)

{

SetAVL(T,i,taller);

printf("\n请输入关键字(以-1结束建立平衡二叉树):");

scanf("%d",&i);

getchar();

taller=0;

}

printf("平衡二叉树创建结束.\n");

if(T)

PrintBT(T);

else

printf("这是一棵空树.\n");

}

/*菜单函数*/

int menu( )

{

int m;

printf("..........................2015年7月1日......................\n\n");

printf(" 平衡二叉树\n");

printf(" ________________________________\n\n"); printf(" 1 创建平衡二叉树\n");

printf(" 2 在平衡二叉树上增加新结点并调平衡\n"); printf(" 3 删除一个结点\n");

printf(" 0 退出\n");

printf(" ________________________________\n\n"); printf(" 请输入所选功能0-3\n");

scanf("%d",&m);

return m;

}

/*主函数*/

void main()

{

int input,search;

bool taller=0;

int shorter=0;

BTree T;

T=(BTree)malloc(sizeof(BTNode));

T=NULL;

while(1)

{

printf("\n请选择需要的二叉树操作\n"); input=menu( );

switch(input)

{

case 1:

Adj_balance(T);

break;

case 2:

printf("请输入你要增加的关键字"); scanf("%d",&search);

getchar();

SetAVL(T,search,taller); PrintBT(T);

break;

case 3:

printf("请输入你要删除的关键字"); scanf("%d",&search);

getchar();

DeleteAVL(T,search,shorter); PrintBT(T);

break;

case 0:

break;

default:

printf("输入错误,请重新选择。"); break;

}

if(input == 0)

break;

printf("按任意键继续."); getchar();

}

}


相关文章

  • 惠斯通电桥实验报告
  • 阜阳师范学院 大学物理实验报告 学号姓名实验日期 教师签字 成绩 [实验名称] 惠斯通电桥测电阻 [实验目的] (1)掌握惠斯通电桥的基本原理. (2)学会自组惠斯通电桥测电阻,掌握QJ23型箱式电桥的使用方法. (3)了解直流电桥的灵敏度 ...查看


  • 2015广工数据结构实验报告平衡二叉树
  • 数据结构设计性实验报告 课程名称_____数据结构实验_ 题目名称平衡二叉树 学生学院__ 计算机学院______ 专业班级_ 学 号____ ______ 学生姓名____ _ ___ 指导教师______ ____ 2015年6月14日 ...查看


  • 探究:杠杆的平衡条件实验报告[绝对经典]
  • 探究:杠杆的平衡条件 作者:广西崇左市桐中 梁洪章 一.探究目的: 杠杆的平衡条件 二.实验器材: 杠杆 . 钩码盒一套 . 弹簧测力计 . 细线 . 刻度尺 三.探究假设: 杠杆的平衡可能与"动力和力臂的乘积".&qu ...查看


  • 杠杆平衡条件实验报告单
  • 探究杠杆的平衡条件实验报告单 学校 班级 实验日期 年 月 日 姓名 同组人姓名 一.探究目的: 二.实验器材: . . . . 三.探究假设: 四.实验步骤: 一.调节杠杆两端的 ,使横梁平衡. 二.在杠杆的左右两端分别用细线依次悬挂个数 ...查看


  • 会计实验报告(总账系统期末处理)
  • 实验报告 系 部 会计系 _ 专业班级 课程名称 会计信息系统 实验教师 学 号 学生姓名 实验项目名称 总账系统期末处理 实验日期 实验地点 会计电算化实验室 _ 成 绩 _ 制表单位:会计系 实验报告 实验目的和要求 1.掌握用友财务管 ...查看


  • 密立根油滴实验实验报告
  • 实验目的 1. 通过对带电油滴在重力场和静电场中运动的测量,验证电荷的不连续性,并测定电子电荷的电荷值e. 2. 通过实验过程中,对仪器的调整.油滴的选择.耐心地跟踪和测量以及数据的处理等,培养学生严肃认真和一丝不苟的科学实验方法和态度. ...查看


  • 转子动平衡实验报告
  • 转子动平衡实验报告 一 实验目的 1. 巩固转子动平衡知识,加深转子动平衡概念的理解. 2. 掌握刚性转子动平衡实验的原理及基本方法. 3.了解动平衡试验机的组成﹑工作原理,通过参数化和可视化的方法,观察转子动平衡虚拟实验的平衡效果. 二实 ...查看


  • 实验报告模板用惠斯通电桥测电阻
  • 梧州学院学生实验报告 成绩: 专业: 实验人: 实验名称: 班别: 学号: 实验十二 指导教师: 实验时间: 同组实验人: 用惠斯登电桥测电阻 实验目的: 1.掌握用惠斯登电桥测电阻的原理. 2.学会用惠斯登电桥测电阻. 3.了解电桥灵敏度 ...查看


  • 探究加速度与力.质量的关系_实验报告
  • 实验:探究加速度与力.质量的关系 [实验目的] 通过实验探究物体的加速度与它所受的合力.质量的定量关系 [实验原理] 1.控制变量法: ⑴保持m一定时,改变物体受力F测出加速度a,用图像法研究a与F关系 ⑵保持F一定时,改变物体质量m测出加 ...查看


  • 物理化学实验报告模板
  • 物理化学实验报告 院系班级学号姓名 1820100019 凯文 实验名称 二元体系沸点-组成图测绘 日期 同组者姓名 欧阳洁 成绩 一. 实验目的和要求 (1)在大气压下,测定环已烷-乙醇体系.液气平衡相图(沸点-组成图). (2)掌握阿贝 ...查看


热门内容