中国大学MOOC-陈越、何钦铭-数据结构-2017春

5 篇文章 0 订阅
这篇博客介绍了如何使用C语言实现一元多项式的加法和乘法运算,涉及数据结构中的链表操作。文章中提到了C语言中取余运算的特性,并展示了如何创建和管理链表节点,以及读取、打印一元多项式的方法。此外,还提及了C++中的栈、队列和C语言中没有bool类型的特点。
摘要由CSDN通过智能技术生成

       C语言中在做a%b模运算(取余)时,其中a是被除数,b是除数。在做%运算时,被除数和除数都是取正数运算,最后结果与被除数符号相同,如-7%5就是-2,7%(-5)就是2。【-7/5=-1,7/-5=-1】

       malloc、qsort要用<stdlib.h>;stack、queue要在C++下用<stack>、<queue>

       C没有bool类型,C++有

    素数:2,3,5,7,11,13...


02-线性结构2 一元多项式的乘法与加法运算   (20分)

--参考MOOC里的小白专场

#include 
  
  
   
   
#include 
   
   
    
    

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    ElementType Expon;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表;空链表将输出NULL */

List Add( List L1, List L2 );
List Mult(List L1,List L2);

int main()
{
    List L1, L2, La,Lm;
    L1 = Read();
    L2 = Read();
    Lm = Mult(L1,L2);
    La = Add(L1, L2);
    Print(Lm);
    Print(La);
    return 0;
}
void Attach(int d,int e,List *rear)
{
    List node;
    node=(List)malloc(sizeof(struct Node));
    node->Data=d;
    node->Expon=e;
    node->Next=NULL;
    (*rear)->Next=node;
    *rear=node;
}
List Add( List L1, List L2 )
{
    List front,p,q,rear,temp;
    ElementType sum;
    p=L1;
    q=L2;
    front=(List)malloc(sizeof(struct Node));
    front->Next=NULL;
    rear=front;
    while(p&&q)
    {
        if(p->Expon>q->Expon)
        {
            Attach(p->Data,p->Expon,&rear);
            p=p->Next;
        }
        else if(p->Expon
    
    
     
     Expon)
        {
            Attach(q->Data,q->Expon,&rear);
            q=q->Next;
        }
        else
        {
            sum=p->Data+q->Data;
            if(sum)
                Attach(sum,p->Expon,&rear);
            p=p->Next;
            q=q->Next;
        }
    }
    for(;p;p=p->Next) Attach(p->Data,p->Expon,&rear);
    for(;q;q=q->Next) Attach(q->Data,q->Expon,&rear);
    temp=front;
    front=front->Next;
    free(temp);
    return front;
}
List Mult( List L1, List L2 )
{
    List front,p,q,rear,temp;
    ElementType d,e;
    if(!L1||!L2) return NULL;
    p=L1; q=L2;
    front=(List)malloc(sizeof(struct Node));
    front->Next=NULL;
    rear=front;
    while(q)
    {
        Attach(p->Data*q->Data,p->Expon+q->Expon,&rear);
        q=q->Next;
    }
    p=p->Next;
    while(p)
    {
        q=L2;
        rear=front;
        while(q)
        {
            d=p->Data*q->Data;
            e=p->Expon+q->Expon;
            while(rear->Next&&rear->Next->Expon>e)
                rear=rear->Next;
            if(rear->Next&&rear->Next->Expon==e)
            {
                if(rear->Next->Data+d)
                    rear->Next->Data+=d;
                else
                {
                    temp=rear->Next;
                    rear->Next=rear->Next->Next;
                    free(temp);
                }
            }
            else
            {
                temp=(List)malloc(sizeof(struct Node));
                temp->Data=d;
                temp->Expon=e;
                temp->Next=rear->Next;
                rear->Next=temp;
            }
            q=q->Next;
        }
        p=p->Next;
    }
    temp=front;
    front=front->Next;
    free(temp);
    return front;
}
List Read()
{
    List h,last,temp;
    ElementType len,d,e;
    scanf("%d",&len);
    if(len==0)
        return NULL;
    h = ( List )malloc( sizeof( struct Node ) );//建立头结点
    h->Next = NULL;
    last=h;
    while(len--)
    {
        scanf("%d %d",&d,&e);
        Attach(d,e,&last);
    }
    temp=h;
    h=h->Next;
    free(temp);
    return h;
}
void Print(List L)
{
    int flag=0;  //C中没有bool型,C++有
    if(!L)
    {
        printf("0 0\n");
        return;
    }
    while(L)
    {
        if(flag)
            printf(" %d %d",L->Data,L->Expon);
        else
        {
            printf("%d %d",L->Data,L->Expon);
            flag=1;
        }
        L=L->Next;
    }
    putchar('\n');
}
    
    
   
   
  
  


02-线性结构3 Reversing Linked List   (25分)

--参考http://www.cnblogs.com/kuotian/p/5269434.html

#include 
  
  
   
   
#include 
   
   
    
    

struct Node {
    int Address;
    int Data;
    int NextAddress;
    struct Node * Next;
};
typedef struct Node *List;

int main()
{
    List L, rear, temp, Ls, rear2, Lr, temp2;
    L=(List)malloc(sizeof(struct Node));
    L->Next=NULL;
    int FirstAddress,N,K;
    scanf("%d %d %d",&FirstAddress,&N,&K);
    rear=L;
    for(int i=0;i
    
    
     
     Address,&temp->Data,&temp->NextAddress);
        rear->Next=temp;
        rear=rear->Next;
    }
    rear->Next=NULL;
//    //测试(输出负数时格式不对
//    printf("测试1 :\n");
//    rear=L;
//    while(rear=rear->Next){
//        printf("%05d %d %05d\n", rear->Address, rear->Data, rear->NextAddress);
//    }
    //排序
    int addr=FirstAddress;
    int count=0;
    Ls=(List)malloc(sizeof(struct Node));
    Ls->Next=NULL;
    rear2=Ls;
    while(addr!=-1)
    {
        rear=L;
        while(rear->Next)
        {
            if(rear->Next->Address==addr)
            {
                rear2->Next=rear->Next;
                rear->Next=rear->Next->Next;
                rear2=rear2->Next;
                count++;
                addr=rear2->NextAddress;
            }
            else
                rear=rear->Next;
        }
    }
    rear2->Next=NULL;
    free(L);
//    //测试(输出负数时格式不对
//    printf("测试2 :\n");
//    rear2=Ls;
//    while(rear2=rear2->Next){
//        printf("%05d %d %05d\n", rear2->Address, rear2->Data, rear2->NextAddress);
//    }
    //Reversing
    Lr=(List)malloc(sizeof(struct Node));
    Lr->Next=NULL;
    rear=Lr;
    rear2=Ls;
    int n=count;
    while(n>=K)
    {
        n-=K;
        for(int i=0;i
     
     
      
      Next=rear2->Next;
            rear2->Next=rear2->Next->Next;
            if(i==0)
                temp=rear->Next;
            else
                rear->Next->Next=temp2;
            temp2=rear->Next;
        }
        temp->Next=rear2->Next;
        rear=temp;
    }
    rear=Lr->Next;
    while(rear->Next)
    {
        printf("%05d %d %05d\n", rear->Address, rear->Data, rear->Next->Address);
        rear=rear->Next;
    }
    printf("%05d %d -1\n", rear->Address, rear->Data);
    return 0;
}

     
     
    
    
   
   
  
  


02-线性结构4   Pop Sequence    ( 25 分)
--参考http://blog.csdn.net/jimko_penng/article/details/47815981

03-树1 树的同构   (25分)
--参考MOOC里的小白专场
#include
     
     
      
      
#define MaxTree 10
struct TreeNode
{
    char Element;
    int Left;
    int Right;
}T1[MaxTree],T2[MaxTree];
int BuildTree(struct TreeNode T[])
{
    int N,Root=-1,i;
    int check[MaxTree];
    char cl,cr;
    scanf("%d",&N);
    if(N)
    {
        for(i=0;i
      
      
     
     

03-树2 List Leaves   (25分)
--建树和广度优先遍历
#include
      
      
       
       
#include
       
       
        
        
#include
        
        
         
         
using namespace std;
#define MaxTree 10
struct TreeNode
{
    int Index;
    int Left;
    int Right;
}T[MaxTree];
int BuildTree(struct TreeNode T[])  //直接TreeNode T[]也行
{
    int N,Root=-1,i;
    int check[MaxTree];
    char cl,cr;
    scanf("%d",&N);
    if(N)
    {
        for(i=0;i
         
         
          
           q;
    q.push(T[Root]);
    while(!q.empty())
    {
        node=q.front();
        q.pop();
        if(node.Left==-1&&node.Right==-1)
        {
            if(!flag)
            {
                printf("%d",node.Index);
                flag=true;
            }
            else
                printf(" %d",node.Index);
        }
        else
        {
            if(node.Left!=-1)
                q.push(T[node.Left]);
            if(node.Right!=-1)
                q.push(T[node.Right]);
        }
    }
}
int main()
{
    int R;
    R=BuildTree(T);
    LevelOrderTraversal(R);
    return 0;
}

         
         
        
        
       
       
      
      

04-树4   是否同一棵二叉搜索树    ( 25 分)
--参考MOOC里的小白专场

#include
      
      
       
       
#include
       
       
        
        
typedef struct TreeNode *Tree;
struct TreeNode
{
    int Data;
    Tree Left;
    Tree Right;
    int Flag;
};
Tree NewNode(int d)
{
    Tree T=(Tree)malloc(sizeof(struct TreeNode));
    T->Data=d;
    T->Left=T->Right=NULL;
    T->Flag=0;
    return T;
}
Tree Insert(Tree T,int d)
{
    if(!T) T=NewNode(d);
    else
    {
        if(T->Data>d)
            T->Left=Insert(T->Left,d);
        else
            T->Right=Insert(T->Right,d);
    }
    return T;
}
Tree BuildTree(int N)
{
    Tree T;
    int d;
    scanf("%d",&d);
    T=NewNode(d);
    for(int i=1;i
        
        
         
         Flag)
    {
        if(T->Data>d) return Check(T->Left,d);
        else if(T->Data
         
         
          
          Right,d);
        else return 0;
    }
    else
    {
        if(T->Data==d)
        {
            T->Flag=1;
            return 1;
        }
        else
            return 0;
    }
}
int Isormorphic(Tree T,int N)
{
    int d,flag=0;  //flag=0表示一致
    scanf("%d",&d);
    if(T->Data!=d) flag=1;
    else T->Flag=1;
    for(int i=1;i
          
          
            Left) ResetFlag(T->Left); if(T->Right) ResetFlag(T->Right); T->Flag=0; } void FreeTree(Tree T) { if(T->Left) FreeTree(T->Left); if(T->Right) FreeTree(T->Right); free(T); } int main() { int N,L,i; Tree T; scanf("%d",&N); while(N) //N为0,输入结束 { scanf("%d",&L); T=BuildTree(N); for(i=0;i 
            
          
         
         
        
        
       
       
      
      

04-树5 Root of AVL Tree   (25分)
--参考MOOC:4.2 平衡二叉树
AVL树
#include
        
        
         
         
#include
         
         
          
            //malloc要用
typedef int ElementType;
typedef struct AVLNode * AVLTree; /* AVL树类型 */
struct AVLNode{
    ElementType Data; /* 结点数据 */
    AVLTree Left;     /* 指向左子树 */
    AVLTree Right;    /* 指向右子树 */
    int Height;       /* 树高 */
};

int Max ( int a, int b )
{
    return a > b ? a : b;
}
int GetHeight(AVLTree T)
{
    if(!T)
        return -1;
    else
        return T->Height;
}
AVLTree SingleLeftRotation ( AVLTree A )
{ /* 注意:A必须有一个左子结点B */
  /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */

    AVLTree B = A->Left;
    A->Left = B->Right;
    B->Right = A;
    A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
    B->Height = Max( GetHeight(B->Left), A->Height ) + 1;

    return B;
}
AVLTree SingleRightRotation ( AVLTree A )
{ /* 注意:A必须有一个右子结点B */
  /* 将A与B做右单旋,更新A与B的高度,返回新的根结点B */

    AVLTree B = A->Right;
    A->Right = B->Left;
    B->Left = A;
    A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
    B->Height = Max( GetHeight(B->Right), A->Height ) + 1;

    return B;
}
AVLTree DoubleLeftRightRotation ( AVLTree A )
{ /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
  /* 将A、B与C做两次单旋,返回新的根结点C */

    /* 将B与C做右单旋,C被返回 */
    A->Left = SingleRightRotation(A->Left);
    /* 将A与C做左单旋,C被返回 */
    return SingleLeftRotation(A);
}
AVLTree DoubleRightLeftRotation ( AVLTree A )
{ /* 注意:A必须有一个右子结点B,且B必须有一个左子结点C */
  /* 将A、B与C做两次单旋,返回新的根结点C */

    /* 将B与C做左单旋,C被返回 */
    A->Right = SingleLeftRotation(A->Right);
    /* 将A与C做右单旋,C被返回 */
    return SingleRightRotation(A);
}

AVLTree Insert( AVLTree T, ElementType X )
{ /* 将X插入AVL树T中,并且返回调整后的AVL树 */
    if ( !T ) { /* 若插入空树,则新建包含一个结点的树 */
        T = (AVLTree)malloc(sizeof(struct AVLNode));
        T->Data = X;
        T->Height = 0;
        T->Left = T->Right = NULL;
    } /* if (插入空树) 结束 */

    else if ( X < T->Data ) {
        /* 插入T的左子树 */
        T->Left = Insert( T->Left, X);
        /* 如果需要左旋 */
        if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 )
            if ( X < T->Left->Data )
               T = SingleLeftRotation(T);      /* 左单旋 */
            else
               T = DoubleLeftRightRotation(T); /* 左-右双旋 */
    } /* else if (插入左子树) 结束 */

    else if ( X > T->Data ) {
        /* 插入T的右子树 */
        T->Right = Insert( T->Right, X );
        /* 如果需要右旋 */
        if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 )
            if ( X > T->Right->Data )
               T = SingleRightRotation(T);     /* 右单旋 */
            else
               T = DoubleRightLeftRotation(T); /* 右-左双旋 */
    } /* else if (插入右子树) 结束 */

    /* else X == T->Data,无须插入 */

    /* 别忘了更新树高 */
    T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1;

    return T;
}
int main()
{
    int N,d;
    AVLTree T=NULL;  //不写NULL会出错哦
    scanf("%d",&N);
    for(int i=0;i
          
          
           
           Data);
    return 0;
}

          
          
         
         
        
        

05-树7   堆中的路径    ( 25 分)

--参考MOOC里的小白专场和5.1堆

最小堆

#include
    
    
     
     
#include
     
     
      
        //malloc要用
#define MaxSize 1001
typedef int ElementType;  //不能用#define 否则ElementType H[MaxSize];不能使用
#define MINDATA -10001  /* 该值应根据具体情况定义为小于堆中所有可能元素的值 */
ElementType H[MaxSize];

void Insert(int p,ElementType X)
{ /* 将元素X插入最小堆H,其中H[0]已经定义为哨兵 */
    int i=p;
    for ( ; H[i/2] > X; i/=2 )
        H[i] = H[i/2]; /* 上滤X */
    H[i] = X; /* 将X插入 */
}

void PercDown(int p,int n)
{ /* 下滤:将H中以H->Data[p]为根的子堆调整为最小堆 */
    int Parent, Child;
    ElementType X;
    X = H[p]; /* 取出根结点存放的值 */
    for( Parent=p; Parent*2<=n; Parent=Child ) {
        Child = Parent * 2;
        if( (Child!=n) && (H[Child]>H[Child+1]) )
            Child++;  /* Child指向左右子结点的较小者 */
        if( X <= H[Child] ) break; /* 找到了合适位置 */
        else  /* 下滤X */
            H[Parent] = H[Child];
    }
    H[Parent] = X;
}

void BuildHeap(int n)
{ /* 调整H->Data[]中的元素,使满足最小堆的有序性  */
    int i,x;
    H[0] = MINDATA; /* 定义"哨兵"为小于堆中所有可能元素的值*/
    for (i=1; i<=n; i++) {
        scanf("%d", &x);
        Insert(i,x);
    }
//    /* 从最后一个结点的父节点开始,到根结点1 */
//    for( i = n/2; i>0; i-- )
//        PercDown(i,n);
}
int main()
{
    int n, m, x, j;
    scanf("%d %d", &n, &m);
    BuildHeap(n); /* 堆初始化 */
    for (int i=0; i
      
      
       
       1) { /*沿根方向输出各结点*/
            j /= 2;
            printf(" %d", H[j]);
        }
        printf("\n");
    }
    return 0;
}

      
      
     
     
    
    


05-树8 File Transfer   (25分)

--参考MOOC里的小白专场和5.3 集合及运算

并查集

#include
      
      
       
       
#include
       
       
        
          //malloc要用
#define MAXN 10000                 /* 集合最大元素个数 */
typedef int ElementType;           /* 默认元素可以用非负整数表示 */
typedef ElementType SetType[MAXN]; /* 假设集合元素下标从0开始 */
//把根2连到根1上
void Union( SetType S, int Root1, int Root2 )
{
    S[Root2] = Root1;
}

int Find( SetType S, ElementType X )
{ /* 默认集合元素全部初始化为-1 */
    if ( S[X] < 0 ) /* 找到集合的根 */
        return X;
    else
        return S[X] = Find( S, S[X] ); /* 路径压缩 */
}
void Input_connection(SetType S)
{
    ElementType u,v;
    int root1,root2;
    scanf("%d %d",&u,&v);
    root1=Find(S,u-1);
    root2=Find(S,v-1);
    if(root1!=root2)
        Union(S,root1,root2);
}
void Check_connection(SetType S)
{
    ElementType u,v;
    int root1,root2;
    scanf("%d %d",&u,&v);
    root1=Find(S,u-1);
    root2=Find(S,v-1);
    if(root1==root2) printf("yes\n");
    else printf("no\n");
}
void Check_network(SetType S,int n)
{
    int count=0;
    for(int i=0;i
        
        
       
       
      
      

06-图1 列出连通集   (25分)
--参考MOOC和http://www.cnblogs.com/llhthinker/p/4844972.html
BFS和DFS
#include 
       
       
        
        
#include 
        
        
         
         
#include 
         
         
          
          
using namespace std;
#define MaxVertexNum 10 /* 最大顶点数设为100 */
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
int G[MaxVertexNum][MaxVertexNum]={0};
int Visited[MaxVertexNum];
int N;
void InitVisit()
{
    for (int i = 0; i < N; i++)
        Visited[i] = 0;
}
void DFS (int V)
{
    Visited[V] = 1;
    printf("%d ", V);
    for (int i=0;i
          
          
           
            q;
    q.push(V);
    while(!q.empty()){
        F=q.front();
        printf("%d ", F);
        q.pop();
        for (int i=0;i
           
           
          
          
         
         
        
        
       
       

06-图2 Saving James Bond - Easy Version (25分)
--参考MOOC:--6-3 应用实例:拯救007和http://blog.csdn.net/fanfan4569/article/details/53143205
无权图的最短路算法DFS
#include 
       
       
        
        
#include 
        
        
         
         
using namespace std;
#define MaxN 101
struct Node{
    int x;
    int y;
    bool visited;
}node[MaxN];

double GetDistance(int i,int j)
{
    return sqrt( pow(node[i].x - node[j].x, 2)
               + pow(node[i].y - node[j].y, 2) );
}
bool IsSafe(int i,int D)
{
    if(node[i].x-D<=-50||node[i].x+D>=50
       ||node[i].y-D<=-50||node[i].y+D>=50)
       return true;
    else return false;
}
bool DFS(int i,int N,int D){
    bool flag=false;
    node[i].visited=true;
    if(IsSafe(i,D)){
        return true;
    }
    for(int j = 1; j <= N; ++j){
        if(node[j].visited == false && GetDistance(j, i) <= D){
            flag=DFS(j,N,D);
            if(flag) break;
        }
    }
    return flag;
}
void Save007(int N,int D)
{
    bool flag=false;
    for(int i=1;i<=N;i++)
    {
        if(!node[i].visited&&7.5+D>=GetDistance(i,0))
        {
            flag=DFS(i,N,D);
            if(flag) break;
        }
    }
    if(flag) printf("Yes\n");
    else printf("No\n");
}
int main()
{
    int N,D,i;
    scanf("%d %d", &N,&D);
    node[0].x=node[0].y=0;
    node[0].visited=true;
    for ( i=1; i<=N; i++ )
    {
        scanf("%d %d", &node[i].x,&node[i].y);
        node[i].visited=false;
    }
    if(D+7.5>=50){
        printf("Yes\n");
        return 0;
    }
    Save007(N,D);
    return 0;
}

        
        
       
       

07-图4   哈利·波特的考试    ( 25 分)

--参考MOOC里的小白专场

有权图的多源最短路算法Floyd

#include 
        
        
         
         
#include 
         
         
          
          
#define MaxVertexNum 100 /* 最大顶点数设为100 */
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex; /* 用顶点下标表示顶点,为整型*/
typedef int WeightType; /* 边的权值设为整型*/

/* 边的定义*/
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2; /* 有向边
          
          
           
            */
    WeightType Weight; /* 权重*/
};
typedef PtrToENode Edge;

/* 图结点的定义*/
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv; /* 顶点数*/
    int Ne; /* 边数*/
    WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵*/
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型*/

MGraph CreateGraph( int VertexNum )
{ /* 初始化一个有VertexNum个顶点但没有边的图*/
    Vertex V, W;
    MGraph Graph;
    Graph = (MGraph)malloc(sizeof(struct GNode)); /* 建立图*/
    Graph->Nv = VertexNum;
    Graph->Ne = 0;
    /* 初始化邻接矩阵*/
    /* 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1) */
    for (V=0; V
           
           
            
            Nv; V++)
        for (W=0; W
            
            
              Nv; W++) Graph->G[V][W] = INFINITY; return Graph; } void InsertEdge( MGraph Graph, Edge E ) { /* 插入边 
             
               */ Graph->G[E->V1][E->V2] = E->Weight; /* 若是无向图,还要插入边 
              
                */ Graph->G[E->V2][E->V1] = E->Weight; } MGraph BuildGraph() { MGraph Graph; Edge E; int Nv, i; scanf("%d", &Nv); /* 读入顶点个数*/ Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图*/ scanf("%d", &(Graph->Ne)); /* 读入边数*/ if ( Graph->Ne != 0 ) { /* 如果有边*/ E = (Edge)malloc(sizeof(struct ENode)); /* 建立临时边结点*/ /* 读入边,格式为"起点终点权重",插入邻接矩阵*/ for (i=0; i 
               
                 Ne; i++) { scanf("%d %d %d", &E->V1, &E->V2, &E->Weight); /* 注意:如果权重不是整型,Weight的读入格式要改*/ E->V1--; E->V2--; //数组编号从0开始 InsertEdge( Graph, E ); } } return Graph; } /* 邻接矩阵存储 - 多源最短路算法 */ void Floyd( MGraph Graph, WeightType D[][MaxVertexNum] ) { Vertex i, j, k; /* 初始化 */ for ( i=0; i 
                
                  Nv; i++ ) for( j=0; j 
                 
                   Nv; j++ ) { D[i][j] = Graph->G[i][j]; } for( k=0; k 
                  
                    Nv; k++ ) for( i=0; i 
                   
                     Nv; i++ ) for( j=0; j 
                    
                      Nv; j++ ) if( D[i][k] + D[k][j] < D[i][j] ) { D[i][j] = D[i][k] + D[k][j]; } } WeightType FindMaxDist( WeightType D[][MaxVertexNum],Vertex i, int N ) { WeightType MaxDist; Vertex j; MaxDist = 0; for( j=0; j 
                     
                       MaxDist ) MaxDist = D[i][j]; return MaxDist; } void FindAnimal( MGraph Graph ) { WeightType D[MaxVertexNum][MaxVertexNum], MaxDist, MinDist; Vertex Animal, i; Floyd( Graph, D ); MinDist = INFINITY; for ( i=0; i 
                      
                        Nv; i++ ) { MaxDist = FindMaxDist( D, i, Graph->Nv ); if ( MaxDist == INFINITY ) { /* 说明有从i无法变出的动物*/ printf("0\n"); return; } if ( MinDist > MaxDist ) { /* 找到最长距离更小的动物*/ MinDist = MaxDist; Animal = i+1; /* 更新距离,记录编号*/ } } printf("%d %d\n", Animal, MinDist); } int main() { MGraph G = BuildGraph(); FindAnimal( G ); return 0; } 
                       
                      
                     
                    
                   
                  
                 
                
               
              
            
           
           
          
          
         
         
        
        

07-图6 旅游规划   (25分)
--参考MOOC里的小白专场和MOOC:7-1 最短路径问题
有权图的单源最短路算法 Dijkstra
#include 
         
         
          
          
#define MaxVertexNum 500 /* 最大顶点数设为100 */
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
#define Vertex int
#define ERROR -1
struct MGraph
{
    int length;
    int cost;
}G[MaxVertexNum][MaxVertexNum];
int collected[MaxVertexNum];  //全局变量自动初始化为0
int dist[MaxVertexNum];
int cost[MaxVertexNum];
int N;
/* 邻接矩阵存储 - 有权图的单源最短路算法 */

Vertex FindMinDist()
{ /* 返回未被收录顶点中dist最小者 */
    Vertex MinV, V;
    int MinDist = INFINITY;

    for (V=0; V
          
          
         
         

09-排序1 排序   (25分)

--参考MOOC课件(各种排序算法,不包括表排序。其中基数排序负数可以实现)


#include 
         
         
          
          
#include 
          
          
           
           
#define ElementType int
#define MaxN 100000
void Bubble_Sort(ElementType[],int);  //数据5,7,9超时,内存2MB
void Insertion_Sort(ElementType[],int);  //正确,用时6796ms(数据7),内存2M
void Shell_Sort(ElementType[],int);  //正确,用时87ms(数据5),内存2M
void Shell_Sort_Sedgewick(ElementType[],int);  //正确,用时54ms(数据5),内存2M
void Selection_Sort(ElementType[],int);  //正确,用时9237ms(数据9),内存2M
void Heap_Sort(ElementType[],int);  //正确,用时55ms(数据6),内存2M
void MergeSort(ElementType[],int);  //正确,用时54ms(数据5),内存2M
void Merge_Sort(ElementType[],int);  //正确,用时52ms(数据5),内存2M
void Quick_Sort(ElementType[],int);  //正确,Cutoff=20和50用时47ms,Cutoff=1000用时61ms(数据5),Cutoff=10000用时314ms,内存2M
/* 快速排序 - 直接调用库函数#include 
           
           
            
             */
/*---------------简单整数排序--------------------*/
int compare(const void *a, const void *b)
{ /* 比较两整数。非降序排列 */
    return (*(int*)a - *(int*)b);
}
///* 调用接口 */
//qsort(A, N, sizeof(int), compare);  //正确,用时53ms(数据5),内存2M
/*---------------简单整数排序--------------------*/
void LSDRadix_Sort(ElementType[],int);  //正确,用时377ms(数据9),内存5M

int main()
{
    int N;
    ElementType A[MaxN];
    scanf("%d",&N);
    for(int i=0;i
            
            
             
             0;i--)
    {
        flag=0;
        for(j=0;j
             
             
               A[j+1]) { Swap(&A[j],&A[j+1]); flag=1; } } if(flag==0) break; //一个循环全程无交换,则已有序 } } void Insertion_Sort(ElementType A[],int N) { int i,j; ElementType Tmp; for(i=1;i 
              
                0&&A[j-1]>Tmp;j--) A[j]=A[j-1]; A[j]=Tmp; } } void Shell_Sort(ElementType A[],int N) { int i,j,k; ElementType Tmp; for(i=N/2;i>0;i/=2) { for(j=i;j 
               
                 =i&&A[k-i]>Tmp;k-=i) A[k]=A[k-i]; A[k]=Tmp; } } } void Shell_Sort_Sedgewick(ElementType A[],int N) { int i,j,k,s; ElementType Tmp; int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0}; for(s=0;Sedgewick[s]>=N;s++); for(i=Sedgewick[s];i>0;i=Sedgewick[++s]) { for(j=i;j 
                
                  =i&&A[k-i]>Tmp;k-=i) A[k]=A[k-i]; A[k]=Tmp; } } } void Selection_Sort(ElementType A[],int N) { int MinPosition; for(int i=0;i 
                 
                   A[j]) MinPosition=j; Swap(&A[i],&A[MinPosition]); } } void PercDown( ElementType A[], int p, int N ) { /* 改编代码4.24的PercDown( MaxHeap H, int p ) */ /* 将N个元素的数组中以A[p]为根的子堆调整为最大堆 */ int Parent, Child; ElementType X; X = A[p]; /* 取出根结点存放的值 */ for( Parent=p; (Parent*2+1) 
                  
                    = A[Child] ) break; /* 找到了合适位置 */ else /* 下滤X */ A[Parent] = A[Child]; } A[Parent] = X; } void Heap_Sort( ElementType A[], int N ) { /* 堆排序 */ int i; for ( i=N/2-1; i>=0; i-- )/* 建立最大堆 */ PercDown( A, i, N ); for ( i=N-1; i>0; i-- ) { /* 删除最大堆顶 */ Swap( &A[0], &A[i] ); /* 见代码7.1 */ PercDown( A, 0, i ); } } /* 归并排序 - 递归实现 */ /* L = 左边起始位置, R = 右边起始位置, RightEnd = 右边终点位置*/ void Merge( ElementType A[], ElementType TmpA[], int L, int R, int RightEnd ) { /* 将有序的A[L]~A[R-1]和A[R]~A[RightEnd]归并成一个有序序列 */ int LeftEnd, NumElements, Tmp; int i; LeftEnd = R - 1; /* 左边终点位置 */ Tmp = L; /* 有序序列的起始位置 */ NumElements = RightEnd - L + 1; while( L <= LeftEnd && R <= RightEnd ) { if ( A[L] <= A[R] ) TmpA[Tmp++] = A[L++]; /* 将左边元素复制到TmpA */ else TmpA[Tmp++] = A[R++]; /* 将右边元素复制到TmpA */ } while( L <= LeftEnd ) TmpA[Tmp++] = A[L++]; /* 直接复制左边剩下的 */ while( R <= RightEnd ) TmpA[Tmp++] = A[R++]; /* 直接复制右边剩下的 */ for( i = 0; i < NumElements; i++, RightEnd -- ) A[RightEnd] = TmpA[RightEnd]; /* 将有序的TmpA[]复制回A[] */ } void Msort( ElementType A[], ElementType TmpA[], int L, int RightEnd ) { /* 核心递归排序函数 */ int Center; if ( L < RightEnd ) { Center = (L+RightEnd) / 2; Msort( A, TmpA, L, Center ); /* 递归解决左边 */ Msort( A, TmpA, Center+1, RightEnd ); /* 递归解决右边 */ Merge( A, TmpA, L, Center+1, RightEnd ); /* 合并两段有序序列 */ } } void MergeSort( ElementType A[], int N ) { /* 归并排序 */ ElementType *TmpA; TmpA = (ElementType *)malloc(N*sizeof(ElementType)); if ( TmpA != NULL ) { Msort( A, TmpA, 0, N-1 ); free( TmpA ); } else printf( "空间不足" ); } /* 归并排序 - 循环实现 */ /* 这里Merge函数在递归版本中给出 */ /* length = 当前有序子列的长度*/ void Merge_pass( ElementType A[], ElementType TmpA[], int N, int length ) { /* 两两归并相邻有序子列 */ int i, j; for ( i=0; i <= N-2*length; i += 2*length ) Merge( A, TmpA, i, i+length, i+2*length-1 ); if ( i+length < N ) /* 归并最后2个子列*/ Merge( A, TmpA, i, i+length, N-1); else /* 最后只剩1个子列*/ for ( j = i; j < N; j++ ) TmpA[j] = A[j]; } void Merge_Sort( ElementType A[], int N ) { int length; ElementType *TmpA; length = 1; /* 初始化子序列长度*/ TmpA = (ElementType*)malloc( N * sizeof( ElementType ) ); if ( TmpA != NULL ) { while( length < N ) { Merge_pass( A, TmpA, N, length ); length *= 2; Merge_pass( TmpA, A, N, length ); length *= 2; } free( TmpA ); } else printf( "空间不足" ); } /* 快速排序 */ ElementType Median3( ElementType A[], int Left, int Right ) { int Center = (Left+Right) / 2; if ( A[Left] > A[Center] ) Swap( &A[Left], &A[Center] ); if ( A[Left] > A[Right] ) Swap( &A[Left], &A[Right] ); if ( A[Center] > A[Right] ) Swap( &A[Center], &A[Right] ); /* 此时A[Left] <= A[Center] <= A[Right] */ Swap( &A[Center], &A[Right-1] ); /* 将基准Pivot藏到右边*/ /* 只需要考虑A[Left+1] … A[Right-2] */ return A[Right-1]; /* 返回基准Pivot */ } void Qsort( ElementType A[], int Left, int Right ) { /* 核心递归函数 */ int Pivot, Cutoff=50, Low, High; if ( Cutoff <= Right-Left ) { /* 如果序列元素充分多,进入快排 */ Pivot = Median3( A, Left, Right ); /* 选基准 */ Low = Left; High = Right-1; while (1) { /*将序列中比基准小的移到基准左边,大的移到右边*/ while ( A[++Low] < Pivot ) ; while ( A[--High] > Pivot ) ; if ( Low < High ) Swap( &A[Low], &A[High] ); else break; } Swap( &A[Low], &A[Right-1] ); /* 将基准换到正确的位置 */ Qsort( A, Left, Low-1 ); /* 递归解决左边 */ Qsort( A, Low+1, Right ); /* 递归解决右边 */ } else Insertion_Sort( A+Left, Right-Left+1 ); /* 元素太少,用简单排序 */ } void Quick_Sort( ElementType A[], int N ) { /* 统一接口 */ Qsort( A, 0, N-1 ); } /* 基数排序 - 次位优先 */ /* 假设元素最多有MaxDigit个关键字,基数全是同样的Radix */ #define MaxDigit 19 #define Radix 10 /* 桶元素结点 */ typedef struct Node *PtrToNode; struct Node { int key; PtrToNode next; }; /* 桶头结点 */ struct HeadNode { PtrToNode head, tail; }; typedef struct HeadNode Bucket[2*Radix-1]; int GetDigit ( int X, int D ) { /* 默认次位D=1, 主位D<=MaxDigit */ int d, i; for (i=1; i<=D; i++) { d = X % Radix; X /= Radix; } return d; } //这个代码已经改成负数也可使用了1-Radix~Radix-1(数组下标从0~Radix-2) void LSDRadix_Sort( ElementType A[], int N ) { /* 基数排序 - 次位优先 */ int D, Di, i; Bucket B; PtrToNode tmp, p, List,rear; for (i=0; i<2*Radix-1; i++) /* 初始化每个桶为空链表 */ B[i].head = B[i].tail = NULL; List = (PtrToNode)malloc(sizeof(struct Node)); List->next = NULL; rear=List; for (i=0; i 
                   
                     key = A[i]; tmp->next = NULL; rear->next = tmp; rear=tmp; } tmp=List; List=List->next; free(tmp); /* 下面开始排序 */ for (D=1; D<=MaxDigit; D++) { /* 对数据的每一位循环处理 */ /* 下面是分配的过程 */ p = List; while (p) { Di = GetDigit(p->key, D)+Radix-1; /* 获得当前元素的当前位数字 */ /* 从List中摘除 */ tmp = p; p = p->next; /* 插入B[Di]号桶尾 */ tmp->next = NULL; if (B[Di].head == NULL) B[Di].head = B[Di].tail = tmp; else { B[Di].tail->next = tmp; B[Di].tail = tmp; } } /* 下面是收集的过程 */ List = NULL; for (Di=2*Radix-2; Di>=0; Di--) { /* 将每个桶的元素顺序收集入List */ if (B[Di].head) { /* 如果桶不为空 */ /* 整桶插入List表头 */ B[Di].tail->next = List; List = B[Di].head; B[Di].head = B[Di].tail = NULL; /* 清空桶 */ } } } /* 将List倒入A[]并释放空间 */ for (i=0; i 
                    
                      next; A[i] = tmp->key; free(tmp); } } 
                     
                    
                   
                  
                 
                
               
             
            
            
           
           
          
          
         
         

11-散列1 电话聊天狂人   (25分)

--参考MOOC里的小白专场

#include 
         
         
          
          
#include 
          
          
           
           
#include 
           
           
            
            
#include 
            
            
             
             
#define KEYLENGTH 11 /* 关键词字符串的最大长度*/
#define MAXD 5
/* 关键词类型用字符串*/
typedef char ElementType[KEYLENGTH+1];
typedef int Index; /* 散列地址类型*/
typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
    int Count;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;
typedef struct TblNode *HashTable;
struct TblNode { /* 散列表结点定义*/
    int TableSize; /* 表的最大长度*/
    List Heads; /* 指向链表头结点的数组*/
};
#define MAXTABLESIZE 1000000
int NextPrime( int N )
{ /* 返回大于N且不超过MAXTABLESIZE的最小素数*/
    int i, p = (N%2)? N+2 : N+1; /*从大于N的下一个奇数开始*/
    while( p <= MAXTABLESIZE ) {
        for( i=(int)sqrt(p); i>2; i-- )
            if ( !(p%i) ) break; /* p不是素数*/
        if ( i==2 ) break; /* for正常结束,说明p是素数*/
        else p += 2; /* 否则试探下一个奇数*/
    }
    return p;
}
HashTable CreateTable( int TableSize )
{
    HashTable H;
    int i;
    H = (HashTable)malloc(sizeof(struct TblNode));
    H->TableSize = NextPrime(TableSize);
    H->Heads = (List)malloc(H->TableSize*sizeof(struct LNode));
    for( i=0; i
             
             
               TableSize; i++ ) { H->Heads[i].Data[0] = '\0'; H->Heads[i].Next = NULL; H->Heads[i].Count = 0; } return H; } int Hash ( int Key, int P ) { /* 除留余数法法散列函数*/ return Key%P; } Position Find( HashTable H, ElementType Key ) { Position P; Index Pos; /* 初始散列位置*/ Pos = Hash( atoi(Key+KEYLENGTH-MAXD), H->TableSize ); P = H->Heads[Pos].Next; /* 从该链表的第1个结点开始*/ /* 当未到表尾,并且Key未找到时*/ while( P && strcmp(P->Data, Key) ) P = P->Next; return P; /* 此时P或者指向找到的结点,或者为NULL */ } int Insert( HashTable H, ElementType Key ) { Position P, NewCell; Index Pos; P = Find( H, Key ); if ( !P ) { /* 关键词未找到,可以插入*/ NewCell = (Position)malloc(sizeof(struct LNode)); strcpy(NewCell->Data, Key); NewCell->Count = 1; Pos = Hash( atoi(Key+KEYLENGTH-MAXD), H->TableSize); /* 将NewCell插入为H->Heads[Pos]链表的第1个结点*/ NewCell->Next = H->Heads[Pos].Next; H->Heads[Pos].Next = NewCell; return 1; } else { P->Count++; return 0; } } void ScanAndOutput( HashTable H ) { int i, MaxCnt=0,PCnt = 0; ElementType MinPhone; List Ptr; MinPhone[0] = '\0'; for (i=0; i 
              
                TableSize; i++) { /* 扫描链表*/ Ptr = H->Heads[i].Next; while (Ptr) { if (Ptr->Count > MaxCnt) { /* 更新最大通话次数*/ MaxCnt = Ptr->Count; strcpy(MinPhone, Ptr->Data); PCnt = 1; } else if (Ptr->Count == MaxCnt) { PCnt ++; /* 狂人计数*/ if ( strcmp(MinPhone, Ptr->Data)>0 ) strcpy(MinPhone, Ptr->Data); /* 更新狂人的最小手机号码*/ } Ptr = Ptr->Next; } } printf("%s %d", MinPhone, MaxCnt); if( PCnt > 1 ) printf(" %d", PCnt); printf("\n"); } void DestroyTable( HashTable H ) { int i; Position P, Tmp; /* 释放每个链表的结点 */ for( i=0; i 
               
                 TableSize; i++ ) { P = H->Heads[i].Next; while( P ) { Tmp = P->Next; free( P ); P = Tmp; } } free( H->Heads ); /* 释放头结点数组 */ free( H ); /* 释放散列表结点 */ } int main() { int N, i; ElementType Key; HashTable H; scanf("%d", &N); H = CreateTable(N*2); /* 创建一个散列表*/ for (i=0; i 
                 
                
               
             
            
            
           
           
          
          
         
         

11-散列2 Hashing   (25分)

#include 
          
          
           
           
#include 
           
           
            
            
#include 
            
            
             
             
#define ElementType int
typedef struct TblNode *HashTable;
struct TblNode { /* 散列表结点定义*/
    int TableSize; /* 表的最大长度*/
    ElementType *Head; /* 指向数组*/
};
int flag=1;
int NextPrime(int n) {
    if(n == 1) return 2;
    int p = n%2==0 ? n+1 : n+2;
    int i;
    while(1) {
        for(i = (int)sqrt(p); i > 2; i--)
            if(p%i == 0) break;
        if(i == 2) break;
        else p += 2;
    }
    return p;
}
HashTable CreateTable( int TableSize )
{
    HashTable H;
    int i;
    H = (HashTable)malloc(sizeof(struct TblNode));
    H->TableSize = NextPrime(TableSize);
    H->Head = (ElementType *)malloc(H->TableSize*sizeof(ElementType));
    for( i=0; i
             
             
              
              TableSize; i++ )
        H->Head[i]=-1;
    return H;
}
int Hash ( int Key, int P )
{ /* 除留余数法法散列函数*/
    return Key%P;
}
int Find( HashTable H, ElementType Key )
{
    int pos,newPos;
    int cnt=0;  //冲突次数
    newPos=pos=Hash(Key,H->TableSize);
    while(H->Head[newPos]!=-1)
    {
        //Quadratic probing (with positive increments only)
        cnt++;
        newPos=(pos+cnt*cnt)%H->TableSize;
        if(cnt>=H->TableSize)
        {
            newPos=-1;
            break;
        }
    }
    return newPos;
}
void Insert( HashTable H, ElementType Key )
{
    int pos = Find( H, Key );
    if(flag==0)
        printf(" ");
    else
        flag=0;
    if(pos==-1)
        printf("-");
    else
    {
        H->Head[pos]=Key;
        printf("%d",pos);
    }
    return;
}
int main()
{
    int M, N,i;
    ElementType d;
    HashTable H;
    scanf("%d%d", &M,&N);
    H = CreateTable(M); /* 创建一个散列表*/
    for (i=0; i
              
              
             
             
            
            
           
           
          
          

11-散列4 Hashing - Hard Version   (30分)

--参考MOOC和http://blog.csdn.net/xijujie/article/details/53236387

散列表(数组num)、邻接表(vector g)、拓扑排序

#include 
           
           
            
            
#include 
            
            
             
             
#include 
             
             
              
              
using namespace std;
const int N=1000;
int num[N],indegree[N];  //indegree[i]记录了i的先驱的个数
struct cmp{
    bool operator()(int i,int j){
        return num[i]>num[j];  //优先队列从小到大
    }
};
int main()
{
    int n,i,j,k,flag=0;
    scanf("%d",&n);
    vector
              
              
               
               
                 > g(n); //邻接表 priority_queue 
                 
                 
                   ,cmp> q; //保存先驱为0的那些i for(i=0;i 
                  
                    -1) { j=num[i]%n; indegree[i]=(i-j+n)%n; if(indegree[i]) { for(k=0;k<=indegree[i];k++) g[(j+k)%n].push_back(i); } else q.push(i); } } while(!q.empty()) { i=q.top(); q.pop(); if(!flag) { flag=1; printf("%d",num[i]); } else printf(" %d",num[i]); for(j=0;j 
                    
                   
                  
                 
               
              
              
             
             
            
            
           
           

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值