C语言中在做a%b模运算(取余)时,其中a是被除数,b是除数。在做%运算时,被除数和除数都是取正数运算,最后结果与被除数符号相同,如-7%5就是-2,7%(-5)就是2。【-7/5=-1,7/-5=-1】
malloc、qsort要用
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;
}
#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
#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;
}
#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;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
#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;
}
--参考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; i1) { /*沿根方向输出各结点*/
j /= 2;
printf(" %d", H[j]);
}
printf("\n");
}
return 0;
}
--参考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 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;
}
--参考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;
}
#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;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 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; 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 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; 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
--参考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