二叉树通讯录

合集下载

二叉树的基本操作

二叉树的基本操作

二叉树的基本操作二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。

二叉树在计算机领域中得到广泛应用,它的基本操作包括插入、删除、查找、遍历等。

1.插入操作:二叉树的插入操作是将一个新的节点添加到已有的二叉树中的过程。

插入操作会按照一定规则将新节点放置在正确的位置上。

插入操作的具体步骤如下:-首先,从根节点开始,比较新节点的值与当前节点的值的大小关系。

-如果新节点的值小于当前节点的值,则将新节点插入到当前节点的左子树中。

-如果新节点的值大于当前节点的值,则将新节点插入到当前节点的右子树中。

-如果当前节点的左子树或右子树为空,则直接将新节点插入到该位置上。

-如果当前节点的左子树和右子树都不为空,则递归地对左子树或右子树进行插入操作。

2.删除操作:二叉树的删除操作是将指定节点从二叉树中删除的过程。

删除操作有以下几种情况需要考虑:-如果待删除节点是叶子节点,则直接将其从二叉树中删除即可。

-如果待删除节点只有一个子节点,则将其子节点替换为待删除节点的位置即可。

-如果待删除节点有两个子节点,则需要找到其左子树或右子树中的最大节点或最小节点,将其值替换为待删除节点的值,然后再删除最大节点或最小节点。

3.查找操作:二叉树的查找操作是在二叉树中查找指定值的节点的过程。

查找操作的具体步骤如下:-从根节点开始,将待查找值与当前节点的值进行比较。

-如果待查找值等于当前节点的值,则返回该节点。

-如果待查找值小于当前节点的值,则在当前节点的左子树中继续查找。

-如果待查找值大于当前节点的值,则在当前节点的右子树中继续查找。

-如果左子树或右子树为空,则说明在二叉树中找不到该值。

4.遍历操作:二叉树的遍历操作是按照一定规则依次访问二叉树中的每个节点。

有三种常用的遍历方式:- 前序遍历(Preorder Traversal):先访问根节点,然后递归地前序遍历左子树和右子树。

- 中序遍历(Inorder Traversal):先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。

二叉树的建立与基本操作

二叉树的建立与基本操作

二叉树的建立与基本操作二叉树是一种特殊的树形结构,它由节点(node)组成,每个节点最多有两个子节点。

二叉树的基本操作包括建立二叉树、遍历二叉树、查找二叉树节点、插入和删除节点等。

本文将详细介绍二叉树的建立和基本操作,并给出相应的代码示例。

一、建立二叉树建立二叉树有多种方法,包括使用数组、链表和前序、中序、后序遍历等。

下面以使用链表的方式来建立二叉树为例。

1.定义二叉树节点类首先,定义一个二叉树节点的类,包含节点值、左子节点和右子节点三个属性。

```pythonclass Node:def __init__(self, value):self.value = valueself.left = Noneself.right = None```2.建立二叉树使用递归的方法来建立二叉树,先构造根节点,然后递归地构造左子树和右子树。

```pythondef build_binary_tree(lst):if not lst: # 如果 lst 为空,则返回 Nonereturn Nonemid = len(lst) // 2 # 取 lst 的中间元素作为根节点的值root = Node(lst[mid])root.left = build_binary_tree(lst[:mid]) # 递归构造左子树root.right = build_binary_tree(lst[mid+1:]) # 递归构造右子树return root```下面是建立二叉树的示例代码:```pythonlst = [1, 2, 3, 4, 5, 6, 7]root = build_binary_tree(lst)```二、遍历二叉树遍历二叉树是指按照其中一规则访问二叉树的所有节点,常见的遍历方式有前序遍历、中序遍历和后序遍历。

1.前序遍历前序遍历是指先访问根节点,然后访问左子节点,最后访问右子节点。

```pythondef pre_order_traversal(root):if root:print(root.value) # 先访问根节点pre_order_traversal(root.left) # 递归访问左子树pre_order_traversal(root.right) # 递归访问右子树```2.中序遍历中序遍历是指先访问左子节点,然后访问根节点,最后访问右子节点。

完全二叉树概念

完全二叉树概念

完全二叉树概念
完全二叉树是一种特殊的二叉树结构,它在很多算法和数据结构中都有广泛应用。

它的特点是:除了最后一层之外,其他层的节点数目都达到最大值,并且最后一层的节点都集中在左边。

对于一棵完全二叉树,从根节点到倒数第二层,每一层都是满的。

也就是说,倒数第二层的节点数为2^(h-1),其中h是树的高度。

最后一层的节点数可能不满,但是节点都靠左对齐。

这意味着,最后一层的节点按从左到右的顺序插入树中。

完全二叉树的定义可以用一个数组来表示。

对于一个节点的索引i,它的左子节点的索引为2i,右子节点的索引为2i+1。

反过来,对于一个节点的索引i,它的父节点的索引为i/2(整除)。

完全二叉树具有一些特殊的性质,这使得它在某些场景下非常有用。

例如,它可以被用作堆数据结构的底层实现。

堆是一种特殊的树结构,能够高效地找到最大或最小元素。

完全二叉树的性质使得堆的操作效率得到提升。

此外,在某些情况下,完全二叉树可以通过数组来表示,而不需要使用指针或其他数据结构。

这样做可以节省内存空间,并且提高数据的访问效率。

完全二叉树的应用非常广泛。

除了堆之外,它还被用于优先队列、哈夫曼树、二叉搜索树等。

它的特殊性质使得在这些应用中能够快速定位和操作节点,提高算法的效率。

总结起来,完全二叉树是一种具有特殊性质的二叉树结构。

它的节点在树中的位置有一定的规律,使得它在很多算法和数据结构中都有重要的应用。

了解完全二叉树的概念和性质,可以帮助我们更好地理解和设计相关的算法和数据结构。

二叉树基本操作经典实例

二叉树基本操作经典实例

二叉树基本操作经典实例二叉树是一种常见的数据结构,它由节点和指向左右子节点的指针组成。

二叉树的基本操作包括插入节点、删除节点、查找节点和遍历节点等。

在实际应用中,我们经常需要对二叉树进行基本操作,下面将介绍一些经典的例子。

一、插入节点插入节点是指向二叉树中添加一个新的节点。

在二叉树中插入节点的基本操作可以使用递归或者迭代的方法来实现。

下面是一个使用递归方法的示例代码:```public class TreeNodeint val;TreeNode left;TreeNode right;TreeNode(int x) { val = x; }public TreeNode insertNode(TreeNode root, int val)if (root == null)return new TreeNode(val);}if (val < root.val)root.left = insertNode(root.left, val);} else if (val > root.val)root.right = insertNode(root.right, val);}return root;```在上述代码中,通过递归的方式判断要插入的值和当前节点的大小关系,并将值插入到左子树或者右子树中,最后返回根节点。

二、删除节点删除节点是从二叉树中移除一个节点。

删除节点的基本操作可以分为三种情况:删除叶子节点、删除只有一个子节点的节点和删除有两个子节点的节点。

(1)删除叶子节点:如果要删除的节点是叶子节点,直接将该节点的父节点的指针指向空即可。

(2)删除只有一个子节点的节点:如果要删除的节点只有一个子节点,将该节点的子节点连接到该节点的父节点即可。

(3)删除有两个子节点的节点:如果要删除的节点有两个子节点,可以使用该节点右子树中的最小节点或者左子树中的最大节点来替代。

下面是一个使用递归方法的示例代码:```public TreeNode deleteNode(TreeNode root, int key) if (root == null)return root;}if (key < root.val)root.left = deleteNode(root.left, key);} else if (key > root.val)root.right = deleteNode(root.right, key);} elseif (root.left == null)return root.right;} else if (root.right == null)return root.left;}TreeNode minNode = findMin(root.right);root.val = minNode.val;root.right = deleteNode(root.right, minNode.val); }return root;private TreeNode findMin(TreeNode node)while (node.left != null)node = node.left;}return node;```在上述代码中,通过递归的方式判断要删除的值和当前节点的大小关系,并根据不同情况进行处理。

二叉树的储存结构的实现及应用

二叉树的储存结构的实现及应用

二叉树的储存结构的实现及应用二叉树是一种常见的数据结构,它在计算机科学和算法设计中广泛应用。

二叉树的储存结构有多种实现方式,包括顺序储存结构和链式储存结构。

本文将从这两种储存结构的实现和应用角度进行详细介绍,以便读者更好地理解二叉树的储存结构及其在实际应用中的作用。

一、顺序储存结构的实现及应用顺序储存结构是将二叉树的节点按照从上到下、从左到右的顺序依次存储在一维数组中。

通常采用数组来实现顺序储存结构,数组的下标和节点的位置之间存在一定的对应关系,通过数学计算可以快速找到节点的父节点、左孩子和右孩子。

顺序储存结构的实现相对简单,利用数组的特性可以迅速随机访问节点,适用于完全二叉树。

1.1 实现过程在采用顺序储存结构的实现中,需要首先确定二叉树的深度,然后根据深度确定数组的长度。

通过数学计算可以得到节点间的位置关系,初始化数组并按照规定的顺序将二叉树节点逐一填入数组中。

在访问二叉树节点时,可以通过计算得到节点的父节点和子节点的位置,从而实现随机访问。

1.2 应用场景顺序储存结构适用于完全二叉树的储存和遍历,常见的应用场景包括二叉堆和哈夫曼树。

二叉堆是一种特殊的二叉树,顺序储存结构可以方便地实现它的插入、删除和调整操作,因此在堆排序、优先队列等算法中得到广泛应用。

哈夫曼树则是数据压缩领域的重要应用,通过顺序储存结构可以有效地构建和处理哈夫曼树,实现压缩编码和解码操作。

二、链式储存结构的实现及应用链式储存结构是通过指针将二叉树的节点连接起来,形成一个类似链表的结构。

每个节点包含数据域和指针域,指针域指向节点的左右孩子节点。

链式储存结构的实现相对灵活,适用于任意形态的二叉树,但需要额外的指针空间来存储节点的地址信息。

2.1 实现过程在链式储存结构的实现中,每个节点需要定义为一个包含数据域和指针域的结构体或类。

通过指针来连接各个节点,形成一个二叉树的结构。

在树的遍历和操作中,可以通过指针的操作来实现节点的访问和处理,具有较高的灵活性和可扩展性。

二叉树的5种基本形态。 -回复

二叉树的5种基本形态。 -回复

二叉树的5种基本形态。

-回复二叉树是计算机科学中常用的数据结构之一,它由一个根节点和两个子节点组成,每个节点最多有两个子节点。

在这篇文章中,我们将探讨二叉树的五种基本形态。

一、满二叉树(full binary tree):满二叉树是一种特殊的二叉树,其中每个节点都有零个或两个子节点。

换句话说,满二叉树的每个内部节点都是一个分支节点。

满二叉树的特征是每一层的节点数量都是满的,最底层的节点与高度呈指数关系。

例如,一个满二叉树的高度为3,那么它有7个节点。

满二叉树的特点使得它在存储和搜索方面具有很高的效率。

然而,满二叉树的缺点是它需要较多的存储空间,并且在删除和插入节点时可能需要进行大量的重新排序。

二、完全二叉树(complete binary tree):完全二叉树是一种二叉树,其中除了最后一层外,每一层的节点都是满的,并且最后一层的节点从左到右连续排列。

换句话说,完全二叉树是一颗填满节点的树,只有最后一层的节点位置可以是不完全的,但是它们仍然从左到右排列。

完全二叉树的特点是它可以使用数组来表示,这样节省了存储空间。

此外,在完全二叉树中,插入和删除节点的操作也非常高效。

但是,相对于满二叉树,完全二叉树的节点数可能较少,并且在搜索方面的效率稍低。

三、平衡二叉树(balanced binary tree):平衡二叉树是一种特殊的二叉树,其中每个节点的左子树和右子树高度之差不超过1。

换句话说,平衡二叉树的高度在对数范围内增长。

平衡二叉树的特点是它保持了二叉搜索树的有序性,并且在插入和删除操作时能够自动调整以保持平衡。

这使得在平衡二叉树中搜索和插入节点时的时间复杂度保持在O(log n)级别。

但是,这种平衡性的维护也增加了操作的复杂性和内存需求。

四、搜索二叉树(binary search tree):搜索二叉树,也称为二叉查找树,是一种有序的二叉树。

在搜索二叉树中,所有左子树的值都小于父节点的值,而所有右子树的值都大于父节点的值。

通讯录的制作数据结构课程设计

通讯录的制作数据结构课程设计

通讯录的制作数据结构课程设计一、引言随着互联网和移动设备的普及,通讯录的重要性日益凸显。

通讯录不仅是一个人与人之间联系的桥梁,也是个人和组织之间沟通的纽带。

在数据结构课程设计中,我们将探讨如何制作一个高效、易用且具备良好扩展性的通讯录。

二、通讯录的需求分析在设计通讯录时,我们需要考虑以下需求: 1. 支持添加、删除、修改联系人信息的功能; 2. 支持按姓名、电话号码等属性进行搜索的功能; 3. 支持导入、导出通讯录的功能; 4. 支持多用户共享的功能; 5. 支持通讯录的快速访问和响应;6. 支持对联系人信息进行分类和标记的功能。

三、通讯录的数据结构设计为了满足上述需求,我们需要设计一个合适的数据结构来存储通讯录信息。

一种常见的数据结构是哈希表(Hash Table)。

哈希表可以通过将联系人的属性(如姓名、电话号码)进行哈希运算,将其转换为一个唯一的索引,从而实现快速的插入、搜索和删除操作。

3.1 哈希函数的选择在设计哈希表时,选择合适的哈希函数十分关键。

一个好的哈希函数应具备以下特点: - 均匀性:能够将联系人的属性均匀地映射到哈希表的槽位上,避免出现冲突; - 快速性:计算哈希值的过程应尽量简单、高效; - 低冲突率:尽可能避免多个联系人映射到同一个槽位的情况。

3.2 哈希表的实现我们可以使用数组来表示哈希表的槽位,每个槽位存储一个链表。

链表的节点包含联系人的信息。

当发生冲突时,我们可以使用链表来解决。

3.3 哈希表的性能分析哈希表在理想情况下可以达到常数级的时间复杂度,但在最坏情况下可能会退化为线性时间复杂度。

为了降低冲突率,我们可以使用一些解决冲突的技术,如链地址法、开放地址法等。

四、通讯录的功能实现在通讯录中,我们需要实现添加、删除、修改联系人信息的功能,以及按属性进行搜索等功能。

4.1 添加联系人当用户需要添加一个联系人时,我们首先需要计算联系人的哈希值,并找到对应的槽位。

然后将联系人的信息插入到链表的头部。

二叉树在多种通信组网下的应用

二叉树在多种通信组网下的应用
维普资讯
Hale Waihona Puke 第3 卷 第 l 期 2 O
、 t 2 , . 0 _3






20 0 6年 5月
M a 0 6 y2 0
№ l o
Co p t rEn i e rn m u e gn e ig
网络与i信 ・ 匝
文 ■号 0卜 3 8 I )_0 9 o 章 I 0 _ 22I1_ l — 4 文 标 码: 1 l 4 (I 0 1 I _ 6 越 识 A
中 分 号 T3 . 圈 类 : P11 12
二 叉树在 多种 通信 组 网下的应 用
余新胜,戎之玮
( 计算技术研 究所,上海 2 0 3 ) 华东 023

要: 通过对一个基本的 网络 互联模型进行分析 , 出多种通信 方式纰 刚下应用系统 的 种解决 方案 :将通信 刚络从逻辑 上抽象 成为多 ’ 得
YU n h n , Xi s e g RONG i i Zh we ( at hn nt ueo o u e e h oo y S a g a 2 0 3 ) E s C iaI s tt f mp tr c n lg , h n h i 0 2 3 i C T
[ b t c]A e aa z g n n r n et n o e o b s e ok a ou o f p l a o s m u dr ut o u i t n e ok a A s at f r n l i t c nc o d l f i nt r, l i o pi t n yt e l— mm n ao t r cn r t y n aieo i m aac w s tn a c i s e n m i c ci nw
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <stdio.h>#include <string.h>#include <conio.h>#include <stdlib.h>#include <windows.h>#define MaxSize 100FILE *fp;//有关结点个数的定义typedef struct{int nodenum;}num;num *node=new num;//有关结点个数的函数void savenodeBSTree(num *n);//保存树结点void dispnodeBSTree(num *n,int &m);//提取结点个数void savenodeBSTree(num *n)//保存树结点{int i;if((fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\nodenum.txt","wb"))==NULL){printf("cannot open file\n");return;}for(i=0;i<1;i++)if(fwrite(&n[i],sizeof(num),1,fp)!=1)printf("file write error\n");fclose(fp);}void dispnodeBSTree(num *n,int &m)//提取结点个数{int i;fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\nodenum.txt","rb");if(!fp){printf("cannot open file\n");exit(0);}for(i=0;i<1;i++){fread(&n[i],sizeof(num),1,fp);m=n[i].nodenum;}fclose(fp);}//数据类型的定义typedef struct{char Name[22];//姓名char Tel[11];//固定电话char Portable[11];//移动电话char Add[22];//住址char Birth[11];//生日}TElemType;TElemType *telbook=(TElemType *)malloc(MaxSize*sizeof(TElemType));//二叉平衡树数据类型的定义typedef struct BSTNode{TElemType data;int bf;//平衡因子BSTNode *lch,*rch;}*BSTree;//有关栈定义typedef struct{int top;BSTree *tree;int stacksize;}stack;//有关栈的一组操作void initstack(stack &s,int n);//初始化栈void pop(stack &s,BSTree &q);//出栈void push(stack &s,BSTree q);//进栈void gettop(stack s,BSTree &q);//得到栈顶int emptystack(stack s);//判断栈空与否void travlstack(stack s);//遍历栈void initstack(stack &s,int n){s.top=-1;s.stacksize=MaxSize;s.tree=new BSTree;}void pop(stack &s,BSTree &q){if(s.top==-1)return;q=s.tree[s.top--];}void push(stack &s,BSTree q){if(s.top+1==s.stacksize)return;s.tree[++s.top]=q;}void gettop(stack s,BSTree &q){if(s.top==-1)q=NULL;elseq=s.tree[s.top];}int emptystack(stack s){if(s.top==-1)return 1;elsereturn 0;}void travlstack(stack s){int i;for(i=0;i<=s.top;i++)printf("%s\n",s.tree[i]->data.Portable); }//二叉平衡树相关函数的定义int depthBSTree(BSTree T);//计算二叉平衡树的深度void LLprocess(BSTree &T);//LL型调节void RRprocess(BSTree &T);//RR型调节void RLprocess(BSTree &T);//RL型调节void LRprocess(BSTree &T);//LR型调节void jsbf(BSTree &T);//计算平衡因子int judge(BSTree T);//判断应进行哪种调节void Link(BSTree &q,BSTree s,BSTree &T,BSTree p);//最小不平衡子树与原树的连接int insertBSTree(BSTree &T,TElemType e);//插入int searchBSTree(BSTree T,char kval[11],BSTree &f,BSTree &p);//按移动电话查找void path(BSTree T,BSTree p,stack &s);//求根到p的一个路径void process(BSTree &T,BSTree p,stack s);//插入或者删除后进行的调节void creatBSTree(BSTree &T,int n,TElemType *telbook);//创建二叉平衡树void TravLevel(BSTree T,TElemType *telbook,int &i);//层次遍历二叉平衡树int DeletBST(BSTree &p,char kval[11],BSTree &T);//删除结点void Delete(BSTree &p,BSTree &T);//删除结点void menu();//菜单void saveBSTree(TElemType *e,int n);//保存void dispfileBSTree(TElemType *telbook,int n);//显示文件中信息void TravLevel2BSTree(BSTree T);//层次遍历二叉平衡树void filecreatBSTree(BSTree &T,TElemType *telbook,int n);//从文件中调入数据创建void AVLTree();//二叉平衡树整套算法函数void jsnodenumBSTree(BSTree T,int &n);//计算结点个数void jsSSASLBSTree(BSTree T,int &asl,TElemType *telbook,int n);//计算查找成功时的ASLvoid jsUNASLBSTree(BSTree T,int &asl,TElemType *telbook,int n);//计算查找不成功时的ASLint nodelevelBSTree(BSTree T,char kval[11],int &level);//计算结点所在层数int searchBSTreebyName(BSTree T,char kval[22],BSTree &f,BSTree &p);//按名字查找int searchBSTreebyTel(BSTree T,char kval[11],BSTree &f,BSTree &p);//按固定电话查找int searchBSTreebyBirth(BSTree T,char kval[],BSTree &f,BSTree &p);//按生日查找int searchBSTreebyBirth(BSTree T,char kval[],BSTree &f,BSTree &p)//按生日查找{//no found successfullyif(!T){// printf("Birth\n");p=f;return 0;}else if(strcmp(kval,T->data.Birth)==0) //found successfully{// printf("Birth\n");p=T;return 1;}else if(strcmp(kval,T->data.Birth)<0) //continue to find his lch; {f=T;return searchBSTree(T->lch,kval,T,p);}else //continue to find his rch{f=T;return searchBSTree(T->rch,kval,T,p);}}int searchBSTreebyTel(BSTree T,char kval[11],BSTree &f,BSTree &p)//按固定电话查找{//no found successfullyif(!T){// printf("Tel\n");p=f;return 0;}else if(strcmp(kval,T->data.Tel)==0) //found successfully{// printf("Tel\n");p=T;return 1;}else if(strcmp(kval,T->data.Tel)<0) //continue to find his lch; {f=T;return searchBSTree(T->lch,kval,T,p);}else //continue to find his rch{f=T;return searchBSTree(T->rch,kval,T,p);}}int searchBSTreebyName(BSTree T,char kval[22],BSTree &f,BSTree &p)//按名字查找{//no found successfullyif(!T){// printf("Name\n");p=f;return 0;}else if(strcmp(kval,T->)==0) //found successfully{// printf("Name\n");p=T;return 1;}else if(strcmp(kval,T->)<0) //continue to find his lch; {f=T;return searchBSTree(T->lch,kval,T,p);}else //continue to find his rch{f=T;return searchBSTree(T->rch,kval,T,p);}}int depthBSTree(BSTree T)//计算二叉平衡树的深度{int hl,hr;if(!T) return 0;else{hl=depthBSTree(T->lch);hr=depthBSTree(T->rch);return hl>hr?(hl+1):(hr+1);}}void LRprocess(BSTree &T)//LR型调节{BSTree p1,p2;p1=T->lch;p2=p1->rch;p1->rch=p2->lch;p2->lch=p1;T->lch=p2->rch;p2->rch=T;T=p2;}void RLprocess(BSTree &T)//RL型调节{BSTree p1,p2;p1=T->rch;p2=p1->lch;p1->lch=p2->rch;p2->rch=p1;T->rch=p2->lch;p2->lch=T;T=p2;}void RRprocess(BSTree &T)//RR型调节{BSTree p;p=T->rch;T->rch=p->lch;p->lch=T;T=p;}void LLprocess(BSTree &T)//LL型调节{BSTree p;p=T->lch;T->lch=p->rch;p->rch=T;T=p;}void jsbf(BSTree &T)//计算平衡因子{int hl,hr;hl=depthBSTree(T->lch);hr=depthBSTree(T->rch);T->bf=hl-hr;}int judge(BSTree T)//判断进行哪种调节{if(T->bf==2&&T->lch->bf==1)return 1;//LL型if(T->bf==-2&&T->rch->bf==-1)return 2;//RR型if(T->bf==2&&T->lch->bf==-1)return 3;//LR型if(T->bf==-2&&T->rch->bf==1)return 4;//RL型}void Link(BSTree &q,BSTree s,BSTree &T,BSTree p)//最小不平衡子树和原树的连接{if(q&&strcmp(q->lch->data.Portable,s->data.Portable)==0)q->lch=p;else if(q&&strcmp(q->rch->data.Portable,s->data.Portable)==0)q->rch=p;else T=p;}int searchBSTree(BSTree T,char kval[11],BSTree &f,BSTree &p)//按移动电话查找{//no found successfullyif(!T){p=f;return 0;}else if(strcmp(kval,T->data.Portable)==0) //found successfully {p=T;return 1;}else if(strcmp(kval,T->data.Portable)<0) //continue to find his lch;{f=T;return searchBSTree(T->lch,kval,T,p);}else //continue to find his rch{f=T;return searchBSTree(T->rch,kval,T,p);}}void path(BSTree T,BSTree p,stack &s)//求根到p的一个路径{if(!T) return;else{if(strcmp(T->data.Portable,p->data.Portable)==0){push(s,T);return;}else if(strcmp(T->data.Portable,p->data.Portable)<0) {push(s,T);path(T->rch,p,s);}else{push(s,T);path(T->lch,p,s);}}}int insertBSTree(BSTree &T,TElemType e){BSTree p,f=NULL;BSTree s;stack st;initstack(st,MaxSize);int i=searchBSTree(T,e.Portable,f,p);if(!i){//give new node a new space;s=new BSTNode;s->data=e;s->lch=s->rch=NULL;if(!p){T=s;}//if it is root node;else if(strcmp(e.Portable,p->data.Portable)<0)p->lch=s;else p->rch=s;// TravLevel(T);process(T,s,st);return 1;}else return 0; //no insert successfully}void process(BSTree &T,BSTree p,stack s)//插入或者删除后进行的调节{BSTree ch,fa,q;int i;path(T,p,s);// travlstack(s);// printf("!!!!\n");while(!emptystack(s)){pop(s,ch);gettop(s,fa);jsbf(ch);if(ch->bf!=1||ch->bf!=-1||ch->bf!=0){i=judge(ch);switch(i){case 1:q=ch;LLprocess(ch);Link(fa,q,T,ch);break;case 2:q=ch;RRprocess(ch);Link(fa,q,T,ch);break;case 3:q=ch;LRprocess(ch);Link(fa,q,T,ch);break;case 4:q=ch;RLprocess(ch);Link(fa,q,T,ch);break;}}//if}//wile}void creatBSTree(BSTree &T,int n,TElemType *telbook)//创建二叉平衡树{ int i;for(i=0;i<n;i++){printf("请输入第%d个人的名字,固定电话,移动电话,地址,生辰\n",i+1); scanf("%s %s %s %s%s",telbook[i].Name,telbook[i].Tel,telbook[i].Portable,telbook[i].Add ,telbook[i].Birth);getchar();insertBSTree(T,telbook[i]);}}void TravLevelBSTree(BSTree T,TElemType *telbook,int &i)//层次遍历二叉平衡树{BSTree Qu[MaxSize],b;int front,rear;front=rear=0;if(T!=NULL)telbook[i++]=T->data;Qu[rear]=T;rear=(rear+1)%MaxSize;while(front!=rear){b=Qu[front];front=(front+1)%MaxSize;if(b->lch){telbook[i++]=b->lch->data;Qu[rear]=b->lch;rear=(rear+1)%MaxSize;}if(b->rch){telbook[i++]=b->rch->data;Qu[rear]=b->rch;rear=(rear+1)%MaxSize;}}}int DeletBST(BSTree &p,char kval[11],BSTree &T)//删除结点{if(!p) {printf("没有该电话,无法删除\n");return 0;} else if(strcmp(kval,p->data.Portable)==0){// printf("====\n");Delete(p,T);// printf("!!!!\n");return 1;}else if(strcmp(kval,p->data.Portable)<0){// printf("<<<<\n");return DeletBST(p->lch,kval,T);}else{// printf(">>>>\n");return DeletBST(p->rch,kval,T);}}void Delete(BSTree &p,BSTree &T)//删除结点{BSTree q,s,fa=NULL;stack st;initstack(st,MaxSize);if(!p->rch){q = p;p = q->lch;process(T,q,st);// printf("!!!!\n");// TravLevel2(T);// free(q);}else if(!p->lch){q=p;p=q->rch;process(T,q,st);// free(q);}else{q=p;s=p->lch;while(s->rch){q=s;s=s->rch;}p->data=s->data;if(q==p) //左子树是单支树q->lch=s->lch;else // 重接*s的左子树q->rch=s->lch;// printf("!!!!\n");process(T,s,st);// printf("!!!!\n");// free(s);// printf("!!!!\n");}}void menu(){printf("************欢迎使用电话管理系统************\n\n");printf(" 1、创建 2、插入 3、删除\n");printf(" 4、查找 5、显示 6、保存\n");printf(" 7、计算ASL 8、退出\n");printf("********************************************\n\n");}void saveBSTree(TElemType *e,int n)//保存{int i;if((fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\电话簿——平衡树.txt","wb"))==NULL){printf("cannot open file\n");return;}for(i=0;i<n;i++)if(fwrite(&e[i],sizeof(TElemType),1,fp)!=1)printf("file write error\n");fclose(fp);}void dispfileBSTree(TElemType *telbook,int n)//显示文件中信息{int i;fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\电话簿——平衡树.txt","rb");if(!fp){printf("cannot open file\n");exit(0);}for(i=0;i<n;i++){fread(&telbook[i],sizeof(TElemType),1,fp);printf("姓名:%s 固定电话:%s 移动电话:%s 地址:%s 生日:%s\n",telbook[i].Name,telbook[i].Tel,telbook[i].Portable,telbook[i].A dd,telbook[i].Birth);}fclose(fp);}void TravLevel2(BSTree T)//层次遍历二叉平衡树{BSTree Qu[MaxSize],b;int front,rear;front=rear=0;if(T!=NULL)printf("%s\n",T->data.Portable);Qu[rear]=T;rear=(rear+1)%MaxSize;while(front!=rear){b=Qu[front];front=(front+1)%MaxSize;if(b->lch){printf("%s\n",b->lch->data.Portable);Qu[rear]=b->lch;rear=(rear+1)%MaxSize;}if(b->rch){printf("%s\n",b->rch->data.Portable);Qu[rear]=b->rch;rear=(rear+1)%MaxSize;}}}void filecreatBSTree(BSTree &T,TElemType *telbook,int n)//从文件中调入数据创建{fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\电话簿——平衡树.txt","rb");if(!fp){printf("cannot open file\n");exit(0);}for(i=0;i<n;i++){fread(&telbook[i],sizeof(TElemType),1,fp);insertBSTree(T,telbook[i]);}}void jsnodenumBSTree(BSTree T,int &n)//计算结点个数{if(!T) return;else{jsnodenumBSTree(T->lch,n);n++;jsnodenumBSTree(T->rch,n);}}void jsSSASLBSTree(BSTree T,int &asl,TElemType *telbook,int n)//计算查找成功时的ASL{int i;int level=1;for(i=0;i<n;i++){level=1;nodelevelBSTree(T,telbook[i].Portable,level);asl=asl+level;}}void jsUNASLBSTree(BSTree T,int &asl,TElemType *telbook,int n)//计算查找不成功时的ASL{int i;BSTree f=NULL,p;int level;for(i=0;i<n;i++){searchBSTree(T,telbook[i].Portable,f,p);if(!p->lch){level=1;nodelevelBSTree(T,telbook[i].Portable,level);asl=asl+level;}if(!p->rch){level=1;nodelevelBSTree(T,telbook[i].Portable,level);asl=asl+level;}}}int nodelevelBSTree(BSTree T,char kval[11],int &level)//计算结点所在层数{if(!T) return level;else if(strcmp(T->data.Portable,kval)==0){// printf("====\n");return level;}else if(strcmp(T->data.Portable,kval)<0)nodelevelBSTree(T->rch,kval,++level);elsenodelevelBSTree(T->lch,kval,++level);}void AVLTree()//二叉平衡树整套算法函数{int choice,n,m,asl=0;TElemType e;BSTree T=NULL,q,f=NULL,p;char ch;while(1){system("cls");printf("您现在使用的是二叉平衡树\n");menu();printf("请输入选项1--6:");scanf("%d",&choice);getchar();switch(choice){case 1:printf("请输入首次创建的个数:");scanf("%d",&n);getchar();creatBSTree(T,n,telbook);break;case 2:ch='y';T=NULL;dispnodeBSTree(node,m);filecreatBSTree(T,telbook,m);while(ch=='y'||ch=='Y'){printf("请输入要插入的信息\n");printf("姓名:");scanf("%s",);getchar();printf("固定电话:");scanf("%s",e.Tel);getchar();printf("移动电话");scanf("%s",e.Portable);getchar();printf("住址:");scanf("%s",e.Add);getchar();printf("生日:");scanf("%s",e.Birth);getchar();insertBSTree(T,e);printf("是否继续插入?是=y,否=n:");scanf("%c",&ch);getchar(); }break;case 3:ch='y';T=NULL;dispnodeBSTree(node,m);filecreatBSTree(T,telbook,m);while(ch=='y'||ch=='Y'){printf("请输入要删除的移动电话:");scanf("%s",e.Portable);getchar();DeletBST(T,e.Portable,T);printf("是否继续删除?是=y,否=n:");scanf("%c",&ch);getchar(); }break;case 4:ch='y';T=NULL;dispnodeBSTree(node,m);filecreatBSTree(T,telbook,m);while(ch=='y'||ch=='Y'){f=NULL;system("cls");printf("\n===========================\n");printf("1、按名字 2、按生日\n");printf("3、按固定电话 4、按移动电话\n"); printf("===========================\n"); printf("请输入查找的方式:");scanf("%d",&choice);getchar();switch(choice){case 1:printf("请输入要查找的姓名:");scanf("%s",);getchar();if(searchBSTreebyName(T,,f,p)){printf("姓名:%s\n",p->);printf("移动电话:%s\n",p->data.Portable); printf("固定电话:%s\n",p->data.Tel);printf("地址:%s\n",p->data.Add);printf("生日:%s\n",p->data.Birth);}else printf("没有该信息\n");break;case 2:printf("请输入要查找的生日:");scanf("%s",e.Birth);getchar();if(searchBSTreebyBirth(T,e.Birth,f,p)){printf("姓名:%s\n",p->);printf("移动电话:%s\n",p->data.Portable); printf("固定电话:%s\n",p->data.Tel);printf("地址:%s\n",p->data.Add);printf("生日:%s\n",p->data.Birth);}else printf("没有该信息\n");break;case 3:printf("请输入要查找的固定电话:");scanf("%s",e.Tel);getchar();if(searchBSTreebyTel(T,e.Tel,f,p)){printf("姓名:%s\n",p->);printf("移动电话:%s\n",p->data.Portable); printf("固定电话:%s\n",p->data.Tel);printf("地址:%s\n",p->data.Add);printf("生日:%s\n",p->data.Birth);}else printf("没有该信息\n");break;case 4:printf("请输入要查找的移动电话:");scanf("%s",e.Portable);getchar();if(searchBSTree(T,e.Portable,f,p)){printf("姓名:%s\n",p->);printf("移动电话:%s\n",p->data.Portable);printf("固定电话:%s\n",p->data.Tel);printf("地址:%s\n",p->data.Add);printf("生日:%s\n",p->data.Birth);}else printf("没有该信息\n");break;}//switchprintf("是否继续查找?是=y,否=n:");scanf("%c",&ch);getchar();}break;case 5:dispnodeBSTree(node,m);dispfileBSTree(telbook,m);break;case 6:m=0;TravLevelBSTree(T,telbook,m);node[0].nodenum=m;savenodeBSTree(node);saveBSTree(telbook,m);break;case 7:n=0;T=NULL;dispnodeBSTree(node,m);filecreatBSTree(T,telbook,m);jsnodenumBSTree(T,n);jsSSASLBSTree(T,asl,telbook,m);printf("查找成功的ASL=%.2f\n",(float)asl/n); asl=0;jsUNASLBSTree(T,asl,telbook,m);printf("查找不成功的ASL=%.2f\n",(float)asl/n);break;case 8:return;}//switchprintf("请按任意建继续");getchar();}//while}//有关结点个数的函数void savenodeBiTree(num *node);//保存树结点void dispnodeBiTree(num *node,int &m);//提取结点个数void savenodeBiTree(num *node)//保存树结点{int i;if((fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\nodenum2.txt","wb"))==NULL){printf("cannot open file\n");return;}for(i=0;i<1;i++)if(fwrite(&node[i],sizeof(num),1,fp)!=1)printf("file write error\n");fclose(fp);}void dispnodeBiTree(num *node,int &m)//提取结点个数{int i;fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\nodenum2.txt","rb");if(!fp){printf("cannot open file\n");exit(0);}for(i=0;i<1;i++){fread(&node[i],sizeof(num),1,fp);m=node[i].nodenum;}fclose(fp);}//关于二叉排序树的定义typedef struct BiTNode{TElemType data;BiTNode *lch,*rch;}*BiTree;//二叉排序树的相关函数int searchBiTree(BiTree T, char kval[11],BiTree f, BiTree &p);//二叉排序树的按移动电话的查找int insertBiTree(BiTree &T,TElemType e);//二叉排序树的插入void creatBiTree(BiTree &T,int n);//二叉排序树的创建void TravLevel2BiTree(BiTree T);//层次遍历二叉树void saveBiTree(TElemType *e,int n);//保存二叉排序树void dispfileBiTree(TElemType *telbook,int n);//显示文件中信息void TravLevelBiTree(BiTree T,TElemType *telbook,int &i);//层次遍历二叉排序树,将其保存在telbook中int DeleteBiTree (BiTree &T,char kval[11]);//删除二叉排序树的结点void Delete2 (BiTree &p);//删除排序树void jsSSASL(BiTree T,int &asl,TElemType *telbook,int n);//计算查找成功时的ASLint jsnodenum(BiTree T);//计算结点个数int nodelevel(BiTree T,char kval[11],int &level);//计算结点所在层数void BITree();//二叉排序树的所有相关算法函数int searchBiTreebyTel(BiTree T, char kval[11],BiTree f, BiTree &p);//二叉排序树的按固定电话电话的查找int searchBiTreebyBirth(BiTree T, char kval[11],BiTree f, BiTree &p);//二叉排序树的按生日的查找int searchBiTreebyName(BiTree T, char kval[11],BiTree f, BiTree &p);//二叉排序树的按名字的查找int searchBiTreebyName(BiTree T,char kval[11],BiTree f,BiTree &p)//二叉排序树的查找{//no found successfullyif(!T){p=f;return 0;}else if(strcmp(kval,T->)==0) //found successfully{p=T;return 1;}else if(strcmp(kval,T->)<0) //continue to find his lch; return searchBiTreebyName(T->lch,kval,T,p);else //continue to find his rchreturn searchBiTreebyName(T->rch,kval,T,p);}int searchBiTreebyBirth(BiTree T,char kval[11],BiTree f,BiTree &p)//二叉排序树的查找{//no found successfullyif(!T){p=f;return 0;}else if(strcmp(kval,T->data.Birth)==0) //found successfully{p=T;return 1;}else if(strcmp(kval,T->data.Birth)<0) //continue to find his lch; return searchBiTreebyBirth(T->lch,kval,T,p);else //continue to find his rchreturn searchBiTreebyBirth(T->rch,kval,T,p);}int searchBiTreebyTel(BiTree T,char kval[11],BiTree f,BiTree &p)//二叉排序树的查找{//no found successfullyif(!T){p=f;return 0;}else if(strcmp(kval,T->data.Tel)==0) //found successfully{p=T;return 1;}else if(strcmp(kval,T->data.Tel)<0) //continue to find his lch; return searchBiTreebyTel(T->lch,kval,T,p);else //continue to find his rchreturn searchBiTreebyTel(T->rch,kval,T,p);}int searchBiTree(BiTree T,char kval[11],BiTree f,BiTree &p)//二叉排序树的查找{//no found successfullyif(!T){p=f;return 0;}else if(strcmp(kval,T->data.Portable)==0) //found successfully{p=T;return 1;}else if(strcmp(kval,T->data.Portable)<0) //continue to find his lch;return searchBiTree(T->lch,kval,T,p);else //continue to find his rchreturn searchBiTree(T->rch,kval,T,p);}int insertBiTree(BiTree &T,TElemType e)//二叉排序树的插入{BiTree p;BiTree s;int i=searchBiTree(T,e.Portable,NULL,p);if(!i){//give new node a new space;s=new BiTNode;s->data=e;s->lch=s->rch=NULL;if(!p) T=s; //if it is root node;else if(strcmp(e.Portable,p->data.Portable)<0)p->lch=s;else p->rch=s;return 1;}else return 0; //no insert successfully}void creatBiTree(BiTree &T,int n)//二叉排序树的创建{int i;TElemType *e=(TElemType *)malloc(n*sizeof(TElemType));for(i=0;i<n;i++){printf("请输入第%d个人的名字,固定电话,移动电话,地址,生辰\n",i+1);scanf("%s %s %s %s%s",e[i].Name,e[i].Tel,e[i].Portable,e[i].Add,e[i].Birth);getchar();insertBiTree(T,e[i]);// TravLevel2BiTree(T);}}void TravLevel2BiTree(BiTree T)//层次遍历二叉树{BiTree Qu[MaxSize];BiTree b;int front,rear;front=rear=0;if(T!=NULL)printf("%s\n",T->data.Portable);Qu[rear]=T;rear=(rear+1)%MaxSize;while(front!=rear){b=Qu[front];front=(front+1)%MaxSize;if(b->lch){printf("%s\n",b->lch->data.Portable);Qu[rear]=b->lch;rear=(rear+1)%MaxSize;}if(b->rch){printf("%s\n",b->rch->data.Portable);Qu[rear]=b->rch;rear=(rear+1)%MaxSize;}}}void saveBiTree(TElemType *e,int n)//保存{int i;if((fp=fopen("E:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\电话簿——排序树.txt","wb"))==NULL){printf("cannot open file\n");return;}for(i=0;i<n;i++)if(fwrite(&e[i],sizeof(TElemType),1,fp)!=1)printf("file write error\n");fclose(fp);}void dispfileBiTree(TElemType *telbook,int n)//显示文件中信息{int i;fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\电话簿——排序树.txt","rb");if(!fp){printf("cannot open file\n");exit(0);}for(i=0;i<n;i++){fread(&telbook[i],sizeof(TElemType),1,fp);printf("姓名:%s 固定电话:%s 移动电话:%s 地址:%s 生日:%s\n",telbook[i].Name,telbook[i].Tel,telbook[i].Portable,telbook[i].A dd,telbook[i].Birth);}fclose(fp);}void TravLevelBiTree(BiTree T,TElemType *telbook,int &i)//层次遍历二叉排序树,将其保存在telbook中{BiTree Qu[MaxSize],b;int front,rear;front=rear=0;if(T!=NULL)telbook[i++]=T->data;Qu[rear]=T;rear=(rear+1)%MaxSize;while(front!=rear){b=Qu[front];front=(front+1)%MaxSize;if(b->lch){telbook[i++]=b->lch->data;Qu[rear]=b->lch;rear=(rear+1)%MaxSize;}if(b->rch){telbook[i++]=b->rch->data;Qu[rear]=b->rch;rear=(rear+1)%MaxSize;}}}int DeleteBiTree (BiTree &T,char kval[11])//删除二叉排序树的结点{if(T==NULL){printf("没有该信息,无法删除\n");return 0;}else if(strcmp(T->data.Portable,kval)==0){Delete2(T);return 1;}else if(strcmp(T->data.Portable,kval)<0){return DeleteBiTree(T->rch,kval);}else{return DeleteBiTree(T->lch,kval);}}void Delete2(BiTree &p)//删除排序树{BiTree q,s;if(!p->rch){q=p;p=q->lch;free(q);}else if(!p->lch){q=p;p=q->rch;free(q);}else{q=p;s=p->lch;while(s->rch){q=s;s=s->rch;}p->data=s->data;if(q==p) //左子树是单支树q->lch=s->lch;else // 重接*s的左子树q->rch=s->lch;free(s);}//else}void filecreatBiTree(BiTree &T,TElemType *telbook,int n)//从文件中调入数据创建{int i;fp=fopen("e:\\workplace\\MSDev98\\MyProjects\\电话簿管理系统\\电话簿——排序树.txt","rb");if(!fp){printf("cannot open file\n");exit(0);}for(i=0;i<n;i++){fread(&telbook[i],sizeof(TElemType),1,fp);// printf("telbook[i]=%s\n",telbook[i].Portable);insertBiTree(T,telbook[i]);}}void jsnodenum(BiTree T,int &n)//计算结点个数{if(!T) return;else{jsnodenum(T->lch,n);n++;jsnodenum(T->rch,n);}void jsSSASL(BiTree T,int &asl,TElemType *telbook,int n)//计算查找成功时的ASL{int i;int level=1;for(i=0;i<n;i++){level=1;nodelevel(T,telbook[i].Portable,level);asl=asl+level;}}void jsUNASL(BiTree T,int &asl,TElemType *telbook,int n)//计算查找不成功时的ASL{int i;BiTree f=NULL,p;int level;for(i=0;i<n;i++){f=NULL;searchBiTree(T,telbook[i].Portable,f,p);if(!p->lch){level=1;nodelevel(T,telbook[i].Portable,level);asl=asl+level;}if(!p->rch){level=1;nodelevel(T,telbook[i].Portable,level);asl=asl+level;}}}int nodelevel(BiTree T,char kval[11],int &level)//计算结点所在层数{if(!T) return level;else if(strcmp(T->data.Portable,kval)==0){// printf("====\n");return level;else if(strcmp(T->data.Portable,kval)<0)nodelevel(T->rch,kval,++level);elsenodelevel(T->lch,kval,++level);}void BITree()//二叉排序树的所有相关算法函数{BiTree T=NULL,f=NULL,p;TElemType e;BiTree *s=(BiTree *)malloc(MaxSize*sizeof(BiTree));int choice,n;int m=0,i=0,asl=0,top=-1;char ch;while(1){system("cls");printf("您现在使用的是二叉排序树\n");menu();printf("请输入选项1--6:");scanf("%d",&choice);getchar();switch(choice){case 1:printf("请输入首次创建的个数:");scanf("%d",&n);getchar();creatBiTree(T,n);break;case 2:ch='y';T=NULL;dispnodeBiTree(node,m);filecreatBiTree(T,telbook,m);while(ch=='y'||ch=='Y'){printf("请输入要插入的信息\n");printf("姓名:");scanf("%s",);getchar();printf("固定电话:");scanf("%s",e.Tel);getchar();printf("移动电话");scanf("%s",e.Portable);getchar();printf("住址:");scanf("%s",e.Add);getchar();printf("生日:");scanf("%s",e.Birth);getchar();insertBiTree(T,e);printf("是否继续插入?是=y,否=n:");scanf("%c",&ch);getchar(); }。

相关文档
最新文档