中国大学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
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;}
#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
#include#include #include using 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;}
--参考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
#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;}
--参考MOOC里的小白专场和5.1堆
最小堆
#include
--参考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
#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
#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;}
--参考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;}
#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;i 0;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;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 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; 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 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; 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
--参考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
- 中国大学MOOC-陈越、何钦铭-数据结构-2017春
- 中国大学MOOC-陈越、何钦铭-数据结构-2017春期中考试
- 中国大学MOOC-陈越、何钦铭-数据结构-2017春期末考试
- 中国大学MOOC-陈越、何钦铭-数据结构 List Leaves
- 中国大学MOOC-陈越、何钦铭-数据结构 File Transfer
- 中国大学MOOC-陈越、何钦铭-数据结构 统计工龄
- 中国大学MOOC-陈越、何钦铭-数据结构-2017秋 02-线性结构4 Pop Sequence
- 【中国大学MOOC-陈越、何钦铭-数据结构-2017秋】最大子列和问题
- 最大子列和问题(20) - 中国大学MOOC-陈越、何钦铭-数据结构基础习题集
- 中国大学MOOC-陈越、何钦铭-数据结构基础习题——总结
- 中国大学MOOC-陈越、何钦铭-数据结构基础习题集 00-自测1. 打印沙漏(20)
- 中国大学MOOC-陈越、何钦铭-数据结构 Maximum Subsequence Sum
- 中国大学MOOC-陈越、何钦铭-数据结构 一元多项式的乘法与加法运算
- 中国大学MOOC-陈越、何钦铭-数据结构 树的同构
- 中国大学MOOC-陈越、何钦铭-数据结构 是否同一棵二叉搜索树
- 中国大学MOOC-陈越、何钦铭-数据结构 Root of AVL Tree
- 中国大学MOOC-陈越、何钦铭-数据结构 堆中的路径
- 中国大学MOOC-陈越、何钦铭-数据结构 列出连通集
- STM32之EXTI——外部中断
- IOS--The sandbox is not in sync with the Podfile.lock.
- 李白喝酒问题
- 欢迎使用CSDN-markdown编辑器
- 支持向量机(SVM)、支持向量回归(SVR)
- 中国大学MOOC-陈越、何钦铭-数据结构-2017春
- Pythno3爬虫
- OkHttp和Gson
- poen 用法
- java的反射机制
- hdoj1026 Ignatius and the Princess I(图bfs+栈)
- Java IO 学习笔记五
- Tomcat配置虚拟路径,访问项目外的路径
- linux中sqoop部署以及实现mysql数据导入hive