几种算法

2016-02-19 13:12 17 1 收藏

在这个颜值当道,屌丝闪边的时代,拼不过颜值拼内涵,只有知识丰富才能提升一个人的内在气质和修养,所谓人丑就要多学习,今天图老师给大家分享几种算法,希望可以对大家能有小小的帮助。

【 tulaoshi.com - 编程语言 】


  已知一棵二叉树按顺序方式存储在数组 A[1..n]中。设计算法求出下标分别为 i 和 j 的两个结点的最近的公共祖先结点的值。
  
  武汉大学2000年第五(1)题(8’)
  
  
  #inlcude stdio.h
  parent(int A[],int i,int j)
  {int k,m;
  m=k=0;
  if(i==1j==1A[i]==0A[j]==0i==j) // A[i]==0或A[j]==0表示不存在该结点
  {printf("Error.");return;}
  while(i!=1&&j!=1){
  if(ij){j=j/2;m=1;} // 结点 j 的最近祖先结点是 ┗ j/2 ┛
  else if(ji){i=i/2;k=1;}
  else if(j==i){i=j;break;} // i=j 表示找到共同祖先
  }
  if(j==1i==1)i=1; // i 或 j 有一个到了根结点
  else if(m==0k==0)i=i/2; // m、k 中有一个为 0 ,说明在查找过程中 i 或 j 有一个没移动
  printf("The nearest common parent is A[%d].",i);
  }
  
  
  本题思路是使 i 和 j 交替追赶,直到相等。
  
  ------------------------------------------------------------------------
  
试写一个判别给定二叉树是否为二叉排序树的算法。
  
  长沙铁道学院98年第五(1)题(12’)
  
  
  typedef strUCt node{
  char data;
  struct node *left,*right;
  }*T;
  
  issorttree(T)
  {
  initqueue(Q); // 初始化队列
  inqueue(Q,T); // 树根结点进队列
  while(!empty(Q)){
  outqueue(Q,T);
  if(T-dataT-left-data&&T-dataT-right-data){
  if(T-left)inqueue(Q,T-left);
  if(T-right)inqueue(Q,T-right);
  }
  else if(T-leftT-right)return 1; // 不符合二叉排序树的特征,则终止并返回‘ 1 ’
  }
  return 0; // 是二叉排序树,则返回 ‘0’
  }
  
  注重队列的运用,其他如图的广度搜索(教材《清华 C 版》)。
  
  ------------------------------------------------------------------------------
  设一单向链表的头指针为head,链表的记录中包含着整数类型的key域,试设计算法,
  将此链表的记录按照key递增的次序进行就地排序.(不答应使用数组做辅助存储)
  
  中科院计算机技术研究所1999年第五(1)题 (10’)
  华中理工大学2000年第八(2)题 (13’)
  
  
  typedef struct CircleList{ // 定义循环链表
  int key;
  struct CircleList *next;
  }*listnode;
  
  ListSort(listnode head)
  {
  int k,min,i,j;
  listnode p,q,t;
  p=head-next;
  while(p-next!=head-next){p=p-next;k+=1;} // 统计链表中元素个数,保存在 K 中
  p=head;j=1;
  for(i=1;ik;i++){
  while(j=i){p=p-next;j++;} // 找应填入当前最小元素的位置,该位置保存在 q 中
  min=p-key;q=p; // 将当前位置元素的值设为初始最小值
  while(p-next!=head-next){
  if(minp-key){min=p-key;t=p;} // 找当前最小元素,并保存在 t 所指位置中
  p=p-next;
  }
  t-key=q-key;q-key=min;j=1; // 交换 q 位置元素和最小元素的值
  }
  }
  
  本题不需要修改链表中的各个指针。
  
  --------------------------------------------------------------------------
  前几天根据快速排序 Quick Sort算法的基本思想,编写了如下分治策略的算法,供大家讨论: 
  思路: 
  设输入的序列L[p..r],确定支点元素l[p]和l[r],并使l[p].key=l[r].key 
  分解(Divide):将序列L[p..r]划分成三个子序列L[p..k-1]、L[k+1..m-1]和L[m+1..r],使L[p..q]中关系为L[p..k-1]、l[k]、L[k+1..m-1]、l[m]、L[m+1..r]任一区间元素的值不大于其后区间元素的值。 
  递归求解(Conquer):通过递归调用快速排序算法分别对L[p..k-1]、L[k+1..m-1]和L[m+1..r]进行排序。 
  算法的实现(用C语言实现) 
  QSort(Sqlist &L,int low,int high){ 
  c=high-low; /*循环次数*/ 
  if(c10)直接调用插入排序法; /*小数时直接调用插入排序法*/ 
  if(L.r[low].keyL.r[high].key)L.r[low]-L.r[high]; /*确保区间内第一个元素的值不大于区间内最后一个元素的值*/ 
  ilow=low; /*小于区间内第一个元素的值数组边界下标*/ 
  ihigh=high; /*大于区间内最后一个元素的值数组边界下标*/ 
  for(i=low+1;ic;i++){ 
  if(L.r[i].keyL.r[low].key)L.r[i]-L.r[++ilow]; /*小于区间内第一个元素的值放置ilow区间内*/ 
  else 
  if(L.r[i].keyL.r[high].key){ 
  L.r[i]-L.r[--ihigh]; /*大于区间内最后一个元素的值放置ihigh区间内*/ 
  i--; /*下一个比较位置不变*/ 
  c--; /*循环次数减一*/ 
  } 
  } 
  L.r[ilow]-L.r[low]; /*将小于区间内第一个元素的边界下标元素与第一个元素互换*/ 
  L.r[ihigh]-L.r[high]; /*将大于区间内最后一个元素的边界下标元素与最后一个元素互换*/ 
  QSort(L,low,ilow-1); 
  QSort(L,ilow+1,ihigh-1); 
  QSort(L,ihigh+1,high); 
  } 
  void QuickSort(Sqlist &L) 
  { 
  QSort(L,1,L.length); 
  } 
  优点: 
  1、每次快速排序将确定二个元素位置 
  2、每次快速排序将划分三个区间,优化后续平均时间和空间复杂度 
  缺点: 
  1、存在较多的元素交换(每次需要三步),不及改进快速排序法利用空穴赋值方便
  
  --------------------------------------------------------------------------------------
  
  四阶Runge-Kutta法 
  
  一阶常微分方程: 
  u'=f(t,u) atb
  u(t(0))=u(0) 
  
  
  Runge-Kutta非线性高阶单步法,p阶R-K法的整体阶段误差为O(h^p)
  
  R-K四阶算法:
  u(i+1)=u(i)+h*(k1+3*k2+3*k3+k4)/8
  k1=f(t(i),u(i))
  k2=f(t(i+h/3),u(i+h*k1/3))
  k3=f(t(i+h/3),u(i+h*k2/3))
  k4=f(t(i+h),u(i+h*k3)) 
  
  四阶程序如下:
  class RK{
  private:
  double k1,k2,k3,k4;
  double h,b,u,a;
  public:
  void seth(double l=0){h=l;} //设步长
  void setf(double xa=0,double xb=0,double y=0) //设初值和范围(xa,xb)
  {
  b=xb;
  a=xa;
  u=y;
  }
  double f(double t,double u) //函数值,修改它以适应各自需要
  {
  //函数设定
  double f=u-2*t/u; 
  return f;
  }
  void dork() //R-K 主函数
  {
  for(int count=0;count(b-a)/h;count++)
  {
  k1=f(a+count*h,u);
  k2=f(a+count*h+h/3,u+h*k1/3);
  k3=f(a+count*h+2*h/3,u-h*k1/3+h*k2);
  k4=f(a+count*h+h,u+h*k1-h*k2+h*k3);
  u=u+h*(k1+3*k2+3*k3+k4)/8;
  countuendl;
  }
  
  }
  }; 
  
  void main()
  {
  RK my;
  my.seth(0.1);
  my.setf(0,1,1);
  my.dork();
  }
  
  --------------------------------------------------------------------------------------
  快速排序 
  
  算法的基本思想:
  
  快速排序的基本思想是基于分治策略的。对于输入的子序列ap..ar,假如规模足够小则直接进行排序,否则分三步处理:
  
  分解(Divide):将输入的序列ap..ar划分成两个非空子序列ap..aq和aq+1..ar,使ap..aq中任一元素的值不大于aq+1..ar中任一元素的值。 
  递归求解(Conquer):通过递归调用快速排序算法分别对ap..aq和aq+1..ar进行排序。 
  合并(Merge):由于对分解出的两个子序列的排序是就地进行的,所以在ap..aq和aq+1..ar都排好序后不需要执行任何计算ap..ar就已排好序。 
  这个解决流程是符合分治法的基本步骤的。因此,快速排序法是分治法的经典应用实例之一。
  
  算法Quick_Sort的实现:
  
  Pascal实现:
  Procedure Quick_Sort(p,r:TPosition;var L:TList); {快速排序}
  
  var
  
  q:TPosition;
  
  begin
  
  if L[p..r]足够小 then Sort(p,r,L) {若L[p..r]足够小则直接对L[p..r]排序}
  
  else
  
  begin
  
  q:=Partition(p,r,L); {将L[p..r]分解为L[p..q]和L[q+1..r]两部分}
  
  Quick_Sort(p,q,L); {递归排序L[p..q]}
  
  Quick_Sort(q+1,r,L); {递归排序L[q+1..r]}
  
  end;
  
  end;
  
  --------------------------------------------------------------------------------------
  设中序线索二叉树的结点结构为:leftltagdatartagright. 现已知中序线索
  二叉树的根结点地址root。设计一程序,打印出该线索二叉树的中序遍历结果.不得
  再使用O(n)级的辅存空间。
  
  上海交通大学96年第十题(15') 
  
  intravers(root:bitree)
  finished:=false;t:=root;
  while not finished do
  
  else 
  t:=t↑.rch; // 右孩子不空
  

来源:https://www.tulaoshi.com/n/20160219/1603353.html

延伸阅读
在这一篇中我将和大家讲述铅笔画算法和木雕算法和它们的实现。为什么我要把这两个算法放在一起说呢,因为这两个算法是非常相似的。首先要说一下人的眼睛对于图像的观察,人的眼睛对于灰度(亮度)的敏感要远远大于对色彩的敏感,而人的眼睛对于暖色调和冷色调的敏感有要远大于对一般色彩的敏感度。 经过大量的测试,人们得到了一个经验...
  // 节日算法 请参见 《农历与西历对照、万年历》 unit CNYear; interface uses sysutils; type TCNDate = Cardinal; function DecodeGregToCNDate(dtGreg:TDateTime):TCNDate; function GetGregDateFromCN(cnYear,cnMonth,cnDay:word;bLeap:Boolean=False):TDateTime; function GregDate...
残缺棋盘(defective chessboard)是一个有2k×2k 个方格的棋盘,其中恰有一个方格残缺。图2 - 3给出k≤2时各种可能的残缺棋盘,其中残缺的方格用阴影表示。注重当k= 0时,仅存在一种可能的残缺棋盘(如图1 4 - 3 a所示)。事实上,对于任意k,恰好存在22k 种不同的残缺棋盘。 残缺棋盘的问题要求用三格板(t r i o m i n o e s)覆盖...
CRC算法与实现 作者:bhw98 提交者:eastvc 发布日期:2004-1-2 20:57:13 原文出处:http://www.csdn.net/ 摘要: 本文首先讨论了CRC的代数学算法,然后以常见的CRC-ITU为例,通过硬件电路的实现,引出了比特型算法,最后重点介绍了字节型快速查表算法,给出了相应的C语言实现。 关键词: CRC, FCS, 生成多项式, 检错重传 引言 ...
推算法知排卵期 大部分妇女在下次来月经前2周左右(12-16天)排卵,可以根据自己以前月经周期的规律推算,由于排卵可受疾病、情绪、环境及药物的影响而发生改变,应与其他方法结合使用。 测量基础体温知排卵期 女性基础体温有周期性变化,排卵后基础体温升高能提示排卵已经发生,排卵一般发生在基础体温上升前由低到高上升的过...

经验教程

895

收藏

19
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部