二叉树查找-二分法查找二叉树
![二叉树查找-二分法查找二叉树](https://img.360docs.net/img2e/01eg1befrrha40b4e0vb-e1.webp)
![二叉树查找-二分法查找二叉树](https://img.360docs.net/img2e/01eg1befrrha40b4e0vb-b2.webp)
二叉树查找-二分法查找二叉树
二分法查找二叉树方法:左大右小,找不到的时候就分支限定的查找#include
#include
using namespace std;
struct tree{ // 声明树的结构
struct tree *left;
int data;
struct tree *right;
};
typedef struct tree treenode;//声明新类型的树的结构
typedef treenode *b_tree;//声明二叉树的链表
/*递归建立二叉树*/
b_tree creat_btree(int *nodelist,int position)//看好了某些定义b_tree {
b_tree newnode;//声明树根指针
if(nodelist[position]==0||position>15)
{//cout <<"d";
return NULL;}
else{
newnode = (b_tree) malloc(sizeof(treenode));//申请空间
newnode->data=nodelist[position];//建立节点内容
//cout << " newnode=" << newnode->data;
newnode->left=creat_btree(nodelist,2*position); //递归建立左子树newnode->right=creat_btree(nodelist,2*position+1);//递归建立右子树return newnode;
}
}
//建立二叉树
//二叉树遍历方式查找
b_tree btree_travesal_search(b_tree point,int findnode)
{
b_tree point1,point2;//声名往左和往右查询的指针
if(point!=NULL)
{
if(point->data==findnode)
return point;
else
//找左子树
point1=btree_travesal_search(point->left,findnode);
//找右子树
point2=btree_travesal_search(point->right,findnode);
if(point1 != NULL)
return point1;
else if(point2!=NULL)
return point2;
else return NULL;
}
else
return NULL;
}
//二叉树二分查找法
b_tree btree_travesal_search1(b_tree point, int findnode)
{
while(point!=NULL)
{
if(point->data==findnode)//找到了数据
return point;//返回找到节点的指针
else
if(point->data>findnode)
{point=point->left;}//向左子树找
else {point=point->right;}//向右子树找
}
return NULL;
}
void inoder(b_tree point)
{
if(point!=NULL)
{
inoder(point->left);
cout << point->data<<" ";
inoder(point->right);
}
};
int main(int argc, char *argv[])
{
b_tree root = NULL;//树根指针
b_tree point = NULL;
int findnode;
int i;
int nodelist[16]={0,5,2,9,0,4,7,0,0,0,3,0,6,8,0,0};
//---------------建立树状结构-----------//
root = creat_btree(nodelist,1); //建立
printf("\n The node content of arrary_structure is:\n");
printf("\nPlease input the node value(1...9) you want search:");
scanf("%d",&findnode);
//进行遍历查找
point=btree_travesal_search(root,findnode);
if(point!=NULL)
{
cout << "\n=Travesal search result: \n";
printf(" The finding node value is [%d]\n",point->data); }
else
printf("\nTravesal search result: NOT found!!\n");
//二分查找
point = btree_travesal_search1(root,findnode);
if(point!=NULL)
{
cout << "\n=Binary search result: \n";
printf(" The finding node value is [%d]\n",point->data); }
else cout << "\nBinary search not found!!\n";
inoder(root);
/*
for(i=1;i<16;i++)
cout << nodelist[i] <<" ";
cout < //打印树状结构连表的内容 //cout <<"\nThe postoder travesal result is"; inoder(root);*/ system("PAUSE"); return EXIT_SUCCESS; } #include #include using namespace std; struct tree{ // 声明树的结构 struct tree *left; int data; struct tree *right; }; typedef struct tree treenode;//声明新类型的树的结构 typedef treenode *b_tree;//声明二叉树的链表 b_tree creat_btree(int *nodelist,int position)//看好了某些定义b_tree { b_tree newnode;//声明树根指针 if(nodelist[position]==0||position>15) {cout <<"d";return NULL;} else{ newnode = (b_tree) malloc(sizeof(treenode));//申请空间 newnode->data=nodelist[position];//建立节点内容 newnode->left=creat_btree(nodelist,2*position); //递归建立左子树newnode->right=creat_btree(nodelist,2*position+1);//递归建立右子树return newnode; } } //建立二叉树 void inoder(b_tree point) { if(point!=NULL) { inoder(point->left); cout << point->data<<" "; inoder(point->right); } } int main(int argc, char *argv[]) { b_tree root = NULL;//树根指针 int i; int nodelist[16]={0,5,9,2,1,4,7,0,0,0,3,0,6,8,0,0}; //---------------建立树状结构-----------// root = creat_btree(nodelist,1); printf("\n The node content of arrary_structure is:\n"); for(i=1;i<16;i++) cout << nodelist[i] <<" "; cout < //打印树状结构连表的内容 //cout <<"\nThe postoder travesal result is"; inoder(root); system("PAUSE"); return EXIT_SUCCESS; } 注:递归的构建二叉树只是单独的递归调用构造函数,并没有按照一定的大小比较规则进行排序。 二叉树后序遍历的思想: 从根节点开始,沿左子树一直走到没有左孩子的节点为止, 并将所经[节点]的地址第一次进栈; 当找到没有左孩子的节点时,此节点的左子树已访问完毕; 从栈顶退出该节点,判断该节点是否为第一次进栈,如是,再 将所经[节点]的地址第二次进栈,并沿该节点的右子树一直走到 没有右孩子的节点为止,如否,则访问该节点;此时,该节点的 左、右子树都已完全遍历,且令指针p = NULL; 如此重复到栈空为止。 例如有如上图所示二叉树,则后序遍历的顺序是:O J / I * H + G A 实现程序如下: #include #include using namespace std; struct tree{ // 声明树的结构 struct tree *left; int data; struct tree *right; }; typedef struct tree treenode;//声明新类型的树的结构 typedef treenode *b_tree;//声明二叉树的链表 b_tree insert_node(b_tree root,int node)//看好了某些定义b_tree { b_tree newnode;//声明树根指针 b_tree currentnode;//声明目前节点指针 b_tree parentnode;//声明父亲接点指针 //建立新节点的内存空间 newnode = (b_tree) malloc(sizeof(treenode)); //建立新节点的内存空间 newnode->data=node;//存入节点的内容newnode->right=NULL;//设置右指针的初值newnode->left=NULL;//设置左指针的初值 if(root == NULL) return newnode; else { currentnode = root; while(currentnode!=NULL) { parentnode = currentnode; if(node < currentnode->data)//比较节点的数值大小{currentnode = currentnode->left;}//坐子树 else currentnode =currentnode->right;//右子树 }//寻找空的节点便插入 if(parentnode->data > node) {parentnode->left = newnode;} else parentnode->right = newnode;//插入了哈哈 } return root; } //建立二叉树 b_tree creat_btree(int *data,int len) { b_tree root = NULL;//根节点指针 int i; for(i=0;i { root=insert_node(root,data[i]);} return root; } //打印二叉树 /*void print_btree(b_tree root) { b_tree pointer; pointer = root->left; printf("Print left_subtree node of root:\n"); while(pointer!=NULL) { printf("[%2d]\n",pointer->data); pointer = pointer->left;//指向左节点 } pointer = root->right; printf("Print right_subtree node of root:\n"); while(pointer!=NULL) { printf("[%2d]\n",pointer->data);//打印节点的内容pointer = pointer->right;//指向右节点 } }*/ void postoder(b_tree point) { if(point!=NULL) { postoder(point->left);//左--右--根 postoder(point->right); cout << point->data<<" "; } } int main(int argc, char *argv[]) { b_tree root = NULL; int i,index; int value; int nodelist[20]; printf("\n Please input the elsements of binary tree (Exit for 0):\n"); index = 0; scanf("%d",&value); while (value!= 0) { nodelist[index]=value; index++; scanf("%d",&value); } root= creat_btree(nodelist,index);//建立二叉树 // print_btree(root);//打印二叉树节点的内容 cout <<"\nThe postoder travesal result is"; postoder(root); system("PAUSE"); return EXIT_SUCCESS; } #include #include #include #include #include #include #include #include #define OK 1 #define ERROR 0 #define MAXSIZE 100 #define MAXRC 20 typedef int Status; typedef int ElemType; typedef struct { int i,j; ElemType e; }Triple; typedef struct { Triple data[MAXSIZE+1]; int rpos[MAXRC+1]; int mu,nu,tu; }RLSMatrix; typedef struct OLNode { int i,j; ElemType e; struct OLNode *right,*down; }OLNode,*OLink; typedef struct { OLink *rhead,*chead; }CrossList; Status CreateSMatrix(RLSMatrix *M); void DestroySMatrix(RLSMatrix *M); void PrintSMatrix(RLSMatrix M); Status ADD(RLSMatrix M,RLSMatrix N,RLSMatrix *Q); Status SubtS(RLSMatrix M,RLSMatrix N,RLSMatrix *Q); Status Mult(RLSMatrix M,RLSMatrix N,RLSMatrix *Q); Status FastTransposeSMatrix(RLSMatrix M,RLSMatrix *T); int menu_select(); Status Operate(RLSMatrix A,RLSMatrix B,RLSMatrix *C); Status Exchange(RLSMatrix M,CrossList *N); Status Show(CrossList N); Status Change(RLSMatrix A,RLSMatrix B,RLSMatrix C,CrossList *M); Status DestoryCrossList(CrossList *M); void About(); main() { RLSMatrix A,B,C; CrossList N; clrscr(); About(); for(;;) { switch(menu_select()) { case 1:clrscr(); printf("\n\n\n\t-------------Create Sparse Matrix A-----------------"); CreateSMatrix(&A); break; printf("\n\n\n\t-------------Create Sparse Matrix B-----------------"); CreateSMatrix(&B); break; case 3: Operate(A,B,&C); break; case 4:Change(A,B,C,&N); break; case 5:About();break; case 6: DestroySMatrix(&A); DestroySMatrix(&B); DestroySMatrix(&C); DestoryCrossList(&N); exit(0); } } } int menu_select() { char *menu[]={ "", "", "", " +--------------MENU--------------+", " | |", " | 1.Create Sparse Matrix A |", " | 2.Create Sparse Matrix B |", " | 3.Operate |", " | 4.Change into CrossList |", " | 5.About... |", " | 6.Quit |", " | |", " | |", " +-----------------------------------+", " By Teacher", " 10/10/07",}; char s[3]; int c,i; gotoxy(1,25); printf("Any key to enter menu......\n"); getch(); clrscr(); for(i=0;i<16;i++) { gotoxy(10,i+1); cprintf("%s",menu[i]); } window(1,1,80,25); gotoxy(10,21); do{printf("\n Enter your choice(1~6):"); scanf("%s",s); c=atoi(s); }while(c<1||c>6); return c; } Status CreateSMatrix(RLSMatrix *M) { int i; Triple T; int flag=0,mis; printf("\nPlease input the row,col,and nonzero element number of the Sparse Matrix."); printf("\nForm:row num,col num,nonzero element num\n"); scanf("%d,%d,%d",&(*M).mu,&(*M).nu,&(*M).tu); (*M).data[0].i=0; for(i=1;i<=(*M).tu;i++) { mis=0; do { if(flag) { printf("ERROR INPUT!\n"); flag=0; mis++;} if(mis==3) { printf("Fail Create !"); return OK;} printf("Please input the row,col and value of the %dth nonzero element:",i); scanf("%d,%d,%d",&T.i,&T.j,&T.e); if(T.i<1||T.i>(*M).mu||T.j<1||T.j>(*M).nu) flag=1; if(T.i<(*M).data[i-1].i||T.i==(*M).data[i-1].i&&T.j<=(*M).data[i-1].j) flag=1; }while(flag); (*M).data[i]=T; } for(i=1;i<=(*M).tu;i++) for(T.i=0;T.i<(*M).data[i].i-(*M).data[i-1].i;T.i++) (*M).rpos[(*M).data[i].i-T.i]=i; for(i=(*M).data[(*M).tu].i+1;i<=(*M).mu;i++) (*M).rpos[i]=(*M).tu+1; PrintSMatrix(*M); return OK; } void PrintSMatrix(RLSMatrix M) { int i,j,k; printf("\n "); for(i=1,k=1;i<=M.mu;i++) { for(j=1;j<=M.nu;j++) { if(M.data[k].i==i&&M.data[k].j==j) {printf("%d\t",M.data[k].e); k++;} else printf("0\t"); while(j==M.nu) {printf("\n ");break;} } } } Status ADD(RLSMatrix M,RLSMatrix N,RLSMatrix *Q) { int k,p,q; if(M.mu!=N.mu||M.nu!=N.nu) return ERROR; (*Q).mu=M.mu; (*Q).nu=M.nu; (*Q).tu=0; M.rpos[M.mu+1]=M.tu+1; N.rpos[N.mu+1]=N.tu+1; for(k=1;k<=M.mu;++k) { (*Q).rpos[k]=(*Q).tu+1; p=M.rpos[k]; q=N.rpos[k]; while(p { if(M.data[p].j==N.data[q].j) { (*Q).data[(*Q).tu+1].e=M.data[p].e+N.data[q].e; if((*Q).data[(*Q).tu+1].e!=0) { ++(*Q).tu; (*Q).data[(*Q).tu].i=k; (*Q).data[(*Q).tu].j=M.data[p].j; } ++p; ++q; } else if(M.data[p].j { ++(*Q).tu; (*Q).data[(*Q).tu].e=M.data[p].e; (*Q).data[(*Q).tu].i=k; (*Q).data[(*Q).tu].j=M.data[p].j; ++p; } else { ++(*Q).tu; (*Q).data[(*Q).tu].e=N.data[q].e; (*Q).data[(*Q).tu].i=k; (*Q).data[(*Q).tu].j=N.data[q].j; ++q; } } while(p { ++(*Q).tu; (*Q).data[(*Q).tu].e=M.data[p].e; (*Q).data[(*Q).tu].i=k; (*Q).data[(*Q).tu].j=M.data[p].j; ++p; } while(q { ++(*Q).tu; (*Q).data[(*Q).tu].e=N.data[q].e; (*Q).data[(*Q).tu].i=k; (*Q).data[(*Q).tu].j=N.data[q].j; ++q; } } return OK; } Status SubtS(RLSMatrix M,RLSMatrix N,RLSMatrix *Q) { int i; if(M.mu!=N.mu||M.nu!=N.nu) return ERROR; for(i=1;i<=N.tu;++i) N.data[i].e*=-1; ADD(M,N,Q); return OK; } Status Mult(RLSMatrix M,RLSMatrix N,RLSMatrix *Q) { int arow,brow,p,q,ccol,ctemp[MAXRC+1]; if(M.nu!=N.mu) return ERROR; (*Q).mu=M.mu; (*Q).nu=N.nu; (*Q).tu=0; M.rpos[M.mu+1]=M.tu+1; N.rpos[N.mu+1]=N.tu+1; if(M.tu*N.tu!=0) { for(arow=1;arow<=M.mu;++arow) { for(ccol=1;ccol<=(*Q).nu;++ccol) ctemp[ccol]=0; (*Q).rpos[arow]=(*Q).tu+1; for(p=M.rpos[arow];p { brow=M.data[p].j; for(q=N.rpos[brow];q { ccol=N.data[q].j; ctemp[ccol]+=M.data[p].e*N.data[q].e; } } for(ccol=1;ccol<=(*Q).nu;++ccol) if(ctemp[ccol]) { if(++(*Q).tu>MAXSIZE) return ERROR; (*Q).data[(*Q).tu].i=arow; (*Q).data[(*Q).tu].j=ccol; (*Q).data[(*Q).tu].e=ctemp[ccol]; } } } return OK; } Status FastTransposeSMatrix(RLSMatrix M,RLSMatrix *T) { int col,p,q,t,num[MAXRC+1],cpot[MAXRC+1]; (*T).mu=M.nu; (*T).nu=M.mu; (*T).tu=M.tu; if((*T).tu){ for(col=1;col<=M.nu;++col) num[col]=0; for(t=1;t<=M.tu;++t) ++num[M.data[t].j]; cpot[1]=1; for(col=2;col<=M.nu;++col) cpot[col]=cpot[col-1]+num[col-1]; for(p=1;p<=M.tu;++p){ col=M.data[p].j; q=cpot[col]; (*T).data[q].i=M.data[p].j; (*T).data[q].j=M.data[p].i; (*T).data[q].e=M.data[p].e; ++cpot[col]; } } PrintSMatrix(M); printf("\nTranspose:\n"); PrintSMatrix(*T); return OK; } Status Operate(RLSMatrix A,RLSMatrix B,RLSMatrix *C) { int c; char t; do{ clrscr(); printf("\nInput your choice:\n(ADD--1,SUB--2,MUL--3,Transpose A--4,Transpose B--5,QUIT--any except 1~5)\n"); scanf("%d",&c); switch(c) { case 1: if(A.mu!=B.mu||A.nu!=B.nu) { printf("Can't,condition misfit!\n"); break; } ADD(A,B,C); 课程设计任务书 题目: 二叉排序树的建立及遍历的实现 初始条件: 理论:学习了《数据结构》课程,掌握了基本的数据结构和常用的算法; 实践:计算机技术系实验室提供计算机及软件开发环境。 要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1、系统应具备的功能: (1)建立二叉排序树; (2)中序遍历二叉排序树并输出排序结果; 2、数据结构设计; 3、主要算法设计; 4、编程及上机实现; 5、撰写课程设计报告,包括: (1)设计题目; (2)摘要和关键字; (3)正文,包括引言、需求分析、数据结构设计、算法设计、程序实现及测试、设计体会等; (4)结束语; (5)参考文献。 时间安排:2007年7月2日-7日(第18周) 7月2日查阅资料 7月3日系统设计,数据结构设计,算法设计 7月4日-5日编程并上机调试7月6日撰写报告 7月7日验收程序,提交设计报告书。 指导教师签名: 2007年7月2日 系主任(或责任教师)签名: 2007年7月2日 排序二叉树的建立及其遍历的实现 摘要:我所设计的课题为排序二叉树的建立及其遍历的实现,它的主要功能是将输入的数据 组合成排序二叉树,并进行,先序,中序和后序遍历。设计该课题采用了C语言程序设计,简洁而方便,它主要运用了建立函数,调用函数,建立递归函数等等方面来进行设计。 关键字:排序二叉树,先序遍历,中序遍历,后序遍历 0.引言 我所设计的题目为排序二叉树的建立及其遍历的实现。排序二叉树或是一棵空树;或是具有以下性质的二叉树:(1)若它的左子树不空,则作子树上所有的结点的值均小于它的根结点的值;(2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)它的左,右子树也分别为二叉排序树。对排序二叉树的建立需知道其定义及其通过插入结点来建立排序二叉树,遍历及其输出结果。 该设计根据输入的数据进行建立排序二叉树。对排序二叉树的遍历,其关键是运用递归 调用,这将极大的方便算法设计。 1.需求分析 建立排序二叉树,主要是需要建立节点用来存储输入的数据,需要建立函数用来创造排序二叉树,在函数内,需要进行数据比较决定数据放在左子树还是右子树。在遍历二叉树中,需要建立递归函数进行遍历。 该题目包含两方面的内容,一为排序二叉树的建立;二为排序二叉树的遍历,包括先序遍历,中序遍历和后序遍历。排序二叉树的建立主要运用了循环语句和递归语句进行,对遍历算法运用了递归语句来进行。 2.数据结构设计 本题目主要会用到建立结点,构造指针变量,插入结点函数和建立排序二叉树函数,求深度函数,以及先序遍历函数,中序遍历函数和后序遍历函数,还有一些常用的输入输出语句。对建立的函明确其作用,先理清函数内部的程序以及算法在将其应用到整个程序中,在建立排序二叉树时,主要用到建立节点函数,建立树函数,深度函数,在遍历树是,用到先序遍历函数,中序遍历函数和后序遍历函数。 #include 二叉树查找 //树表的查找 #include bstnode * search_bst(bstnode *p,int k) { if(p==NULL||p->key==k) return p; if(k 平衡二叉树(AVL)查找、插入和删除 小组成员: 陈静101070009 陈丹璐101070006 陈娇101070008 目录 平衡二叉树(AVL) (1) 查找、插入和删除 (1) 问题描述 (2) 设计说明 (3) (一)ADT (3) (二)算法思想 (5) (三)数据结构 (12) (四)程序结构与流程 (13) 运行平台及开发工具 (15) I/O格式 (15) 算法复杂度分析 (18) 源代码 (18) 小结 (37) 问题描述 利用平衡二叉树实现一个动态查找表。 (1)实现动态查找表的三种基本功能:查找、插入和删除。 (2)初始时,平衡二叉树为空树,操作界面给出创建、查找、插入和删除和退出五种操作供选择。每种操作均要提示输入关键字。创建时,根据提示输入数据,以-1为输入数据的结束标志,若输入数据重复,则给出已存在相同关键字的提示,并不将其插入到二叉树中。在查找时,如果查找的关键字不存在,则显示不存在查找的关键字,若存在则显示存在要查找的关键字。插入时首先检验原二叉树中是否已存在相同第3 页共38 页- 3 -的关键字,若没有则进行插入并输出二叉树,若有则给出已有相同关键字的提醒。删除时首先检验原二叉树中是否存在要删除的关键字,若有则进行删除后并输出二叉树,若没有则给出不存在要删除的关键字的提醒。 (3)平衡二叉树的显示采用中序遍历的方法输出,还可以根据输出数据是否有序验证对平衡二叉树的操作是否正确。 设计说明 (一)ADT ADT BalancedBinaryTree{ 数据对象D:D是具有相同特性的数据元素的集合。各个数据元素均含有类型相同,可唯一标志的数据元素的关键字。 数据关系R:数据元素同属一个集合。 基本操作P: void R_Rotate(BSTree &p); 初始条件:二叉树存在,且关键字插入到以*p为根的二叉树的左子树的左孩子上; 操作结果:对以*p为根的二叉排序树作右旋处理 wyf 实现二叉排序树的各种算法 一.需求分析 (1)系统概述: 本系统是针对排序二叉树设计的各种算法,提供的功能包括有:(1)插入新结点(2)前序、中序、后序遍历二叉树(3)中序遍历的非递归算法(4)层次遍历二叉树(5)在二叉树中查找给定关键字(函数返回值为成功1,失败0) 二.总体设计 (1)系统模块结构图 (2)数据结构设计 typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild;//左右孩子指针} BiTNode,*BiTree; typedef BiTree SElemType; typedef BiTree QElemType; typedef struct { QElemType *base; // 初始化的动态分配存储空间 int front; // 头指针,若队列不空,指向队列头元素 int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置 }SqQueue; typedef struct { SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL SElemType *top; // 栈顶指针 int stacksize; // 当前已分配的存储空间,以元素为单位 }SqStack; // 顺序栈 Status InitStack(SqStack &S) { // 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE // 请补全代码 S.base = (SElemType * )malloc(STACK_INIT_SIZE * sizeof(SElemType)); if(!S.base) return (ERROR); S.top = S.base ; 课程设计任务书 2011 —2012 学年第一学期 电子与信息工程系计算机专业09计算机一班班级 课程设计名称:数据结构课程设计 设计题目:排序二叉树的遍历 完成期限:自2012 年 1 月 2 日至2012 年 1 月 6 日共 1 周 设计依据、要求及主要内容(可另加附页): 一、设计目的 熟悉各种数据结构和运算,会使用数据结构的基本操作解决一些实际问题。 二、设计要求 (1)重视课程设计环节,用严谨、科学和踏实的工作态度对待课程设计的每一项任务; (2)按照课程设计的题目要求,独立地完成各项任务,严禁抄袭;凡发现抄袭,抄袭者与被抄袭者皆以零分计入本课程设计成绩。凡发现实验报告或源程序雷同,涉及的全部人员皆以零分计入本课程设计成绩; (3)学生在接受设计任务后,首先要按设计任务书的要求编写设计进程表; (4)认真编写课程设计报告。 三、设计内容 排序二叉树的遍历(用递归或非递归的方法都可以) 1)问题描述 输入树的各个结点,建立排序二叉树,对建立的排序二叉树进行层次、先序、中序和后序遍历并统计该二叉树中叶子结点的数目。 2)基本要求 (1)用菜单实现 (2)能够输入树的各个结点,并能够输出用不同方法遍历的遍历序列和叶子结点的数目。 四、参考文献 1.王红梅.数据结构.清华大学出版社 2.王红梅.数据结构学习辅导与实验指导.清华大学出版社3.严蔚敏,吴伟民.数据结构(C语言版).清华大学出版社 #include 数据结构课程设计---二叉排序树和平衡二叉树的判别 二叉排序树和平衡二叉树的判别 1引言 数据结构是软件工程的一门核心专业基础课程,在我们专业的课程体系中起着承上启下的作用,学好数据结构对于提高理论认知水平和实践能力有着极为重要的作用。学习数据结构的最终目的是为了获得求解问题的能力。对于现实世界中的问题,应该能从中抽象出一个适当的数据模型,该数学模型在计算机内部用相应的数据结构来表示,然后设计一个解此数学模型的算法,在进行编程调试,最后获得问题的解答。 本次课程设计的题目是对二叉排序树和平衡二叉树的扩展延伸应用。首先我们得建立一个二叉树,二叉树有顺序存储结构和链式存储结构两种存储结构,此次我选用的是二叉链表的存储结构。对于判断平衡二叉树,需要求出其每个叶子结点所在的层数,这里我采用的边遍历边求的方式,遍历采用的是先序遍历。二叉树的建立以及二叉排序树和平衡二叉树的判别中都用到了递归思想。 2需求分析 2.1在日常生活中,人们几乎每天都要进行“查找”工作。所谓“查找”即为 在一个含有众多的数据元素(或记录)的查找表中找出某个“特定的”数据元素(或记录),即关键字。 2.2本程序意为对一个已经建立的动态查找表——二叉树——判断其是否是二 叉排序树和平衡二叉树。 3数据结构设计 3.1抽象数据类型二叉树的定义如下: ADT BinaryTree{ 3.1.1数据对象D:D是具有相同特性的数据元素的集合。 3.1.2数据关系R: 若D=NULL,则R=NULL,称BinaryTree为空的二叉树; 若D!=NULL,则R={H},H是如下的二元关系: 3.1.2.1在D中存在唯一的称为根的数据元素root,它在关系H下无前驱; 3.1.2.2若D-{root}!=NULL,则存在D-{root}={Dl,Dr},且Dl与Dr相交为空; 3.1.2.3若Dl!=NULL,则Dl中存在唯一的元素xl, 二叉查找树(BST,Binary Search Tree),又名二叉搜索树或二叉检索树,是一颗满足如下条件的树: 1、每个节点包含一个键值 2、每个节点有最多两个孩子 3、对于任意两个节点x和y,它们满足下述搜索性质: a、如果y在x的左子树里,则key[y] <= key[x] b、如果y在x的右子树里,则key[y] >= key[x] 最优二叉查找树(Optimal BST,Optimal Binary Search Tree) 最优二叉查找树是使查找各节点平均代价最低的二叉查找树。具体来说就是:给定键值序列K = 二叉树的各种算法.txt男人的承诺就像80岁老太太的牙齿,很少有真的。你嗜烟成性的时候,只有三种人会高兴,医生你的仇人和卖香烟的。 /*用函数实现如下二叉排序树算法: (1)插入新结点 (2)前序、中序、后序遍历二叉树 (3)中序遍历的非递归算法 (4)层次遍历二叉树 (5)在二叉树中查找给定关键字(函数返回值为成功1,失败0) (6)交换各结点的左右子树 (7)求二叉树的深度 (8)叶子结点数 Input 第一行:准备建树的结点个数n 第二行:输入n个整数,用空格分隔 第三行:输入待查找的关键字 第四行:输入待查找的关键字 第五行:输入待插入的关键字 Output 第一行:二叉树的先序遍历序列 第二行:二叉树的中序遍历序列 第三行:二叉树的后序遍历序列 第四行:查找结果 第五行:查找结果 第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列 第九行:插入新结点后的二叉树的中序遍历序列(非递归算法) 第十行:插入新结点后的二叉树的层次遍历序列 第十一行~第十三行:第一次交换各结点的左右子树后的先、中、后序遍历序列 第十四行~第十六行:第二次交换各结点的左右子树后的先、中、后序遍历序列 第十七行:二叉树的深度 第十八行:叶子结点数 */ #include "stdio.h" #include "malloc.h" #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; typedef int KeyType; #define STACK_INIT_SIZE 100 // 存储空间初始分配量 #define STACKINCREMENT 10 // 存储空间分配增量 #define MAXQSIZE 100 typedef int ElemType; typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild;//左右孩子指针 } BiTNode,*BiTree; Status SearchBST(BiTree T,KeyType key,BiTree f,BiTree &p) { if(!T){p=f;return FALSE;} else if(key==T->data){p=T;return TRUE;} else if(key 《数据结构》实验报告 姓名: 班级: 学号: 一、算法简介 简单二叉树的创建,删除,查找 二、基本原理 定义节点的结构体,内部成员包括数据data,父节点指针*parent,左子节点指针*lchild,右子结点指针*rchild,以及指针next,然后通过add()和move()函数建立一个二叉树;最后通过del()删除整个二叉树。 三、实现步骤 第一,创建二叉树结点 第二,创建构造二叉树的函数add()和move().在add()中调用move();然后在主函数中初始化二叉树为7个结点(通过建立二叉树的函数)。 创建的二叉树如图: 1 2 3 4 5 6 第三,最后一个个通过查找的方式进行删除结点。该方式不局限于顺序删除,可以 从任何一个结点开始删除,删除后会通过move重新构建,直到删除为止。 四、实验结果如下图 五、结论 本套算法在创建二叉树同时增加了有序检查,通过创建和删除一棵完全二叉树,还可以实现查找结点的功能,未实现遍历、插入、修改、替换等算法,程序较为简单,但是代码工整严谨,时间复杂度和空间复杂度可忽略不计。 六、源程序 #include void move(struct node *p,struct node *s) { while(0) { if(s->data > p->data ) { if(p->rchild==NULL) { p->rchild=s; break; } else { p=p->rchild; } } else { if(p->lchild==NULL) { p->lchild=s; break; } } } } void add(int x) { struct node *s=malloc(sizeof(struct node)),*p=malloc(sizeof(struct node)); s->data=x; s->lchild=NULL; s->rchild=NULL; s->parent=NULL; if(head==NULL) { head=s; } else { p=head; move(p,s); } 5.1树的概念 树的递归定义如下:(1)至少有一个结点(称为根)(2)其它是互不相交的子树 1.树的度——也即是宽度,简单地说,就是结点的分支数。以组成该树各结点中最大的度作为该树的度,如上图的树,其度为3;树中度为零的结点称为叶结点或终端结点。树中度不为零的结点称为分枝结点或非终端结点。除根结点外的分枝结点统称为内部结点。 2.树的深度——组成该树各结点的最大层次,如上图,其深度为4; 3.森林——指若干棵互不相交的树的集合,如上图,去掉根结点A,其原来的二棵子树T1、T2、T3的集合{T1,T2,T3}就为森林; 4.有序树——指树中同层结点从左到右有次序排列,它们之间的次序不能互换,这样的树称为有序树,否则称为无序树。 5.树的表示 树的表示方法有许多,常用的方法是用括号:先将根结点放入一对圆括号中,然后把它的子树由左至右的顺序放入括号中,而对子树也采用同样的方法处理;同层子树与它的根结点用圆括号括起来,同层子树之间用逗号隔开,最后用闭括号括起来。如上图可写成如下形式: (A(B(E(K,L),F),C(G),D(H(M),I,J))) 5. 2 二叉树 1.二叉树的基本形态: 二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态: (1)空二叉树——(a); (2)只有一个根结点的二叉树——(b); (3)右子树为空的二叉树——(c); (4)左子树为空的二叉树——(d); (5)完全二叉树——(e) 注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。 2.两个重要的概念: (1)完全二叉树——只有最下面的两层结点度小于2,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树; (2)满二叉树——除了叶结点外每一个结点都有左右子女且叶结点都处在最底层的二叉树,。 如下图: 完全二叉树 1页 实验三二叉排序树的建立和查找 一、实验目的 1.掌握二叉排序树的建立算法 2.掌握二叉排序树查找算法。 二、实验环境 操作系统和C语言系统 三、预习要求 复习二叉排序树的生成及查找算法,编写完整的程序。 四、实验内容 实现二叉排序树上的查找算法。具体实现要求:用二叉链表做存储结构,输入键值序列,建立一棵二叉排序树并在二叉排序树上实现查找算法。 五、参考算法 #include else return SearchBST(T->rchild,key); /*继续在右子树中查找*/ } void InsertBST(BSTree *T,int key) { /*插入一个值为key的节点到二叉排序树中*/ BSTNode *p,*q; if((*T)==NULL) { /*树为空树*/ (*T)=(BSTree)malloc(sizeof(BSTNode)); (*T)->key=key; (*T)->lchild=(*T)->rchild=NULL; } else { p=(*T); while(p) { q=p; if(p->key>key) p=q->lchild; else if(p->key 学号 数据结构课程设计 设计说明书 排序二叉树的遍历 起止日期:2011 年12月12日至2011 年12月16日 学生姓名 班级 成绩 指导教师(签字) 电子与信息工程系 2011年12月16日 天津城市建设学院 课程设计任务书 2011 —2012 学年第二学期 电子与信息工程系软件工程专业班级 课程设计名称:数据结构课程设计 设计题目:排序二叉树的遍历 完成期限:自2011 年12月12 日至2011 年12月16 日共 1 周 设计依据、要求及主要内容(可另加附页): 一、设计目的 熟悉各种数据结构和运算,会使用数据结构的基本操作解决一些实际问题。 二、设计要求 (1)重视课程设计环节,用严谨、科学和踏实的工作态度对待课程设计的每一项任务; (2)按照课程设计的题目要求,独立地完成各项任务,严禁抄袭;凡发现抄袭,抄袭者与被抄袭者皆以零分计入本课程设计成绩。凡发现实验报告或源程序雷同,涉及的全部人员皆以零分计入本课程设计成绩; (3)学生在接受设计任务后,首先要按设计任务书的要求编写设计进程表; (4)认真编写课程设计报告。 三、设计内容 排序二叉树的遍历(用递归或非递归的方法都可以) 1)问题描述 输入树的各个结点,建立排序二叉树,对建立的排序二叉树进行层次、先序、中序和后序遍历并统计该二叉树中叶子结点的数目。 2)基本要求 (1)用菜单实现 (2)能够输入树的各个结点,并能够输出用不同方法遍历的遍历序列和叶子结点的数目。 四、参考文献 1.王红梅.数据结构.清华大学出版社 2.王红梅.数据结构学习辅导与实验指导.清华大学出版社 3.严蔚敏,吴伟民.数据结构(C语言版).清华大学出版社 指导教师(签字): 教研室主任(签字): 批准日期: 2011 年 12 月 17 日 主要内容: 一、需求分析: 输入树的各个结点,建立排序二叉树,对建立的排序二叉树进行层次、先序、中序和后序遍历并统计该二叉树中叶子结点的数目。 我自己的思想:首先设想把源程序分成头文件,调用和主函数三部分。在头文件中申明类和定义结构体,把先序,中序,后序,层次和叶子节点数的函数定义在类中。然后在调用文件中,把几个函数的实现定义写在里面。最后在主函数中把输出结果以菜单的样式输出来的方式写完主函数程序。实现的过程是先想好自己要输入的是什么,然后通过输入节点制,判断其是否是满足前序遍历,满足则可以实现下后面的功能。 二、问题求解: 现实中的问题:给同学排队问题。 层次是从头开始每一层一层的排,然后分别记号码。 前序是先从最上面的那一个开始往左手边开始排,排之前先计算好人数,然后开始排,排玩左边排右边。 中序是先从最左边开始,然后左斜上角,然后右下角,再左斜上角,直到最上层为止,然后安这个顺序继续排右边的。 后序是先从最左边开始的,左边的一次排过来,然后直接排右边的,也是安依次的顺序,最后才是最上层的。 二叉树查找-二分法查找二叉树 二分法查找二叉树方法:左大右小,找不到的时候就分支限定的查找#include 6.5 二叉排序树★3◎4 1.二叉排序树定义 二叉排序树(Binary Sort Tree)或者是一棵空树;或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结点的值均小于根结点的值;若右子树不空,则右子树上所有结点的值均大于根结点的值。 (2)左右子树也都是二叉排序树,如图6-2所示。 2.二叉排序树的查找过程 由其定义可见,二叉排序树的查找过程为: (1)若查找树为空,查找失败。 (2)查找树非空,将给定值key与查找树的根结点关键码比较。 (3)若相等,查找成功,结束查找过程,否则: ①当给值key小于根结点关键码,查找将在以左孩子为根的子树上继续进行,转(1)。 ②当给值key大于根结点关键码,查找将在以右孩子为根的子树上继续进行,转(1)。 3.二叉排序树插入操作和构造一棵二叉排序树 向二叉排序树中插入一个结点的过程:设待插入结点的关键码为key,为将其插入,先要在二叉排序树中进行查找,若查找成功,按二叉排序树定义,该插入结点已存在,不用插入;查找不成功时,则插入之。因此,新插入结点一定是作为叶子结点添加上去的。构造一棵二叉排序树则是逐个插入结点的过程。对于关键码序列为:{63,90,70,55,67,42,98,83,10,45,58},则构造一棵二叉排序树的过程如图6-3所示。 4.二叉排序树删除操作 从二叉排序树中删除一个结点之后,要求其仍能保持二叉排序树的特性。 设待删结点为*p(p为指向待删结点的指针),其双亲结点为*f,删除可以分三种情况,如图6-4所示。 (1)*p结点为叶结点,由于删去叶结点后不影响整棵树的特性,所以,只需将被删结点的双亲结点相应指针域改为空指针,如图6-4(a)所示。 (2)*p结点只有右子树或只有左子树,此时,只需将或替换*f结点的*p子树即可,如图6-4(b)、(c)所示。 (3)*p结点既有左子树又有右子树,可按中序遍历保持有序地进行调整,如图6-4(d)、(e)所示。 设删除*p结点前,中序遍历序列为: ① P为F的左子女时有:…,Pi子树,P,Pj,S子树,Pk,Sk子树,…,P2,S2子树,P1,S1子树,F,…。 ②P为F的右子女时有:…,F,Pi子树,P,Pj,S子树,Pk,Sk子树,…,P2,S2子树,P1,S1子树,…。 则删除*p结点后,中序遍历序列应为: ①P为F的左子女时有:…,Pi子树,Pj,S子树,Pk,Sk子树,…,P2,S2子树,P1,S1子树,F,…。 ② P为F的右子女时有:…,F,Pi子树,Pj,S子树,Pk,Sk子树,…,P2,S2子树, 实验报告 课程名称:数据结构实验课程 实验四、串的基本操作练习 一、实验目的 1. 掌握二叉树的存储实现 2. 掌握二叉树的遍历思想 3. 掌握二叉树的常见算法的程序实现 二、实验环境 VC++6.0 三、实验内容 1.输入字符序列,建立二叉树的二叉链表结构。(可以采用先序序列) 2.实现二叉树的先序、中序、后序的递归遍历算法。 3.实现二叉树的先序、中序、后序的非递归遍历算法。 4.求二叉树的高度。 5.求二叉树的结点个数。 6.求二叉树的叶子结点的个数。 四、实验要求: 分别编写实现上述算法的子函数,并编写一个主函数,在主函数中设计一个简单的菜单,分别调用上述子函数。 五、实验步骤和结果 1.打开vc,新建文本,命名二叉树算法,编写代码。 2.编写代码: #include BiTNode *base; BiTNode *top; int stacksize; } SqStack;//栈类型 void InitStack(SqStack *S)//创建二叉树 { S->base=(BiTNode*)malloc(STACK_INIT_SIZE*sizeof(BiTNode)); S->top=S->base; S->stacksize=STACK_INIT_SIZE; } void Push(SqStack *S,BiTNode e)//进栈 { if(S->top - S->base >= S->stacksize)//如果栈空间不足 { S->base=(BiTNode*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(B iTNode)); S->top=S->base+S->stacksize; S->stacksize+=STACKINCREMENT; } *(S->top)=e; S->top++; } BiTNode Pop(SqStack *S)//出栈 { S->top --; return *S->top; } int StackEmpty(SqStack *S)//判断栈是否非空 { if(S->top == S->base ) return 1; else return 0; } /*---------------------------------------------递归部分-------------------------------------------*/ 二叉搜索树 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目审核。 在二叉排序树b中查找x的过程为: 若b是空树,则搜索失败,否则: 若x等于b的根结点的数据域之值,则查找成功;否则: 若x小于b的根结点的数据域之值,则搜索左子树;否则: 查找右子树。 Status SearchBST(BiTree T, KeyType key, BiTree f, BiTree &*p){ //在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找成功,//则指针p指向该数据元素结点,并返回TRUE,否则指针指向查找路径上访问的最后//一个结点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL if(!T){ p=f; return FALSE;} //查找不成功 else if EQ(key, T->data.key) {P=T; return TRUE;} //查找成功 else if LT(key,T->data.key) return SearchBST(T->lchild, key, T, p); //在左子树中继续查找 else return SearchBST(T->rchild, key, T, p); //在右子树中继续查找 pascal语言实现 type Link = ^tree; Tree = record D :longint; Left :link; Right :link; End; function search(n :longint;t :link):boolean; Begin If t^.d < n then begin If t^.right = nil then exit(false) else exit(search(n,t^.right)); End; If t^.d > n then begin If t^.left = nil then exit(false) else exit(search(n,t^.left)); End; Exit(true); End; 插入算法 向一个二叉排序树b中插入一个结点s的算法,过程为: 若b是空树,则将s所指结点作为根结点插入,否则: 若s->data等于b的根结点的数据域之值,则返回,否则: 若s->data小于b的根结点的数据域之值,则把s所指结点插入到左子树中,否则:把s所指结点插入到右子树中。二叉排序树的建立及遍历的实现
二叉树的建立,查找,删除,遍历
二叉树查找
平衡二叉树(AVL)的查找、插入和删除
实现二叉排序树的各种算法
数据结构课程设计二叉树遍历查找
数据结构课程设计---二叉排序树和平衡二叉树的判别
最优二叉查找树
二叉树的各种算法
简单二叉树的创建,删除,查找
各类型二叉树例题说明
实验报告 实验三 二叉排序树的建立和查找
数据结构 课程设计 排序二叉树
二叉树查找-二分法查找二叉树
二叉排序树
二叉树排序算法
二叉搜索树