自学内容网 自学内容网

湘潭大学软件工程算法设计与分析考试复习笔记(六)

回顾

说明

这篇笔记是关于 40 分的程序填空的。

前面涉及代码的部分

湘潭大学软件工程算法设计与分析考试复习笔记(二):这篇博客里面有一些代码,可以选择性地记一记。

因为代码填空涉及的内容比较广泛,下面主要是从ppt里面摘录出来。

第一章

没有代码填空,非常轻松。

第二章

汉诺塔问题

void Hanoi(int n, int Fr, int To, int As)
          {
               if  (n > 0) {
                    Hanoi(n–1, Fro, Ass, To);
                    Move(Fro, To);
                    Hanoi(n–1, Ass, To, Fro)}
           }

正整数的划分

q(n, m) { 
       if (n < 1) || (m < 1)      return 0;
       if (n == 1) || (m == 1)  return 1;
       if (n == 1) || (n < m)    return 1 + q(n, n–1);
       return q(n, m–1) + q(n–m, m);  }

Hilbert图案

A(i) { 
   if  (i > 0) { D(i – 1); x = x – h;  ploting(x, y) ; 
      A(i – 1);   y = y – h;  ploting(x, y) ;
      A(i – 1);   x = x + h;  ploting(x, y) ;
       B(i – 1); }}
  //*ploting(x, y)是从画笔现行坐标到坐标(x, y)画条直线

Koch 曲线

Koch(L, i) { //*L为长度,i为级数
  if (i == 0) Line(L) //*i为0,画条长为L的线段
  else {Koch(L/3, i – 1);
           Turn(60);  Koch(L/3, i – 1);
           Turn(120);  Koch(L/3, i – 1);
           Turn(60);  Koch(L/3, i – 1);}}
Draw-Koch(L, θ, n) {//*将角度初始化为θ;
     Turn(θ);  Koch(L, n);}//*然后再画曲线。

二分搜索有序表

Binary-Search(L, n, z)
{k = 1; m = n; //*k和m分别为搜索部分的首和尾
 flag = 0; //*找到标志初始为0
 while (k <= m && flag = 0) {
     j = (k + m) / 2 ; //*取中点下标 
    if (z == L[j]) flag = 1 //* 找到了标志为1
  else if (z < L[j]) m = j – 1 //*小于中点,尾前移
      else k = j + 1 //*大于中点,首后移
} 

一维最接近点对算法

有一些特殊符号显示不出来。所以这里把课件的截图也放在这儿了。

bool Cpair1(S, d)
{
   n = |S|;
   if (n < 2) { d =; return false }
   m = S中各点的坐标的中位数;
   构造S1和S2; // S1={xS | xm}, S2={xS | x>m}
   Cpair1(S1, d1); 
   Cpair1(S2, d2);  //分别求S1和S2的最接近点对
   p=max{S1}; q =min{S2}; d = mim{d1, d2, q – p};
   return true 
}

在这里插入图片描述

平面最接近点对的算法

不是那种非常标准的代码,应该是为了方便我们理解写的伪代码
在这里插入图片描述

第三章

Prim算法的实现

Prim(int n, Type **c) {
int j = 1; s[j] = true; 
for (int i = 2; i <= n;  i++) { 
closest[i] = 1; 
lowcost[i]=c[1][i];
s[i]=false;
}
for (int i = 1; i < n;  i++) {
min= inf; 
for (int k = 2; k <= n;  k++) {
    if (lowcost[k]<min&&!s[k]){
    min = lowcost[k]; 
    j = k;
    } 
s[j] = true;                         
for (int k = 2; k <= n;  k++) {
    if (c[j][k]< lowcost[k]&&!s[k]){
    lowcost[k] = c[j][k]; 
    closest[k] = j;
       }
    }
} 

Kruskal算法的实现

Kruskal(int n, **e)  {
  Sort(e, w); //将边按权重从小到大排序
  initialize(n); //初始时每个顶点为一个集合
  k = 1; //k累计已选边的数目,
  j = 1;  //j为所选的边在e中的序号
  while (k < n) //选择n – 1条边
    {a = Find(e[j][u]); b = Find(e[j][v]); 
   //找出第j条边两个端点所在的集合
     if (a != b) {t[k++] = j; Union(a, b)}
   //若不同,第j条边放入树中并合并这两个集合
     j++ }} //继续考察下一条边

Dijkstra 算法

在这里插入图片描述

第四章

消除重复的矩阵连乘算法

在这里插入图片描述

最优三角剖分的算法

在这里插入图片描述

Void MinWeightTriangulation(int n, Type **t, int **s)
 {  for (int i = 1; i <= n; i++) t[i][i] = 0; 
     for (int r = 2; r <= n; r++) 
        for (int i = 1; i <= n – r +1; i++) {
           int j = i + r – 1;
           t[i][j] = t[i+1][j] + w(i–1, i, j);
           s[i][j] = i; 
           for (int k = i + 1; k < j; k++) {
              int u = t[i][k] + t[k+1][j] + w(i–1, k, j); 
              if (u < t[i][j]) {t[i][j] = u; s[i][j] = k;}
}}} //程序中红色的部分为改动的地方

动态规划法求序列相似性

在这里插入图片描述

第五章

树搜索的一般形式

SearchTree(Space T)//表L用来存放待考察的结点
{unfinish = true; L = T.initial; 
// unfinish表示搜索未结束,先将初始状态放入L
while (unfinish || L≠Φ) {
     a = L.first; //从L中取出第一个元素
     if (a is goal) unfinish = false //若a是终态则结束
 else Control-put-in(L, Sons(a));
} //否则,将a的儿子们以某种控制方式放入L中

迭代回溯法的一般形式

在这里插入图片描述

用末尾标记的迭代回溯

在这里插入图片描述

数字的全排列

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

n 皇后

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

TSP 递归回溯

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

用回溯法解0-1背包问题

Try(s){
 for (i = 0; i < 2; i++)
   if  (Accept(i)) {
        Record(s, i)if (s = = n) {if  ( better ) TakeNewChoice( );}  
   else Try(s+1);
       Move-off(s, i);}
 return } 

在这里插入图片描述

在这里插入图片描述

0-1背包问题的迭代实现

Backtrack(Tree T) {
 j = 1; L.Push(1, 0, 1);
  while (L≠Φ) {
    a = L.Pop( ); 
    if (a = =1) {Move-off(j, N[j]); j– –;}
else if (W+w[j]*a <= C) {Record(a);
        if (j = = n ) {if (V < NV) TakeNewChoice( );}
 else {j++; L.Push(1, 0, 1);}
}}}

第六章

求传递闭包的Warshall算法

for (i = 1; i <= n; i++)
         for (j = 1; j <= n; j++)
              if (M[j][i] == 1) 
                    for (k = 1; k <= n; k++)
                          M[j][k] = M[j][k] + M[i][k]

ppt 上面只有这个代码。之后会补充一些,在博客的最后面。

第七章

直接用概率进行数值计算

double Darts (int n) {double x, y;  int k = 0; 
  static RandomNumber dart;
  for (int i=1; i<=n; i++) {x=dart.fRandom();   
     y=dart.fRandom(); if (y<=f(x)) k++;}
  return k/double(n); }

“洗牌”后的快速排序

void Shuffle(Type a[], int n) { //随机洗牌算法
   static RandomNumber md;
   for (int i = 1; i < n; i++) {
         int j = md.Random(n – i + 1) + i;
         Swap(a[i], a[j]); }}
Void QuiksortByShuffle(Type a[], int n) {
    Shuffle(a, n); //将数组a洗牌
    Quiksort(a, n); }

随机抽样

int RandomSampling(S[n], A[m], m) {
  mark[1..n] = False;  count=0;
  while(count < m) {
      r = random(1, n);
      if (mark[r] == False) {
          count++;
          A[count]=S[r];
          mark[r]=True; }}}

Fermat素数测试法

Bool Fermat_Prime(int n) {
   a = 2; power = n – 1; other = 1;
  while(power > 1)  {
    if (power % 2 = = 1) {other *= a; other %= n;}
    power /= 2;   a = a * a  %  n;}
  if  (a * other  %  n == 1) return True;
  return False;
}

Miller-Rabin素数判定概率算法

Bool  Miller_Rabin_Prime(int n){
 b[1 .. m] = RandomSampling(n, m); 
 /*随机选取m个大于1小于n的无重复的自然数
for (j = 1; j <= m;  j++)
      if (W(b[j]) 满足)  return False;
 return True;
}
若m = 100,则n不是素数的概率小于1/2100。

模拟退火算法的框架

在这里插入图片描述

k = 0; i = i0; t = t0; //初始化
while (不满足停止准则) {
   Gen(Si); //产生i的邻域Si,|Si|=Lk
   for (j∈Si) //用Metropolis准则对Si中的
        if (f(i) < f(j)) i = j; //每个状态j检测是否可替代i
     else if (exp((f(i)f(j))/ t) > random(0, 1)) i = j;
   k = k + 1; t = tk; // 降温;进入下一轮迭代
 }       

第八章

没有代码

补充

最佳调度

long f(int n) {
    if (n < 2) return n;
    long sum = 1;
    for (int i = 1 ; i <= n - 1; i++)
        sum += f(i);
    return sum;
 }

备忘录方法

 Long dp[max]
 long f1(int n) {
    dp[1] = 1;
    dp[2] = 2;
    if (n <2) { 
        return dp[n];
    }
    if (dp[n] > 0) return dp[n];
    long sum = 1;
    for (int i = 1 ; i <= n - 1; i++)
        sum += f1(i);
    dp[n] = sum;
    return dp[n];
 }

上台阶

#include<iostream>
#include<cmath>
using namespace std;
int dp[107];
int main() {
int n, m;
 cin >> n >> m;
 dp[0] = 1;
 for (int i = 1; i <= n; i++) {
 for (int j = 1; j <= m; j++) {
 if (i < j)break;
 dp[i] += dp[i - j];
 }
 }
 cout << dp[n];
 return 0;
}

原文地址:https://blog.csdn.net/L3102250566/article/details/143992237

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!