PTA浙大版《数据结构(第2版)》题目集 参考答案(编程题)

PTA浙大版《数据结构(第2版)》题目集 参考答案(编程题)

本答案配套详解教程专栏,专栏中对每个题目答案有更详细解析,欢迎订阅专栏。

专栏链接:PTA浙大版《数据结构(第2版)》题目集 详解教程_少侠PSY的博客-CSDN博客

实例1.1 最大子列和问题 (20 分)

#include<stdio.h>
int main(){
    
    
    int n,i,thissum,maxsum;
    thissum=maxsum=0;
    scanf("%d",&n);
    int list[n];
    for(i=0;i<n;i++)scanf("%d",&list[i]);
    for(i=0;i<n;i++){
    
    
        thissum+=list[i];
        if(thissum<0)thissum=0;
        else if(thissum>maxsum)maxsum=thissum;
    }
    printf("%d",maxsum);
    return 0;
}

习题2.1 简单计算器 (20 分)

#include<stdio.h>
int main(){
    
    
    int sum=0,a;
    char b;
    scanf("%d",&sum);
    scanf("%c",&b);
    while(b!='='){
    
    
        scanf("%d",&a);
        switch(b){
    
    
            case '+':sum+=a;break;
            case '-':sum-=a;break;
            case '*':sum*=a;break;
            case '/':
                if(a!=0)sum/=a;
                else{
    
    
                    printf("ERROR");
                    return 0;
                }
                break;
            default:printf("ERROR");return 0;
        }
        scanf("%c",&b);
    }
    printf("%d",sum);
    return 0;
}

习题2.2 数组循环左移 (20 分)

#include<stdio.h>
int main(){
    
    
    int m,n,temp,i,j;
    scanf("%d %d",&n,&m);
    int a[n];
    m=m%n;
    for(i=0;i<n;i++)scanf("%d",&a[i]);
    for(i=0;i<m;i++){
    
    
            temp=a[0];
        for(j=0;j<n;j++)a[j]=a[j+1];
        a[n-1]=temp;
    }
    printf("%d",a[0]);
    for(i=1;i<n;i++)printf(" %d",a[i]);
    return 0;
}

习题2.3 数列求和-加强版 (20 分)

#include<stdio.h>

int main(){
    
    
	int A,N,i,carry=0;//carry表示进位的数
	scanf("%d %d",&A,&N);
	if(N==0)printf("0");
    else{
    
    
        int a[N];
        for(i=0;i<N;i++){
    
    
            a[i]=(A*(N-i)+carry)%10;
            carry=(A*(N-i)+carry)/10;
        }
        if(carry)printf("%d",carry);
        for(i=N-1;i>=0;i--)printf("%d",a[i]);
    }
    return 0;
}

习题2.8 输出全排列

#include <stdio.h>

int visited[10]={
    
    0};
int  list[10];
void dfs(int n,int m){
    
    
    int i;
	if(m==n+1){
    
    
		for(int i=1;i<=n;i++)
			printf("%d",list[i]);
		printf("\n");
	}
	else{
    
    
		for(i=1;i<=n;i++){
    
    
			if(!visited[i]){
    
    
				list[m]=i;	
				visited[i]=1;
				dfs(n,m+1);	
				visited[i]=0;
			}
		}
	}
}
int main(){
    
    
	int n;
	scanf("%d", &n);
	dfs(n,1);
	return 0;
} 

习题3.4 最长连续递增子序列

#include<stdio.h>
int main(){
    
    
    int n,i,j=0,num=1,max=1;
    scanf("%d",&n);
    int a[n];
    for(i=0;i<n;i++)scanf("%d",&a[i]);
    if(n==1)printf("%d",a[0]);
    else{
    
    
        for(i=0;i<n-1;i++){
    
    
            if(a[i]<a[i+1]){
    
    
                num+=1;
                if(max<num){
    
    
                    max=num;
                    j=i+1;
                }
            }else num=1;
        }
        for(i=max;i>0;i--){
    
    
            printf("%d",a[j-i+1]);
            if(i>1)printf(" ");
        }
    }
    return 0;
}

习题3.6 一元多项式的乘法与加法运算

#include<stdio.h>
#include<stdlib.h>

typedef struct PolyNode* Polynomial;
struct PolyNode {
    
    
	int  Coef;
	int Expon;
	Polynomial Next;
};

typedef Polynomial PtrToPolyNode;

Polynomial Read();
void Attach(int coef, int expon, PtrToPolyNode* Rear);
Polynomial Mult(Polynomial P1, Polynomial P2);
Polynomial Add(Polynomial P1, Polynomial P2);
void PrintReslut(Polynomial P);

int main(){
    
    
	Polynomial P1, P2, PM, PA;
	P1 = Read();
	P2 = Read();
	PM = Mult(P1, P2);
	PA = Add(P1, P2);
	PrintReslut(PM);
	PrintReslut(PA);

	return 0;
}
Polynomial Read(){
    
    
	Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->Next = NULL;
	Polynomial Rear = P, t;
	int n, coef, expon;
	scanf("%d", &n);
	while (n--){
    
    
		scanf("%d %d", &coef, &expon);
		Attach(coef, expon, &Rear);
	}
	t = P;
	P = P->Next;
	free(t);
	return P;
}
void Attach(int coef, int expon, PtrToPolyNode* Rear){
    
    
	Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->Coef = coef;
	P->Expon = expon;
	P->Next = NULL;
	(*Rear)->Next = P;
	*Rear = P;
}
Polynomial Mult(Polynomial P1, Polynomial P2){
    
    
	if (!P1 || !P2) return NULL;
	Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->Next = NULL;
	Polynomial t1 = P1, t2 = P2, Rear = P, t;
	int coef, expon;

	while (t2){
    
    
		Attach(t1->Coef * t2->Coef, t1->Expon + t2->Expon, &Rear);
		t2 = t2->Next;
	}
	t1 = t1->Next;
	while (t1){
    
    
		t2 = P2;
		Rear = P;
		while (t2){
    
    
			coef = t1->Coef * t2->Coef;
			expon = t1->Expon + t2->Expon;
			while (Rear->Next && Rear->Next->Expon > expon)Rear = Rear->Next;
			if (Rear->Next && Rear->Next->Expon == expon){
    
    
				Rear->Next->Coef += coef;
				if (Rear->Next->Coef == 0){
    
    
					t = Rear->Next;
					Rear->Next = t->Next;
					free(t);
				}
			}else{
    
    
				t = (Polynomial)malloc(sizeof(struct PolyNode));
				t->Coef = coef;
				t->Expon = expon;
				t->Next = Rear->Next;
				Rear->Next = t;
			}
			t2 = t2->Next;
		}
		t1 = t1->Next;
	}
	t = P;
	P = P->Next;
	free(t);

	return P;
}
Polynomial Add(Polynomial P1, Polynomial P2){
    
    
	Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->Next = NULL;
	Polynomial Rear = P, t;

	while (P1 && P2){
    
    
		if (P1->Expon > P2->Expon){
    
    
			Attach(P1->Coef, P1->Expon, &Rear);
			P1 = P1->Next;
			
		}else if (P1->Expon < P2->Expon){
    
    
			Attach(P2->Coef, P2->Expon, &Rear);
			P2 = P2->Next;
			
		}else{
    
    
            if(P1->Coef+P2->Coef)
			Attach(P1->Coef+P2->Coef, P2->Expon, &Rear);
			P1 = P1->Next;
			P2 = P2->Next;
			
		}
	}
	while (P1){
    
    
		Attach(P1->Coef, P1->Expon, &Rear);
		P1 = P1->Next;
	}
	while (P2) {
    
    
		Attach(P2->Coef, P2->Expon, &Rear);
		P2 = P2->Next;
	}
	t = P;
	P = P->Next;
	free(t);
	return P;
}
void PrintReslut(Polynomial P){
    
    
	if (P == NULL) printf("0 0\n");
	else{
    
    
		printf("%d %d", P->Coef, P->Expon);
		P = P->Next;
		while (P){
    
    
			printf(" %d %d", P->Coef, P->Expon); 
			P = P->Next;
		}
		printf("\n");
	}
}

习题3.8 符号配对

#include <stdio.h>
#define MAXN 100

int S[MAXN], top, newline;
void push( int e );
void pop();
int token( char c );/
int check( int t );

int main() {
    
    
	char c;
	int t, out;
	newline = 1;
	top = -1;
	out = 0;
	while (1) {
    
    
		scanf("%c", &c);
		t = token(c);
		switch (t) {
    
    
			case 100:
				out = 1;
				break;
			case 0:
				newline = 1;
				break;
			default: {
    
    
				newline = 0;
				if (t > 10)
					out = check(t);
				break;
			}
		}
		if (out)
			break;
	}
	if (out == 1 && top == -1)
		printf("YES\n");
	else {
    
    
		printf("NO\n");
		if (out > 0) {
    
    
			switch (S[top]) {
    
    
				case 1:
					printf("/*");
					break;
				case 2:
					printf("{");
					break;
				case 3:
					printf("[");
					break;
				case 4:
					printf("(");
					break;
				default:
					break;
			}
			printf("-?\n");
		} else {
    
    
			printf("?-");
			if (t == 11)
				printf("*/\n");
			else
				printf("%c\n", c);
		}
	}
	return 0;
}

void push( int e ) {
    
    
	S[++top] = e;
}

void pop() {
    
    
	top--;
}

int token( char c ) {
    
    
	int t;
	if (c == '.' && newline) {
    
    
		scanf("%c", &c);
		t = token(c);
		if (!t)
			return 100;
		else
			return t;
	}
	switch (c) {
    
    
		case '\n':
			return 0; 
		case '{':
			push(2);
			return 2;
		case '[':
			push(3);
			return 3;
		case '(':
			push(4);
			return 4;
		case '/':
			scanf("%c", &c);
			if (c == '*') {
    
    
				push(1);
				return 1;
			} else
				return token(c);
		case '}':
			return 12;
		case ']':
			return 13;
		case ')':
			return 14;
		case '*':
			scanf("%c", &c);
			if (c == '/') {
    
    
				return 11;
			} else
				return token(c);
		default:
			return -1;
	}
}

int check( int t ) {
    
    
	if (top == -1)
		return -1;
	if (S[top] != (t - 10))
		return 1;
	else {
    
    
		pop();
		return 0;
	}
}

习题3.9 堆栈操作合法性

#include <stdio.h>

#define MAXS 101
#define MAXN 50

int S[MAXN], top, M;

int IsEmpty(){
    
    
    return (top==-1)? 1:0;
}

int IsFull(){
    
    
    return (top==M-1)? 1:0;
}

int push(){
    
    
    if (IsFull()) return 0;
    else {
    
     S[++top] = 1; return 1; }
}

int pop(){
    
    
     if (IsEmpty()) return 0;
     else {
    
     top--; return 1; }
}

int main(){
    
    
    int N, i, j;
    char str[MAXS];
    scanf("%d %d\n", &N, &M);
    for (i=0; i<N; i++) {
    
    
        scanf("%s", str);
        j = 0; top = -1;
        while (str[j]!='\0') {
    
    
           if ((str[j]=='S') && (!push())) break;
           if ((str[j]=='X') && (!pop())) break;
           j++;
        }
        if ((str[j]=='\0') && IsEmpty()) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

习题3.10 汉诺塔的非递归实现

#include<stdio.h>
#define MaxSize  100
typedef struct {
    
    
    int   N; 
    char  A; 
    char  B; 
    char  C; 
} ElementType;

ElementType ERROR;

typedef struct {
    
    
    ElementType Data[MaxSize];
    int Top;
} Stack;

void Push( Stack *PtrS, ElementType item ){
    
    
    if ( PtrS->Top == MaxSize-1 ) {
    
    
        printf("堆栈满");
        return;
    }
    else {
    
    
        PtrS->Data[++(PtrS->Top)] = item;
        return;
    }
}

ElementType Pop( Stack *PtrS ){
    
    
    if ( PtrS->Top == -1 ) {
    
    
        printf("堆栈空");
        return ERROR;
    }
    else {
    
    
        PtrS->Top --;
        return ( PtrS->Data[PtrS->Top+1] );
    }
}

void Hanoi( int n ) {
    
    
    ElementType P, toPush;
    Stack S;
    
    P.N = n;  P.A='a';  P.B='b';  P.C='c';
    S.Top= -1;

    Push(&S, P);
    while ( S.Top != -1 ) {
    
    
        P = Pop(&S);
        if ( P.N == 1)
            printf("%c -> %c\n", P.A, P.C);
        else {
    
    
            toPush.N = P.N - 1; toPush.A = P.B; toPush.B = P.A; toPush.C = P.C;
            Push( &S, toPush ); 
            toPush.N = 1; toPush.A = P.A; toPush.B = P.B; toPush.C = P.C;
            Push( &S, toPush ); 
            toPush.N = P.N - 1; toPush.A = P.A; toPush.B = P.C; toPush.C = P.B;
            Push( &S, toPush ); 
        }
    }
}

int main(){
    
    
    int n;
    ERROR.N = -1; 
    scanf("%d", &n);
    Hanoi(n);
    return 0;
}

习题3.11 表达式转换

#include <stdio.h>
#include <string.h>

#define MAXL 20
char S[MAXL];
int top = -1;

typedef enum {
    
    lparen, rparen, plus, minus, times, divide, eos, operand}
        Precedence;

Precedence P ( char op ){
    
    
	switch ( op ) {
    
    
	case '+':  	return  plus;
	case '-':  	return  minus;
	case '*':  	return  times;
	case '/':  	return  divide;
	case '\0':  return  eos;
	default:	return  operand;
	} 
}

void ToPostfix( char *expr ){
    
    
	int i, j, L;
	char pexpr[2*MAXL+2];

	i = j = 0; L = strlen(expr);
	while ( i<L ) {
    
    
		while (isdigit(expr[i]) || (expr[i]=='.'))
			pexpr[j++] = expr[i++];
		if (j && isdigit(pexpr[j-1]))
			pexpr[j++] = ' ';
		if (i==L) break;
			switch(expr[i]) {
    
    
			case '(': S[++top] = '('; break;
			case ')':
				while (S[top]!='(') {
    
    
					pexpr[j++] = S[top--];
					pexpr[j++] = ' ';
					if (top == -1) return;
				}
				top--;
				break;
			default:
				if ( !i || (!isdigit(expr[i-1]) && (expr[i-1]!=')')) ) {
    
    
					if (expr[i]=='+') break;
					else if (expr[i]=='-') {
    
     pexpr[j++] = expr[i]; break; }
				}
				while (top >-1 && S[top]!='(' && P(expr[i]) <= P(S[top])) {
    
    
					pexpr[j++] = S[top--]; 
					pexpr[j++] = ' ';
					if (top == -1) break;
				}
				S[++top] = expr[i];
				break;
			}
			i++;
	}
	while (top>-1) {
    
    
		pexpr[j++] = S[top--];
		pexpr[j++] = ' ';
	}
	pexpr[j-1] = '\0';
	printf("%s\n", pexpr);
}

int main(){
    
    
	char s[MAXL+1];
	int i = 0;

	scanf("%s", s);
	ToPostfix(s);
	return 0;
}

练习4.1 根据后序和中序遍历输出先序遍历

#include <stdio.h>
#include <stdlib.h>

#define MAXN 30

typedef struct TreeNode *Tree;
struct TreeNode {
    
    
    int Element;
    Tree  Left;
    Tree  Right;
};

Tree BuildTree( int inorder[], int postorder[], int N ){
    
    
     Tree T;
     int p;
     
     if (!N) return NULL;
     
     T = (Tree)malloc(sizeof(struct TreeNode));
     T->Element = postorder[N-1];
     T->Left = T->Right = NULL;
     for (p=0; p<N; p++)
         if (inorder[p]==postorder[N-1]) break;
     T->Left = BuildTree( inorder, postorder, p );
     T->Right = BuildTree( inorder+p+1, postorder+p, N-p-1 );
     return T;
}

void Preorder_output( Tree T ){
    
    
     if (!T) return;
     printf(" %d", T->Element);
     Preorder_output(T->Left);
     Preorder_output(T->Right);
}

int main(){
    
    
    Tree T;
    int inorder[MAXN], postorder[MAXN], N, i;

    scanf("%d", &N);
    for (i=0; i<N; i++) scanf("%d", &postorder[i]);
    for (i=0; i<N; i++) scanf("%d", &inorder[i]);
    T = BuildTree(inorder, postorder, N);
    printf("Preorder:");
    Preorder_output(T);   printf("\n");

    return 0;
}

练习4.2 平衡二叉树的根

#include <stdio.h>
#include <stdlib.h>

typedef struct Node *Tree;
struct Node {
    
    
	int key, h;
	Tree left, right;
};

int maxh( int h1, int h2 ){
    
    
	return h1<h2 ? h2:h1;
}

int Height( Tree T ){
    
    
	if (T) return T->h;
	else return -1;
}

Tree LL( Tree K2 ){
    
    
	Tree K1;
	K1 = K2->left;
	K2->left = K1->right;
	K1->right = K2;
	K2->h = maxh(Height(K2->left), Height(K2->right)) + 1;
	K1->h = maxh(Height(K1->left), K2->h) + 1;
	return K1;
}

Tree RR( Tree K2 ){
    
    
	Tree K1;
	K1 = K2->right;
	K2->right = K1->left;
	K1->left = K2;
	K2->h = maxh(Height(K2->left), Height(K2->right)) + 1;
	K1->h = maxh(Height(K1->right), K2->h) + 1;
	return K1;
}

Tree LR( Tree K3 ){
    
    
	Tree K1, K2;
	K1 = K3->left;
	K2 = K1->right;
	K1->right = K2->left;
	K3->left = K2->right;
	K2->left = K1;
	K2->right = K3;
	K1->h = maxh(Height(K1->left), Height(K1->right)) + 1;
	K3->h = maxh(Height(K3->left), Height(K3->right)) + 1;
	K2->h = maxh(K1->h, K3->h) + 1;
	return K2;
}

Tree RL( Tree K3 ){
    
    
	Tree K1, K2;
	K1 = K3->right;
	K2 = K1->left;
	K1->left = K2->right;
	K3->right = K2->left;
	K2->right = K1;
	K2->left = K3;
	K1->h = maxh(Height(K1->left), Height(K1->right)) + 1;
	K3->h = maxh(Height(K3->left), Height(K3->right)) + 1;
	K2->h = maxh(K1->h, K3->h) + 1;
	return K2;
}

Tree Insert( int K, Tree T ){
    
    
	if (!T) {
    
    
		T = malloc(sizeof(struct Node));
		T->key = K; T->h = 0;
		T->left = T->right = NULL;
	}
	else {
    
    
		if (K < T->key) {
    
    
			T->left = Insert(K, T->left);
			if (Height(T->left) - Height(T->right) > 1)
				if (K < T->left->key) T = LL(T);
				else T = LR(T);
		}
		else {
    
    
			T->right = Insert(K, T->right);
			if (Height(T->right) - Height(T->left) > 1)
				if (K > T->right->key) T = RR(T);
				else T = RL(T);
		}
		T->h = maxh(Height(T->left), Height(T->right)) + 1;
	}
	return T;
}

int main(){
    
    
	int N, K, i;
	Tree T = NULL;

	scanf("%d", &N);
	for (i=0; i<N; i++) {
    
    
		scanf("%d", &K);
		T = Insert(K, T);
	}
	printf("%d\n", T->key);

	return 0;
}

练习4.3 堆中的路径

#include <stdio.h>

#define MAXN 1001
#define MINH -10001

int H[MAXN], size;

void Create (){
    
    
	size = 0;
	H[0] = MINH;
}

void Insert ( int X ){
    
     
	int i;
	for (i=++size; H[i/2] > X; i/=2)
		H[i] = H[i/2];
	H[i] = X;
}

int main(){
    
    
	int n, m, x, i, j;

	scanf("%d %d", &n, &m);
	Create();
	for (i=0; i<n; i++) {
    
    
		scanf("%d", &x);
		Insert(x);
	}
	for (i=0; i<m; i++) {
    
    
		scanf("%d", &j);
		printf("%d", H[j]);
		while (j>1) {
    
    
			j /= 2;
			printf(" %d", H[j]);
		}
		printf("\n");
	}
	return 0;
}

习题4.5 顺序存储的二叉树的最近的公共祖先问题

#include <stdio.h>
#define MAXN 1001

int NCA( int T[], int p1, int p2){
    
    
    int p;
    
    while (p1 != p2) {
    
    
          if (p1 > p2) {
    
     p=p1; p1=p2; p2=p; }
          while (p2>p1) p2/=2;
    }
    return p1;
}

int main(){
    
    
    int n, i, T[MAXN];
    int p1, p2, p;
    
    T[0] = 0;
    scanf("%d", &n);
    for (i=1; i<=n; i++) scanf("%d", &T[i]);
    scanf("%d %d", &p1, &p2);
    if (!T[p1]) printf("ERROR: T[%d] is NULL\n", p1);
    else if (!T[p2]) printf("ERROR: T[%d] is NULL\n", p2);
    else {
    
    
         p = NCA(T, p1, p2);
         printf("%d %d\n", p, T[p]);
    }

    return 0;
}

习题5.13 词频统计

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef enum {
    
    false, true} bool;
#define MAXTable 50653 
#define KEYLENGTH 15                    
typedef char ElementType[KEYLENGTH+1]; 
typedef int Index;                     

typedef struct LNode *PtrToLNode;
struct LNode {
    
    
	ElementType Data;
	int Count;
	PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

typedef struct TblNode *HashTable; 
struct TblNode {
    
     
	int TableSize;
	List Heads; 
};

HashTable CreateTable(){
    
    
	HashTable H;
	int i;

	H = (HashTable)malloc(sizeof(struct TblNode));
	H->TableSize = MAXTable;
    H->Heads = (List)malloc(H->TableSize*sizeof(struct LNode));
    for( i=0; i<H->TableSize; i++ ) {
    
    
         H->Heads[i].Data[0] = '\0';
         H->Heads[i].Count = 0;
         H->Heads[i].Next = NULL;
    }
    return H;
}
int V ( char c ){
    
    
    if (c>='0' && c<='9') return (c-'0');
    if (c=='_') return 36;
    return (c-'a'+10);
}

int Hash( ElementType Key ){
    
    
    int i, h = 0;
    for (i=0; i<3; i++) {
    
    
        if (Key[i]=='\0') {
    
    
           h*=37;
           if (i<2) h*=37;
           break;
        }
        else h = h*37 + V(Key[i]);
    }
    return h;
}
 
bool IsWordChar( char c ){
    
    
	if ( (c>='a'&& c<='z') || (c>='A'&& c<='Z') || (c>='0'&& c<='9')|| (c == '_') )
		return true;
	else 
		return false;
}

#define MAXWORDLEN 80

int GetAWord( ElementType word ){
    
    
	char tempword[MAXWORDLEN+1], c;
	int len = 0; 

	scanf("%c", &c);
	while( c!='#' ){
    
    
		if( IsWordChar(c) ) {
    
     
		    if (c>='A' && c<='Z') c = c-'A'+'a';
			tempword[len++] = c;
        }
		scanf("%c", &c);
		if( len && !IsWordChar(c) )
			break;  
	}
	if (c=='#') return -1;
	tempword[len] = '\0';  
	if( len>KEYLENGTH ){
    
     
		tempword[KEYLENGTH] = '\0';
		len = KEYLENGTH;
	}
	strcpy(word, tempword);
	return len;		
}

void Show( HashTable H, double percent ){
    
    	int diffwordcount = 0; 
	int maxf = 0; 
	Position L;
	int i, j, k, lowerbound, count = 0;

	for( i=0; i<H->TableSize; i++ ) {
    
    
		diffwordcount += H->Heads[i].Count;
		L = H->Heads[i].Next; 
		while( L ){
    
     
			if( maxf<L->Count )  maxf = L->Count;
			L = L->Next;
		}
	} 
 
	printf("%d\n", diffwordcount);
	lowerbound = (int)((double)diffwordcount * percent);
    count = 0;
    for( j=maxf; j>=1; j-- ) {
    
    
		for( k=0; k<H->TableSize; k++ ) {
    
    
			L = H->Heads[k].Next; 
			while( L ){
    
    
				if( j==L->Count ) {
    
     
					printf("%d:%s\n", L->Count, L->Data);
					count++;
                }
                if (count == lowerbound) return;
                L = L->Next;
            }
        }
    }
}

Position Find( HashTable H, ElementType Key ){
    
    
    Position P;
    Index Pos;
    
    Pos = Hash( Key );
    P = H->Heads[Pos].Next; 
    while( P && strcmp(P->Data, Key) )
        P = P->Next;
    return P; 
}

void InsertAndCount( 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( Key ); 
        H->Heads[Pos].Count++; 
        P = H->Heads+Pos;
        while (P->Next && strcmp(P->Next->Data, Key)<0) P = P->Next;
        NewCell->Next = P->Next;
        P->Next = NewCell;
    }
    else {
    
    
        P->Count++;
    }
}

void DestroyTable( HashTable H ){
    
    
	int i;
	Position P, Tmp;
	for( i=0; i<H->TableSize; i++ ) {
    
    
		P = H->Heads[i].Next;
		while( P ) {
    
    
			Tmp = P->Next;
			free( P );
			P = Tmp;
		}
	}
	free( H->Heads );
	free( H );
}

int main(){
    
    
	HashTable H;
	ElementType word;
	int length;

	H = CreateTable();
	while(1){
    
    
		length = GetAWord( word );
		if( length>0 ){
    
    
			InsertAndCount( H, word ); 
		}
		else break;
	}
	Show( H, 10.0/100 ); 
	DestroyTable( H ); 
	return 0;
}

实例6.1 六度空间

#include<stdio.h>
#include<stdlib.h>

#define  MaxVertexNum  1000
#define ERROR -1
typedef enum {
    
    false, true} bool;
typedef int Vertex;
typedef Vertex ElementType;

typedef int Position;
struct QNode {
    
    
	ElementType *Data;
	Position Front, Rear;
	int MaxSize;
};
typedef struct QNode *Queue;

Queue CreateQueue( int MaxSize ){
    
    
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
	Q->Front = Q->Rear = -1;
	Q->MaxSize = MaxSize;
	return Q;
}

bool IsFull( Queue Q ){
    
    
	return ((Q->Rear+1)%Q->MaxSize == Q->Front);
}

bool AddQ( Queue Q, ElementType X ){
    
    
	if ( IsFull(Q) ) {
    
    
		printf("队列满");
		return false;
	}
	else {
    
    
		Q->Rear = (Q->Rear+1)%Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}

bool IsEmpty( Queue Q ){
    
    
	return (Q->Front == Q->Rear);
}

ElementType DeleteQ( Queue Q ){
    
    
	if ( IsEmpty(Q) ) {
    
     
		printf("队列空");
		return ERROR;
	}
	else  {
    
    
		Q->Front =(Q->Front+1)%Q->MaxSize;
		return  Q->Data[Q->Front];
	}
} 

typedef struct ENode *PtrToENode;
struct ENode{
    
    
    Vertex V1, V2;
};
typedef PtrToENode Edge;


typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    
    
	Vertex AdjV;		
	PtrToAdjVNode Next;	
};

typedef struct Vnode{
    
    
	PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

typedef struct GNode *PtrToGNode;
struct GNode{
    
      
	int Nv;
	int Ne;
	AdjList G;
};
typedef PtrToGNode LGraph;

#define SIX 6
int Visited[MaxVertexNum];

LGraph CreateGraph( int VertexNum ){
    
     
    Vertex V;
	LGraph Graph;
    
    Graph = (LGraph)malloc( sizeof(struct GNode) ); 
	Graph->Nv = VertexNum;
    Graph->Ne = 0;
   	for (V=0; V<Graph->Nv; V++)
		Graph->G[V].FirstEdge = NULL;
			
	return Graph; 
}
       
void InsertEdge( LGraph Graph, Edge E ){
    
    
    PtrToAdjVNode NewNode;
    
    NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode->AdjV = E->V2;
	NewNode->Next = Graph->G[E->V1].FirstEdge;
	Graph->G[E->V1].FirstEdge = NewNode;
		
    NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode->AdjV = E->V1;
	NewNode->Next = Graph->G[E->V2].FirstEdge;
	Graph->G[E->V2].FirstEdge = NewNode;
}

LGraph BuildGraph(){
    
    
	LGraph Graph;
	Edge E;
	int Nv, i;
	
	scanf("%d", &Nv);
	Graph = CreateGraph(Nv); 
	
	scanf("%d", &(Graph->Ne));
	if ( Graph->Ne != 0 ) {
    
    
	    E = (Edge)malloc( sizeof(struct ENode) );
	    for (i=0; i<Graph->Ne; i++) {
    
    
		    scanf("%d %d", &E->V1, &E->V2); 
			E->V1--; E->V2--;
            InsertEdge( Graph, E );
		}
	} 

	return Graph;
} 

void InitializeVisited( int Nv ){
    
    
	Vertex V;
	for ( V=0; V<Nv; V++ )
		Visited[V] = false;
}

int SDS_BFS( LGraph Graph, Vertex S ){
    
    
	Queue Q;
	Vertex V, Last, Tail;
	PtrToAdjVNode W;
	int Count, Level;

	Q = CreateQueue( MaxVertexNum );
	Visited[S] = true; 
	Count = 1;
	Level = 0;
	Last = S;
    AddQ (Q, S);
    
	while ( !IsEmpty(Q) ) {
    
    
		V = DeleteQ(Q);
		for( W=Graph->G[V].FirstEdge; W; W=W->Next ) {
    
    
			if ( !Visited[W->AdjV] ) {
    
    
				Visited[W->AdjV] = true;
				Count++;
				Tail = W->AdjV;
                AddQ (Q, W->AdjV);
			}
		}
		if ( V==Last ) {
    
    
			Level++;
			Last = Tail;
		}
		if ( Level==SIX ) break;
	}
	return Count;
}

void Six_Degrees_of_Separation( LGraph Graph ) {
    
    
	Vertex V;
	int count;

	for( V=0; V<Graph->Nv; V++ ) {
    
    
		InitializeVisited( Graph->Nv );
		count = SDS_BFS( Graph, V );
		printf("%d: %.2f%%\n", V+1, 100.0*(double)count/(double)Graph->Nv);
	}
}

int main(){
    
    
	LGraph G = BuildGraph();
	Six_Degrees_of_Separation(G);
	return 0;
}

练习7.1 排序

#include <stdio.h>
#define MAXN 100000
int A[MAXN];
void Insertion_Sort( int A[], int N ) {
    
    
    int P, i, Tmp;

	for ( P=1; P<N; P++ ) {
    
     
     Tmp = A[P];  
     for ( i=P; i>0 && A[i-1]>Tmp; i-- ) 
	A[i] = A[i-1]; 
     A[i] = Tmp;  
   }
}

int main(){
    
    
	int N, i;
	scanf("%d", &N);
	for (i=0; i<N; i++)
		scanf("%d", &A[i]);
	Insertion_Sort(A, N);
	printf("%d", A[0]);
	for (i=1; i<N; i++)
		printf(" %d", A[i]);
	printf("\n");

	return 0;
}

习题8.1 银行排队问题之单队列多窗口服务

#include <stdio.h>
#include <stdlib.h>

#define MAXN 1000
#define MaxWindow 10
#define MaxProc 60
typedef enum{
    
    false, true} bool;

typedef struct People ElementType;
struct People {
    
    
	int T;
	int P;
};

typedef int Position;
struct QNode {
    
    
	ElementType *Data; 
	Position Front, Rear; 
	int MaxSize; 
};
typedef struct QNode *Queue;

Queue CreateQueue( int MaxSize );
bool IsFull( Queue Q );
bool AddQ( Queue Q, ElementType X );
bool IsEmpty( Queue Q );
ElementType DeleteQ( Queue Q );

int FindNextWindow( int W[], int K, int *WaitTime ){
    
    
	int WinAvail;
	int MinW = MaxProc+1;
	int i;

	for ( i=0; i<K; i++ )
		if ( W[i] < MinW ) {
    
    
			MinW = W[i];  WinAvail = i;
		}
	*WaitTime = MinW;
	for ( i=0; i<K; i++ )
		W[i] -= MinW;

	return WinAvail; 
}

void QueueingAtBank( Queue Q, int N ){
    
     
	struct People Next;   
    int K;            
	int TotalTime;      
	int CurrentTime;
	int Window[MaxWindow];
	int WaitTime;  
	int WinAvail;    
	int i, j;
	int MaxWait; 
	int cnt[MaxWindow]; 

	scanf("%d", &K); 

	for ( i=0; i<K; i++ ) {
    
    
		Window[i] = 0;
		cnt[i] = 0;
    }
	TotalTime = CurrentTime = 0;
	MaxWait = 0;
	
	while ( !IsEmpty(Q) ) {
    
    

		WinAvail = FindNextWindow( Window, K, &WaitTime );
		CurrentTime += WaitTime;

		Next = DeleteQ(Q);
		if ( CurrentTime >= Next.T ) {
    
    
			TotalTime += (CurrentTime - Next.T);
			if ((CurrentTime - Next.T)>MaxWait)
			   MaxWait = (CurrentTime - Next.T);
        }
		else {
    
    
			WaitTime = Next.T - CurrentTime;
			for ( j=0; j<K; j++ ) {
    
     
				Window[j] -= WaitTime;
				if ( Window[j] <= 0 )  {
    
    
                     Window[j] = 0;
                     if (j < WinAvail) WinAvail = j;
                }
			}
			CurrentTime = Next.T;
		}
		Window[WinAvail] = Next.P;
		cnt[WinAvail]++;
	}
	WaitTime = 0;
	for (i=0; i<K; i++)
	    if (Window[i]>WaitTime) WaitTime = Window[i];
    CurrentTime += WaitTime;
	printf("%.1f %d %d\n", ((double)TotalTime/(double)N), MaxWait, CurrentTime);
	printf("%d", cnt[0]);
	for( i=1; i<K; i++) printf(" %d", cnt[i]);
	printf("\n");
}

int main(){
    
    
	int N; 
	Queue Q;
	int i;
	ElementType X;

	scanf("%d", &N);
	Q = CreateQueue(N+1); 

	for ( i=0; i<N; i++ ) {
    
    
		scanf("%d %d", &X.T, &X.P);
		if (X.P > MaxProc) X.P = MaxProc;
		AddQ(Q, X);
	}
	QueueingAtBank(Q, N);
	return 0;
}

Queue CreateQueue( int MaxSize ){
    
    
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
	Q->Front = Q->Rear = 0;
	Q->MaxSize = MaxSize;
	return Q;
}

bool IsFull( Queue Q ){
    
    
	return ((Q->Rear+1)%Q->MaxSize == Q->Front);
}

bool AddQ( Queue Q, ElementType X ){
    
    
	if ( IsFull(Q) ) {
    
    
		printf("队列满");
		return false;
	}
	else {
    
    
		Q->Rear = (Q->Rear+1)%Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}

bool IsEmpty( Queue Q ){
    
    
	return (Q->Front == Q->Rear);
}

ElementType DeleteQ( Queue Q ){
    
    
    Q->Front =(Q->Front+1)%Q->MaxSize;
    return  Q->Data[Q->Front];
}

习题8.2 银行排队问题之单队列多窗口加VIP服务

#include <stdio.h>
#include <stdlib.h>

#define MAXN 1000
#define MaxWindow 10
#define MaxProc 60

typedef enum {
    
    false, true} bool;

typedef struct People ElementType;
struct People {
    
     
    int T; 
    int P; 
    int VIP;
};

typedef int Position;
struct QNode {
    
    
    ElementType *Data;
    Position Front, Rear;
    int MaxSize;
    Position VIPFront, VIPRear;
    int *VIPCustomer;
    int VIPSize;
};

typedef struct QNode *Queue;

bool VIPIsFull(Queue Q);
bool AddVIP(Queue Q, Position P);
bool VIPIsEmpty(Queue Q);
ElementType DeleteVIP(Queue Q);

Queue CreateQueue(int MaxSize);
bool IsFull(Queue Q);
bool AddQ(Queue Q, ElementType X);
bool IsEmpty(Queue Q);
ElementType DeleteQ(Queue Q);

Queue CreateQueue(int MaxSize)
{
    
    
    Queue Q = (Queue)malloc(sizeof(struct QNode));
    Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
    Q->Front = Q->Rear = 0;
    Q->MaxSize = MaxSize;
    Q->VIPCustomer = (int *)malloc(MaxSize * sizeof(int));
    Q->VIPFront = Q->VIPRear = 0;
    Q->VIPSize = 0;
    return Q;
}

bool VIPIsFull(Queue Q)
{
    
    
    return (Q->VIPSize == (Q->MaxSize - 1));
}

bool AddVIP(Queue Q, Position P)
{
    
    
    if (VIPIsFull(Q)) {
    
    
        printf("VIP队列满");
        return false;
    } else {
    
    
        Q->VIPRear = (Q->VIPRear + 1) % Q->MaxSize;
        Q->VIPCustomer[Q->VIPRear] = P;
        Q->VIPSize++;
        return true;
    }
}

bool IsFull(Queue Q)
{
    
    
    return ((Q->Rear + 1) % Q->MaxSize == Q->Front);
}

bool AddQ(Queue Q, ElementType X)
{
    
    
    if (IsFull(Q)) {
    
    
        printf("队列满");
        return false;
    } else {
    
    
        Q->Rear = (Q->Rear + 1) % Q->MaxSize;
        Q->Data[Q->Rear] = X;
        if (X.VIP == 1) return AddVIP(Q, Q->Rear);
        else return true;
    }
}

bool IsEmpty(Queue Q)
{
    
    
    return (Q->Front == Q->Rear);
}

ElementType DeleteQ(Queue Q)
{
    
    
    ElementType X;
    while (!IsEmpty(Q) && (Q->Data[(Q->Front + 1) % Q->MaxSize].VIP == -1))
        Q->Front = (Q->Front + 1) % Q->MaxSize;
    if (IsEmpty(Q)) {
    
    
        X.T = -1;
        return X;
    }
    Q->Front = (Q->Front + 1) % Q->MaxSize;
    if (Q->Data[Q->Front].VIP == 1)
        X = DeleteVIP(Q);
    else
        X = Q->Data[Q->Front];
    return X;
}

bool VIPIsEmpty(Queue Q)
{
    
    
    return (Q->VIPSize == 0);
}

ElementType DeleteVIP(Queue Q)
{
    
    
    ElementType X;
    Position P;

    if (!VIPIsEmpty(Q)) {
    
    
        Q->VIPFront = (Q->VIPFront + 1) % Q->MaxSize;
        P = Q->VIPCustomer[Q->VIPFront];
        Q->VIPSize--;
        Q->Data[P].VIP = -1;
        X = Q->Data[P];
    } else
        X = DeleteQ(Q);

    return X;
}

bool IsVipHere(Queue Q, int CurrentTime)
{
    
    
    Position P;

    if (VIPIsEmpty(Q)) return false;
    P = Q->VIPCustomer[(Q->VIPFront + 1) % Q->MaxSize];
    if (Q->Data[P].T > CurrentTime) return false;
    else return true;
}

int FindNextWindow(int W[], int K, int *WaitTime)
{
    
    
    int WinAvail;
    int MinW = MaxProc + 1;
    int i;

    for (i = 0; i < K; i++)
        if (W[i] < MinW) {
    
    
            MinW = W[i];
            WinAvail = i;
        }
    *WaitTime = MinW;
    for (i = 0; i < K; i++)
        W[i] -= MinW;

    return WinAvail;
}

void QueueingAtBank(Queue Q, int N)
{
    
    
    struct People Next;
    int K;
    int TotalTime;
    int CurrentTime;
    int Window[MaxWindow];
    int WaitTime;
    int WinAvail;
    int i, j;
    int MaxWait;
    int cnt[MaxWindow];
    int VIPWindow;

    scanf("%d %d", &K, &VIPWindow);

    for (i = 0; i < K; i++) {
    
    
        Window[i] = 0;
        cnt[i] = 0;
    }
    TotalTime = CurrentTime = 0;
    MaxWait = 0;

    while (!IsEmpty(Q)) {
    
    
        WinAvail = FindNextWindow(Window, K, &WaitTime);
        CurrentTime += WaitTime;

        if ((WinAvail == VIPWindow) && (IsVipHere(Q, CurrentTime)))
            Next = DeleteVIP(Q);
        else
            Next = DeleteQ(Q);

        if (Next.VIP && (Window[VIPWindow] == 0)) WinAvail = VIPWindow;
        if (Next.T == -1) break;

        if (CurrentTime >= Next.T) {
    
    
            TotalTime += (CurrentTime - Next.T);
            if ((CurrentTime - Next.T) > MaxWait)
                MaxWait = (CurrentTime - Next.T);
        } else {
    
    
            WaitTime = Next.T - CurrentTime;
            for (j = 0; j < K; j++) {
    
    
                Window[j] -= WaitTime;
                if (Window[j] < 0) {
    
    
                    Window[j] = 0;
                    if (j < WinAvail) WinAvail = j;
                }
            }
            CurrentTime = Next.T;
        }

        if (Next.VIP && (Window[VIPWindow] == 0)) WinAvail = VIPWindow;
        Window[WinAvail] = Next.P;
        cnt[WinAvail]++;
    }
    WaitTime = 0;
    for (i = 0; i < K; i++)
        if (Window[i] > WaitTime) WaitTime = Window[i];
    CurrentTime += WaitTime;
    printf("%.1f %d %d\n", ((double)TotalTime / (double)N), MaxWait, CurrentTime);
    printf("%d", cnt[0]);
    for (i = 1; i < K; i++) printf(" %d", cnt[i]);
    printf("\n");
}

int main()
{
    
    
    int N;
    Queue Q;
    int i;
    ElementType X;

    scanf("%d", &N);
    Q = CreateQueue(N + 1);

    for (i = 0; i < N; i++) {
    
    
        scanf("%d %d %d", &X.T, &X.P, &X.VIP);
        if (X.P > MaxProc) X.P = MaxProc;
        AddQ(Q, X);
    }
    QueueingAtBank(Q, N);
    return 0;
}

习题8.3 银行排队问题之单窗口“夹塞” 版

#include <stdio.h>
#include <malloc.h>
#include <string.h>

#define MaxProc 60
#define MAXTEAM 100
#define MAXCHAR 3
#define MAXNAME 26426

struct People {
    
    
	char Name[MAXCHAR+1];
	int T;
	int P;
};

struct TeamQueueRecord {
    
    
	int Tfront;
	int Trear;
	int Tsize;
	struct People *Customer;
};
typedef struct TeamQueueRecord *TeamQueue;

struct QueueRecord {
    
    
	int front;
	int rear;
	int size;
	TeamQueue TeamQ;
};
typedef struct QueueRecord *Queue;

int Team[MAXNAME];
struct TeamNode {
    
    
	int Position;
	int Size;
} TeamInfo[MAXTEAM];


int NameHash( char name[] )
{
    
    
	int i, j;

	i = name[0] - 'A';
	j = 1;
	while (name[j]!='\0')
		i = (i<<5) + name[j++] - 'A';

	return i;
}

int Read_and_Set_Teams( int M )
{
    
    
	int L, MaxL;
	int i, j;
	char name[MAXCHAR+1];

	for (i=0; i<MAXNAME; i++)
		Team[i] = -1;

	MaxL = 0;
	for (i=0; i<M; i++) {
    
    
		scanf("%d ", &L);
		if (L > MaxL) MaxL = L;
		for (j=0; j<L; j++) {
    
    
			scanf("%s", name);
			Team[NameHash(name)] = i;
		}
	}
	for (i=0; i<M; i++) 
		TeamInfo[i].Size = 0;

	return MaxL;
}

Queue CreateQueue( int MaxQSize, int MaxTSize )
{
    
    
	Queue Q;
	int i;

	Q = malloc( sizeof( struct QueueRecord ) );
	Q->TeamQ = malloc( sizeof( struct TeamQueueRecord ) * MaxTSize );
	Q->size = 0;
	Q->front = 0;
	Q->rear = -1;
	for ( i=0; i<MaxTSize; i++ ) {
    
    
		Q->TeamQ[i].Customer = 
malloc( sizeof( struct People ) * MaxQSize );
		Q->TeamQ[i].Tsize = 0;
		Q->TeamQ[i].Tfront = 0;
		Q->TeamQ[i].Trear = -1;
	}

	return Q;
}

void AddQ( Queue Q, struct People X )
{
    
    
	int i, pos, r;

	if ( X.P > MaxProc )  X.P = MaxProc;
	i = Team[NameHash(X.Name)];
	if ( (i == -1) || (!TeamInfo[i].Size) ) {
    
    
		Q->rear++;
		r = ++Q->TeamQ[Q->rear].Trear;
		Q->TeamQ[Q->rear].Customer[r].T = X.T;
		Q->TeamQ[Q->rear].Customer[r].P = X.P;
		strcpy(Q->TeamQ[Q->rear].Customer[r].Name, X.Name);
		Q->TeamQ[Q->rear].Tsize++;
		Q->size++;
		if ( i != -1 ) {
    
    
			TeamInfo[i].Position = Q->rear;
			TeamInfo[i].Size++;
		}
	}
	else {
    
    
		pos = TeamInfo[i].Position;
		r = ++Q->TeamQ[pos].Trear;
		Q->TeamQ[pos].Customer[r].T = X.T;
		Q->TeamQ[pos].Customer[r].P = X.P;
		strcpy(Q->TeamQ[pos].Customer[r].Name, X.Name);
		Q->TeamQ[pos].Tsize++;
		TeamInfo[i].Size++;
	}
}

struct People FrontQ( Queue Q )
{
    
    
	struct People X;
	int f;

	f = Q->TeamQ[Q->front].Tfront;
	X.T = Q->TeamQ[Q->front].Customer[f].T;
	X.P = Q->TeamQ[Q->front].Customer[f].P;
	strcpy(X.Name, Q->TeamQ[Q->front].Customer[f].Name);

	return X;

}

void DeleteQ( Queue Q )
{
    
    
	int i, f;

	f = Q->TeamQ[Q->front].Tfront;
	Q->TeamQ[Q->front].Tfront++;
	Q->TeamQ[Q->front].Tsize--;
	i = Team[NameHash(Q->TeamQ[Q->front].Customer[f].Name)];
	if ( i != -1 ) TeamInfo[i].Size--;
	if ( !Q->TeamQ[Q->front].Tsize ) {
    
    
		Q->front++;
		Q->size--;
	}
}

int IsEmpty( Queue Q )
{
    
    
	return ( Q->size == 0 );
}

struct People Enter( int *i )
{
    
    
	struct People X;
	char c;

	if ((*i)) {
    
     
		scanf("%s %d %d%c", X.Name, &X.T, &X.P, &c);
		(*i)--;
	}
	else X.T = -1;

	return X;
}

double QueueingAtBank( Queue Q, int N )
{
    
    
	struct People Next, Wait;
	int TotalTime, CurrentTime;
	int i = N;

	TotalTime = CurrentTime = 0;

	Wait = Enter( &i );
	AddQ( Q, Wait );
	if (!i) {
    
    
		Next = FrontQ(Q);
		printf("%s\n", Next.Name);
		return 0.0;
	}
	else Wait = Enter( &i );
	while ( !IsEmpty(Q) || (Wait.T >= 0) ) {
    
    
		if ( !IsEmpty(Q) ) {
    
    
			Next = FrontQ(Q);
			printf("%s\n", Next.Name);
			if ( CurrentTime >= Next.T )
				TotalTime += (CurrentTime - Next.T);
			else
				CurrentTime = Next.T; 
			CurrentTime += Next.P; 
			while ( (Wait.T >= 0) && (Wait.T <= CurrentTime) ) {
    
    
				AddQ( Q, Wait );
				Wait = Enter( &i );
			}
			DeleteQ(Q);
		}
		else {
    
    
			AddQ( Q, Wait );
			Wait = Enter( &i );
		}
	}

	return ((double)TotalTime/(double)N);
}


int main()
{
    
    
	int N, M, MaxQSize;
	Queue Q;

	scanf("%d %d\n", &N, &M);
	MaxQSize = Read_and_Set_Teams(M);
	Q = CreateQueue( MaxQSize, N );
	printf("%.1lf\n", QueueingAtBank( Q, N ));

	return 0;
}

习题8.4 畅通工程之最低成本建设问题

#include <stdio.h>
#include <stdlib.h>

typedef enum {
    
    false, true} bool;
#define MaxVertexNum 1000
typedef int Vertex;
typedef int WeightType;

typedef struct ENode *PtrToENode;
struct ENode {
    
    
    Vertex V1, V2;
    WeightType Weight;
};
typedef PtrToENode Edge;

typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode {
    
    
    Vertex AdjV;
    WeightType Weight;
    PtrToAdjVNode Next;
};

typedef struct Vnode {
    
    
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

typedef struct GNode *PtrToGNode;
struct GNode {
    
    
    int Nv;
    int Ne;
    AdjList G;
};
typedef PtrToGNode LGraph;

LGraph CreateGraph(int VertexNum) {
    
    
    Vertex V;
    LGraph Graph;

    Graph = (LGraph)malloc(sizeof(struct GNode));
    Graph->Nv = VertexNum;
    Graph->Ne = 0;

    for (V = 0; V < Graph->Nv; V++)
        Graph->G[V].FirstEdge = NULL;

    return Graph;
}

void InsertEdge(LGraph Graph, Edge E) {
    
    
    PtrToAdjVNode NewNode;

    NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
    NewNode->AdjV = E->V2;
    NewNode->Weight = E->Weight;
    NewNode->Next = Graph->G[E->V1].FirstEdge;
    Graph->G[E->V1].FirstEdge = NewNode;

    NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
    NewNode->AdjV = E->V1;
    NewNode->Weight = E->Weight;
    NewNode->Next = Graph->G[E->V2].FirstEdge;
    Graph->G[E->V2].FirstEdge = NewNode;
}

LGraph BuildGraph() {
    
    
    LGraph Graph;
    Edge E;
    int Nv, i;

    scanf("%d", &Nv);
    Graph = CreateGraph(Nv);

    scanf("%d", &(Graph->Ne));
    if (Graph->Ne != 0) {
    
    
        E = (Edge)malloc(sizeof(struct ENode));
        for (i = 0; i < Graph->Ne; i++) {
    
    
            scanf("%d %d %d", &E->V1, &E->V2, &E->Weight);
            E->V1--;
            E->V2--;
            InsertEdge(Graph, E);
        }
    }
    return Graph;
}

void PercDown(Edge ESet, int p, int N) {
    
    
    int Parent, Child;
    struct ENode X;

    X = ESet[p];
    for (Parent = p; (Parent * 2 + 1) < N; Parent = Child) {
    
    
        Child = Parent * 2 + 1;
        if ((Child != N - 1) && (ESet[Child].Weight > ESet[Child + 1].Weight))
            Child++;
        if (X.Weight <= ESet[Child].Weight)
            break;
        else
            ESet[Parent] = ESet[Child];
    }
    ESet[Parent] = X;
}

void InitializeESet(LGraph Graph, Edge ESet) {
    
    
    Vertex V;
    PtrToAdjVNode W;
    int ECount;

    ECount = 0;
    for (V = 0; V < Graph->Nv; V++) {
    
    
        for (W = Graph->G[V].FirstEdge; W; W = W->Next) {
    
    
            if (V < W->AdjV) {
    
    
                ESet[ECount].V1 = V;
                ESet[ECount].V2 = W->AdjV;
                ESet[ECount++].Weight = W->Weight;
            }
        }
    }

    for (ECount = Graph->Ne / 2; ECount >= 0; ECount--)
        PercDown(ESet, ECount, Graph->Ne);
}

void Swap(Edge a, Edge b) {
    
    
    struct ENode t;
    t = *a;
    *a = *b;
    *b = t;
}

int GetEdge(Edge ESet, int CurrentSize) {
    
    
    Swap(&ESet[0], &ESet[CurrentSize - 1]);
    PercDown(ESet, 0, CurrentSize - 1);
    return CurrentSize - 1;
}

typedef Vertex ElementType;
typedef int SetName;
typedef ElementType SetType[MaxVertexNum];

void InitializeVSet(SetType S, int N) {
    
    
    int i;
    for (i = 0; i < N; i++)
        S[i] = -1;
}

SetName Find(SetType S, ElementType X) {
    
    
    if (S[X] < 0)
        return X;
    else
        return S[X] = Find(S, S[X]);
}

void Union(SetType S, SetName Root1, SetName Root2) {
    
    
    if (S[Root2] < S[Root1]) {
    
    
        S[Root2] += S[Root1];
        S[Root1] = Root2;
    } else {
    
    
        S[Root1] += S[Root2];
        S[Root2] = Root1;
    }
}

bool CheckCycle(SetType VSet, Vertex V1, Vertex V2) {
    
    
    Vertex Root1, Root2;

    Root1 = Find(VSet, V1);
    Root2 = Find(VSet, V2);

    if (Root1 == Root2)
        return false;
    else {
    
    
        Union(VSet, Root1, Root2);
        return true;
    }
}

int Kruskal(LGraph Graph) {
    
    
    WeightType TotalWeight;
    int ECount, NextEdge;
    SetType VSet;
    Edge ESet;

    InitializeVSet(VSet, Graph->Nv);
    ESet = (Edge)malloc(sizeof(struct ENode) * Graph->Ne);
    InitializeESet(Graph, ESet);

    TotalWeight = 0;
    ECount = 0;
    NextEdge = Graph->Ne;

    while (ECount < Graph->Nv - 1) {
    
    
        NextEdge = GetEdge(ESet, NextEdge);
        if (NextEdge < 0)
            break;

        if (CheckCycle(VSet, ESet[NextEdge].V1, ESet[NextEdge].V2) == true) {
    
    
            TotalWeight += ESet[NextEdge].Weight;
            ECount++;
        }
    }

    if (ECount < Graph->Nv - 1)
        TotalWeight = -1;

    return TotalWeight;
}

int main() {
    
    
    int w;
    LGraph G = BuildGraph();
    w = Kruskal(G);
    if (w == -1)
        printf("Impossible\n");
    else
        printf("%d\n", w);
    return 0;
}

习题8.5 畅通工程之局部最小花费问题

#include <stdio.h>

#define MAXN 101
#define INF 1000000000

int belongto[MAXN], newcost[MAXN][MAXN], cost[MAXN][MAXN];
int data[MAXN][MAXN];
int n, newn;

int min(int a, int b) {
    
    
    return (a < b) ? a : b;
}

long prim(int n, int mat[][MAXN]) {
    
    
    int min[MAXN];
    long ret = 0;
    int v[MAXN], i, j, k;
    for (i = 0; i < n; i++) {
    
    
        min[i] = INF;
        v[i] = 0;
    }
    for (min[j = 0] = 0; j < n; j++) {
    
    
        for (k = -1, i = 0; i < n; i++) {
    
    
            if (!v[i] && (k == -1 || min[i] < min[k])) {
    
    
                k = i;
            }
        }
        v[k] = 1;
        ret += min[k];
        for (i = 0; i < n; i++) {
    
    
            if (!v[i] && mat[k][i] < min[i]) {
    
    
                min[i] = mat[k][i];
            }
        }
    }
    return ret;
}

void dummy() {
    
    
    int i, j, temp;
    for (i = 0; i != newn; ++i) {
    
    
        for (j = 0; j != newn; ++j) newcost[i][j] = INF;
    }
    for (i = 0; i != n; ++i) --belongto[i];
    for (i = 0; i != n; ++i) {
    
    
        for (j = 0; j != n; ++j) {
    
    
            temp = min(cost[i][j], newcost[belongto[i]][belongto[j]]);
            newcost[belongto[i]][belongto[j]] = newcost[belongto[j]][belongto[i]] = temp;
        }
    }
}

int findComponents(int n, int mat[][MAXN], int *id) {
    
    
    int ret, k, i, j, m;
    for (k = 0; k < n; id[k++] = 0);
    for (ret = k = 0; k < n; k++) {
    
    
        if (!id[k]) {
    
    
            for (id[k] = -1, ret++, m = 1; m;) {
    
    
                for (m = i = 0; i < n; i++) {
    
    
                    if (id[i] == -1) {
    
    
                        for (m++, id[i] = ret, j = 0; j < n; j++) {
    
    
                            if (!id[j] && mat[i][j]) {
    
    
                                id[j] = -1;
                            }
                        }
                    }
                }
            }
        }
    }
    return ret;
}

int main() {
    
    
    int i;
    scanf("%d", &n);
    for (i = 0; i != n * (n - 1) / 2; ++i) {
    
    
        int x, y, t, link;
        scanf("%d %d %d %d", &x, &y, &t, &link);
        --x;
        --y;
        cost[x][y] = cost[y][x] = t;
        if (link) data[x][y] = data[y][x] = 1;
        else data[x][y] = data[y][x] = 0;
    }
    newn = findComponents(n, data, belongto);
    dummy();
    printf("%ld\n", prim(newn, newcost) % INF);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40171190/article/details/134147188