基于平衡二叉树的排序算法分析与设计

来源 :课程教育研究·新教师教学 | 被引量 : 0次 | 上传用户:June_misu
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要 :
  本文根据平衡二叉树的构造原理,提出了利用平衡二叉树进行内部排序的思想,据此完成了对应的算法设计,并通过典型实例进行验证和效率分析。
  关键词:平衡二叉树 内部排序
  Analysis and Design for Internal Sort Algorithm
  Based on AVL tree
  ZOU Yong-lin TANG Xiao-yang
  (school of computer science and engineering,
  Changshu Institute of Technology, 215500)
  Abstract
  According to the principle of AVL tree constructing, the ideal of sorting by using the AVL tree was developed and the algorithm was designed and implemented in this paper. Finally, the correctness and the efficiency for this algorithm were validated and analysed through the example.
  Keywords
  AVL tree, internal sort
  【中图分类号】G642
  1.引言
  在数据结构课程教学的理论和实践中,有关内部排序的常用方法,一般将它们分为五大类[1][2][3]:插入、交换、选择、归并和基数排序;并且,大多采用顺序表或链表(队)结构讨论各种算法的具体实现过程。
  实际上,并不是所有的内部排序算法都必须使用线性表对应的存储结构来描述。不妨换一种思路,二叉排序树(BST树)和平衡二叉树(AVL树)作为动态查找表结构,它们具有一个基本特点,就是进行中序遍历可以得到一个按结点关键字值递增有序的序列;并且对于平衡二叉树而言,进行一次中序遍历的过程,其时间复杂度为O(log2n)。因此,利用构造平衡二叉树的方法,同样可以实现对一个无序序列进行排序的目的。
  2.构造平衡二叉树的基本过程
  由平衡二叉树的原理可知,将一个无序序列构造成一棵平衡二叉树时,为了确保其平均查找长度与树的深度相当,在每次插入一个新结点时,需要判断是否失去平衡,从而决定是否需要进行平衡处理以及如何进行平衡处理。
  如果一棵平衡二叉树,由于插入一个新结点导致失去平衡,则重新恢复平衡的调整方法有4种,分别是:单向右旋、单向左旋、先左后右和先右后左。具体过程是:首先找到最小不平衡子树,根据其根的平衡因子的值和对应的形态,选择采用不同的方法来恢复其平衡性。
  3. 算法设计
  根据上述原理,可选择二叉链表存储结构,设计构造平衡二叉树的算法。为了实现待排序关键字中可能存在重复关键字的情形,可对平衡二叉树的定义稍作修改,允许在平衡二叉树中存在值相同的结点;同时,为了确保其稳定性,约定将后续的值相同的关键字以其右子树中的新结点插入。
  算法主要代码如下:
  #define LH 1 //左高
  #define EH 0 //等高
  #define RH -1 //右高
  #define Num 20
  #define true 1
  #define false 0
  int taller;
  typedef struct BSTnode //平衡二叉树的结点结构
  {
  int data; //关键字
  int bf; //平衡因子
  struct BSTnode *lc,*rc; //左右指针
  }BSTnode;
  int InsrtAVL(BSTnode *T,BSTnode *newNode,BSTnode **Tr,int taller)
  { //在平衡二叉树中插入一个新元素
  if (newNode->datadata) //在T的左子树中搜索插入
  {
  if (T->lc==NULL) //T的左子树为空树,直接插入
  {
  taller=true; T->lc=newNode;
  }
  else //非空,找到插入点再插入
  InsrtAVL(T->lc,newNode,&(T->lc),taller);
  if (taller) //判断平衡性
  switch (T->bf)
  {
  case LH: //进行左平衡处理
  LeftBalance(T,Tr); taller=false; break;
  case EH:
  T->bf=LH; taller=true; break;
  case RH:
  T->bf=EH; taller=false; break;
  }
  }
  else //在T的右子树中搜索插入
  {
  if (T->rc==NULL) //T的右子树为空树,直接插入
  {
  taller=true; T->rc=newNode;   }
  else //非空,找到插入点再插入
  InsrtAVL(T->rc,newNode,&(T->rc),taller);
  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,Tr); taller=false; break;
  }
  }
  return 1;
  }
  void LeftBalance(BSTnode *T,BSTnode **Tr) //左平衡处理
  {
  BSTnode * B_node,*C_node;
  B_node=T->lc;
  switch (B_node->bf)
  {
  case LH: //单向右旋
  T->bf=B_node->bf=EH; R_Rotate(T,Tr); break;
  case RH:
  C_node=B_node->rc;
  switch (C_node->bf)
  {
  case LH:
  T->bf=RH; B_node->bf=EH; break;
  case EH:
  T->bf=B_node->bf=EH; break;
  case RH:
  T->bf=EH; B_node->bf=LH; break;
  }
  C_node->bf=EH;
  L_Rotate(B_node,&(T->lc)); //先左旋后右旋
  R_Rotate(T,Tr);
  }
  }
  void RightBalance(BSTnode *T,BSTnode **Tr) //右平衡处理
  {
  BSTnode * C_node,*B_node;
  B_node=T->rc;
  switch (B_node->bf)
  {
  case RH: //单向左旋
  T->bf=B_node->bf=EH; L_Rotate(T,Tr); break;
  case LH:
  C_node=B_node->lc;
  switch (C_node->bf)
  {
  case RH:
  T->bf=LH; B_node->bf=EH; break;
  case EH:
  T->bf=B_node->bf=EH; break;
  case LH:
  T->bf=EH; B_node->bf=RH; break;
  }
  C_node->bf=EH;
  R_Rotate(B_node,&(T->rc)); //先右旋后左旋
  L_Rotate(T,Tr);
  }
  }
  void R_Rotate(BSTnode *P,BSTnode **Tr) //右旋
  {
  BSTnode *lch;
  lch=P->lc;
  P->lc=lch->rc;
  lch->rc=P;
  P=lch;
  *Tr=P;
  }
  void L_Rotate(BSTnode *P,BSTnode **Tr) //左旋
  {
  BSTnode * rch;
  rch=P->rc;
  P->rc=rch->lc;
  rch->lc=P;
  P=rch;
  *Tr=P;
  }
  int MidOrder(BSTnode *T) //中序遍历平衡二叉树
  {
  int l,r;
  if (!T) return 0;
  l=MidOrder(T->lc);
  printf("%d,",T->data);
  r=MidOrder(T->rc);
  return l+r+1;
  }
  int main()
  {
  int n=0,x,i,len;
  int datas[Num];
  BSTnode *newNode;
  while(scanf("%d",&x)==1) //输入待排序关键字序列
  {datas[n]=x;n++;}
  len=n;
  printf("Init datas:\n"); //第一个关键字作为根
  printf("%d, ",datas[0]);
  newNode=(BSTnode *)malloc(sizeof(BSTnode));   newNode->data=datas[0];
  newNode->lc=NULL;
  newNode->rc=NULL;
  newNode->bf=EH;
  Root=newNode;
  for (n=1;n  {
  printf("\nInsert:%d, ",datas[n]); //构造新结点
  taller=true;
  newNode=(BSTnode*)malloc(sizeof(BSTnode));
  newNode->data=datas[n];
  newNode->lc=NULL;
  newNode->rc=NULL;
  newNode->bf=EH;
  i=InsrtAVL(Root,newNode,&Root,taller); //插入
  }
  printf("\nMid_order:\n"); //中序遍历输出排序结果
  MidOrder(Root);
  return 0;
  }
  4.算法分析
  4.1排序结果与平衡二叉树的状态变化
  假设一个给定的待排序序列,包含12个关键字,初始形态如下:
  int datas[Num]={20,12,6,28,16,36,32,10,2,30,8,32};
  采用上述算法进行排序,排序过程和平衡二叉树的状态变化如图1所示。
  上述过程和结果符合平衡二叉树构造的原理,结果完全正确。
  4.2算法分析
  采用构造平衡二叉树的方法进行排序,其排序思想非常简单,只要根据给定的待排序关键字序列,从无到有依次将每个关键字正确插入平衡二叉树即可。待所有待排序关键字插入完成后,最终进行一次中序遍历,就可得到正确的排序结果。整个算法的关键在于完成平衡二叉树的构造。
  对于上述算法,从时间需求上看,由于在一棵包含n个结点的平衡二叉树中插入一个新结点时,由其平衡性,查找插入位置需要进行的关键字比较的个数不超过平衡二叉树的深度,故插入操作的时间复杂度为O(log2n),整个排序过程共需要插入n个关键字,因此,算法的时间效率均为O(nlog2n);从空间需求分析,除了需要在排序过程中动态申请n个平衡二叉树结点和少量搜索指针外,不再需要额外的存储空间,因而存储空间的需求也低。另外,根据本文对平衡二叉树定义的修改约定,上述算法是一个稳定的排序算法。
  图1平衡二叉树的状态变化和排序结果
  5.结语
  以上根据平衡二叉树的概念和基本特性,讨论了借助构造平衡二叉树的方法进行内部排序的算法设计,并利用一个典型实例对该算法进行了验证;最后,对算法的时间效率、空间需求和稳定性作了分析和讨论,得到了正确的结果。
  本文通过将动态查找与内部排序的方法相结合,提出了基于平衡二叉树构造的排序算法,并就其算法设计、效率和稳定性进行分析,达到了预期目的。这种引导学生将课程知识前后串联、融会贯通、综合分析与设计的思想方法,对于培养学生的发散性思维和创新意识,具有十分重要的示范促进作用和深远的影响。
  参考文献:
  [1] 严蔚敏等,数据结构(C语言版),清华大学出版社,2009.2
  [2] 邹永林等,数据结构与算法教程,机械工业出版社,2004.9
  [3] 秦锋等,数据结构(C++版),北京林业出版社、北京大学出版社,2006.9
其他文献
综合运用GIS技术和景观生态学方法,以贵州省九个地级行政单元为研究对象,分析了贵州省土地利用的空间结构特征,进而,结合贵州省特殊省情--喀斯特石漠化的发育,建立了喀斯特石
【摘要】新课程改革十分强调科学探究。科学探究是物理教学的重要组成部分。科学探究是一种学习方式,是学习目标,也是学习的内容。科学探究也是一种精神,在一定程度上可以说是人们对未知事物的探究精神是与生俱来的,物理教育学应该保护并发扬青少年的这种精神。在探究性理论的指导下,物理教师必须改变教学方式,在物理教学过程中渗透探究性的理念,创设情景与条件,充分发挥学生的主体性。同时,通过激发兴趣,唤起好奇心,培养
摘要:3DSMax在室内设计效果图中的运用相当广泛。笔者从事室内设计专业教学,其中3D软件课程教学多年。本文主要是从室内装饰效果图的制作流程以及3DSMax软件的应用特点出发,针对当前3DSMax教学中遇到的问题,对此软件课程的教学方法进行探讨。  关键词:3DSMax;室内效果图;教学模块  【中图分类号】G712  一、前言  3DSMax软件在室内设计行业效果图表现方面起着至关重要的作用,特
“权力是党和人民给的,只能用于党和人民的事业,决不能用来谋取个人私利。” 这句朴实无华的语言,犹如一面明镜,折射出射洪县人民检察院王国卿检察长的人生信念。四十个春秋
摘 要:在我国,学习英语的热潮已经持续了十余年并且呈现出进一步加强的趋势。高校的英语学习是学生英语能力的提高阶段,尤其是英语听说课,其教学内容和方式直接决定着高校学生英语的最终掌握水平。那么,我国高校英语听说课的现状是什么样的,还存在哪些问题,如何进行改进,这都是本文将要进行研究的重点。  关键词:高校英语听说课;教学现状;改善对策  【中图分类号】G642  拥有较高的英语水平会成为高校学生在就
内容摘要:语文课堂教学之"情境创设"环节,对本节课的教学效果起着十分重要的作用。"情境创设"得当,就会把学生的思维直接引入本课要学习的内容之中,学生就会沿着教师创设的"情境"去学习、理解、探究课文内容,这要比不创设情境或者创设不当好得多,其教学效果自然是"事半功倍"。  关键词:情境创设;方法途径;激起情趣;提高效率  【中图分类号】G632  一个好的班务工作者不仅要给学生传授知识,而且要培养学
摘要:随着人类社会和知识经济突飞猛进的发展,信息技术也在日新月异的变化。信息技术的出现,为我们优化教学过程,提高教学效率提供了新的选择途径,信息技术以文字、图片、声音、动画和视频等综合形式向学习者传播知识,丰富了排球课的教学内容,激发了学习者对运动知识和运动技术学习的兴趣,调动学习的积极性,拓宽知识视野,提高教学效果。  关键词:信息技术;课程整合;教学设计;研究  【中图分类号】G623.58 
目的:构建Beclin1过表达黑素瘤细胞株,观察Beclin1过表达后SK-MEL-2细胞侵袭和迁移能力的改变。方法:通过免疫组化观察皮肤恶性黑素瘤和色素痣组织的Beclin1的表达水平;采用免疫蛋白印迹法检测Beclin1在黑素瘤细胞A375和SK-MEL-2及中的表达水平,筛选低表达Beclin1蛋白的SK-MEL-2细胞株作为研究对象;应用脂质体转染SK-MEL-2细胞,采用免疫蛋白印迹技术
学位
摘要:随着课程改革的深入,综合性学习走入了我们的视野。它以学生主体性活动为构成要素,在内容上、形式上、时间上、空间上都具有开放性,整个过程具有强烈的实践性,而这必然会促进学生各个方面的发展。  关键词:实施;综合性学习;促进;发展  【中图分类号】G620  综合性学习就是学生在教师的指导下,从学生的学习生活和社会生活中提出课题研究或专题活动的全过程中主动地获取知识、应用知识、解决问题,并获得亲身
目前,仍有相当一部分国有企业面临严峻的形势而未能走出困境。企业经济困难给党建工作带来了一些新的情况和新的难度,迫切需要我们认真研究和解决。 问题与共识 困难企业党