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

来源:互联网 发布:字体管家软件pc 编辑:程序博客网 时间:2024/04/28 22:37

       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->ExponExpon)        {            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;iAddress,&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;iNext=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 10struct 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#includeusing namespace std;#define MaxTree 10struct 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#includetypedef 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;iFlag)    {        if(T->Data>d) return Check(T->Left,d);        else if(T->DataRight,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;iLeft) 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;iData);    return 0;}

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

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

最小堆

#include#include  //malloc要用#define MaxSize 1001typedef 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; i1) { /*沿根方向输出各结点*/            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 101struct 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; VNv; V++)        for (W=0; WNv; 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; iNe; 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; iNv; i++ )        for( j=0; jNv; j++ ) {            D[i][j] = Graph->G[i][j];        }    for( k=0; kNv; k++ )        for( i=0; iNv; i++ )            for( j=0; jNv; 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; jMaxDist )            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; iNv; 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 -1struct MGraph{    int length;    int cost;}G[MaxVertexNum][MaxVertexNum];int collected[MaxVertexNum];  //全局变量自动初始化为0int 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 100000void Bubble_Sort(ElementType[],int);  //数据5,7,9超时,内存2MBvoid Insertion_Sort(ElementType[],int);  //正确,用时6796ms(数据7),内存2Mvoid Shell_Sort(ElementType[],int);  //正确,用时87ms(数据5),内存2Mvoid Shell_Sort_Sedgewick(ElementType[],int);  //正确,用时54ms(数据5),内存2Mvoid Selection_Sort(ElementType[],int);  //正确,用时9237ms(数据9),内存2Mvoid Heap_Sort(ElementType[],int);  //正确,用时55ms(数据6),内存2Mvoid MergeSort(ElementType[],int);  //正确,用时54ms(数据5),内存2Mvoid Merge_Sort(ElementType[],int);  //正确,用时52ms(数据5),内存2Mvoid 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),内存5Mint main(){    int N;    ElementType A[MaxN];    scanf("%d",&N);    for(int i=0;i0;i--)    {        flag=0;        for(j=0;jA[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;i0&&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;iA[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; ikey = 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; inext;        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 1000000int 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; iTableSize; 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; iTableSize; 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; iTableSize; 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 inttypedef 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; iTableSize; 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

阅读全文
0 0
原创粉丝点击