第二周周总结

任务描述。

实现KMP模式匹配算法、由遍历序列恢复二叉树、Kruskal算法、关键路径算法、二叉排序树

二、概要设计

1、抽象数据类型

抽象数据类型(Abstract Data Type,ADT)是将数据对象、数据对象之间的关系和数据对象的基本操作封装在一起的一种表达方式,它和工程中的应用是一致的。

2、主程序流程及各程序模块的层次关系

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。

首先,由先序序列可知,结点A是二叉树根结点。其次,根据中序序列,在A之前所有的结点都是根结点的左子树的结点,在A之后的结点都是根结点右子树的结点,由此就是下图的a) 的状态。

然后在对A左子树进行分解,得知B是左子树的根结点,又从中序序列知道,B的左子树为空,B的右子树只有一个结点C。

接着对A的右子树进行分解,得知A的右子树的根结点是D;而D把其余结点分成两部分,即左子树E,右子树FGHI,如图b) 所示。

接下就是以D为根结点,将右子树继续分解了

克鲁斯卡尔算法查找最小生成树的方法是:将连通网中所有的边按照权值大小做升序排序,从权值最小的边开始选择,只要此边不和已选择的边一起构成环路,就可以选择它组成最小生成树。对于 N 个顶点的连通网,挑选出 N-1 条符合条件的边,这些边组成的生成树就是最小生成树。

关键路径算法是在工程能完成的情况下找出关键的几个活动,达到工程更早完成的效果。

一棵空树,或者是具有下列性质的二叉树

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

【注】:以上的三种定义在不同的数据结构教材中均有不同的定义方式 但是都是正确的 在开发时需要根据不 同的需求进行选择

【注2】:没有键值相等的结点。

 

三、详细设计

查找二叉排序树

int SearchBST(BSTNode *bt,KeyType k)

{

 

    if(bt==NULL)

    {

        return 0;

    }

    else if(bt->key==k)

    {

        printf("%d ",bt->key);

        return 1;

    }

    else if(bt->key>k)

    {

        printf("%d ",bt->key);

        return SearchBST(bt->lchild,k);

    }

    else if(bt->key<k)

    {

        printf("%d ",bt->key);

        return SearchBST(bt->rchild,k);

    }

}

实现KMP模式匹配算法

#include <stdio.h>

#include<string.h>

const int MAX_LEN = 20010;

 

// 递推计算Next数组,模板串为str,模板串长度为len

void get_next(char str[], int len, int next[])

{

    int i = 0, j = 0;

    next[0] = -1;

    for (i = 1; i < len; i++) {

        while (j > 0 && str[i] != str[j])

            j = next[j-1];

        if (str[i] == str[j]) j++;

        next[i] = j;

    }

}

 

// 在字符串s中匹配字符串t,s长度为len_s,t长度为len_t,t的Next数组为next[],返回t第一次出现的位置

int find_pattern(char s[], int len_s, char t[], int len_t, int next[])

{

    int i = 0, j = 0;

    while(i < len_s && j < len_t)

    {

        //匹配字符          

              if(j == -1 || s[i] == t[j])

              {

                     j++;

                     i++;

                    

              }

              else{

                        j = next[j];

              }

       }

             

              if(j == len_t)

                return i - j ;

              else

                 return -1;

   

}

 

int main()

{

    int cas,a;

    char s[MAX_LEN], t[MAX_LEN];

    int next[MAX_LEN];

    scanf("%d", &cas);

    while (cas --)

    {

        scanf("%s %s", s, t);

        int len_s = strlen(s);

        int len_t = strlen(t);

        get_next(t, len_t, next);

        a=find_pattern(s, len_s, t, len_t, next);

        if(a==-1)

        printf("not find!\n");

        else

        printf("%d\n", a);

    }

    return 0;

}

关键路径

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

using namespace std;

const int N=1010;

int a[N][N],n;

int in[N],dis[N];

int out[N],rdis[N];

int vec[N],cnt;

 

int main(){

    int m;

    while(cin>>n>>m){

        cnt=0;

        for(int i=1;i<=n;i++){

            for(int j=1;j<=n;j++){

                a[i][j]=0;

            }

        }

        memset(in,0,sizeof in);

        memset(out,0,sizeof out);

        memset(dis,0,sizeof dis);

        memset(rdis,0x3f,sizeof rdis);

       

        for(int i=0;i<m;i++){

            int u,v,d;

            cin>>u>>v>>d;

            in[v]++;

            out[u]++;

            a[u][v]=d;

        }

 

        int o=-1;

        bool ji=0;

        for(int i=1;i<=n;i++){

            if(in[i]==0){

                if(o==-1){

                    o=i;

                }else{

                    ji=1;

                }

            }

        }

        if(o==-1||ji==1){

            cout<<"unworkable project"<<endl;

            continue;

        }

 

        vec[cnt++]=o;

        while(cnt>0){

            int p=vec[--cnt];

            for(int i=1;i<=n;i++){

                if(a[p][i]>0){

                    in[i]--;

                    if(dis[i]<dis[p]+a[p][i]){

                        dis[i]=dis[p]+a[p][i];

                    }

                    if(in[i]==0){

                        vec[cnt++]=i;

                    }

                }

            }

        }

 

        bool fl=1;

        for(int i=1;i<=n;i++){

            if(in[i]>0){

                fl=0;

            }

        }

        if(fl==0){

            cout<<"unworkable project"<<endl;

            continue;

        }

       

       

        int tmp=vec[0];

        rdis[vec[0]]=dis[vec[0]];

        cnt++;

        while(cnt>0){

            int p=vec[--cnt];

            for(int i=1;i<=n;i++){

                if(a[i][p]>0){

                    out[i]--;

                    if(rdis[i]>rdis[p]-a[i][p]){

                        rdis[i]=rdis[p]-a[i][p];

                    }

                    if(out[i]==0){

                        vec[cnt++]=i;

                    }

                }

            }

        }

        cout<<dis[tmp]<<endl;

        for(int i=1;i<=n;i++){

            for(int j=1;j<=n;j++){

                if(a[i][j]>0&&dis[i]==rdis[i]&&dis[j]==rdis[j]&&dis[i]+a[i][j]==dis[j] ){

                    cout<<i<<"->"<<j<<endl;

                }

            }

        }

    }

   

    return 0;

}

修复道路

using namespace std;

const int N=10100;

int g[N][N],p[N];

int find(int x){

    if(x!=p[x])p[x]=find(find(p[x]));

    return p[x];

}

struct node{

    int x,y,w;

}s[N];

bool cmp(node a,node b){

    return a.w<b.w;

}

int main(){

    int n,cnt=0,ans=0;

    cin>>n;

    for(int i=1;i<=n;i++)p[i]=i;

    for(int i=1;i<=n;i++)

        for(int j=1;j<=n;j++)

            cin>>g[i][j];

    int m;

    cin>>m;

    while(m--){

        int a,b;

        cin>>a>>b;

        p[find(a)]=find(b);

        g[a][b]=g[b][a]=0;

    }

    for(int i=1;i<=n;i++){

        for(int j=1;j<=n;j++){

            if(g[i][j]){

                s[cnt].x=i;

                s[cnt].y=j;

                s[cnt].w=g[i][j];

                cnt++;

            }

        }

    }

    sort(s,s+cnt,cmp);

    for(int i=0;i<cnt;i++){

        if(find(s[i].x)!=find(s[i].y)&&g[s[i].x][s[i].y]){

            p[find(s[i].x)]=s[i].y;

            ans+=s[i].w;

        }

    }cout<<ans<<endl;

    return 0;

}

先序和中序构造二叉树

#include <iostream>

using namespace std;

 

void getlast(int n,int *a,int *b);

 

int main() {

       int n;

       cin >> n;

       int prescan[40], midscan[40];

       int i;

       for (i = 0; i < n; i++) {

              cin >> prescan[i];

       }

       for (i = 0; i < n; i++) {

              cin >> midscan[i];

       }

       getlast(n,prescan,midscan);

       cout<<endl;

       system("pause");

       return 0;

}

 

 

void getlast(int n,int *a,int *b)

{

    if(n<=0){

        return ;

    }

    int root=a[0];

    int i;

    for(i=0;i<n;i++){

        if(b[i]==root){

            break;

        }

    }

 

    getlast(i,a+1,b);

    getlast(n-i-1,a+1+i,b+1+i);

    cout<<root<<" ";

}

 

四、调试分析 逐一说明

1、遇到的问题

7-1出现问题,主要是对其中的排序出了问题

2、解决的方法

通过逐个进行排序,来进行处理

五、系统测试 逐一说明

 

posted @ 2022-07-11 23:04  zhuzhurr  阅读(44)  评论(0)    收藏  举报