PTA-Data Structures and Algorithms (English)

目录

函数题

6-1 ~ 6-5

6-1 Deque

6-2 Two Stacks In One Array

6-3 Add Two Polynomials

6-4 Reverse Linked List

6-5 Evaluate Postfix Expression

6-6 ~ 6-10

6-6 Level-order Traversal

6-7 Isomorphic

6-8 Percolate Up and Down

6-9 Sort Three Distinct Keys

6-10 Strongly Connected Components

6-11 ~ 6-15

6-11 Shortest Path [1]

6-12 Shortest Path [2]

6-13 Topological Sort

6-14 Count Connected Components

6-15 Iterative Mergesort

6-16 ~ 6-17

6-16 Shortest Path [3]

6-17 Shortest Path [4]


即使你没有在PTA上做过题,也强烈建议你收藏下来,因为些代码都非常适合作为你学习数据结构的模板

题集链接:PTA | 程序设计类实验辅助教学平台 (pintia.cn)

函数题

6-1 ~ 6-5

6-1 Deque

Deque CreateDeque() {
    Deque q = (Deque)malloc(sizeof(struct DequeRecord));
    PtrToNode header = (PtrToNode)malloc(sizeof(struct Node));
    header->Next = header->Last = NULL;
    q->Front = q->Rear = header;
    return q;
}

int Push( ElementType X, Deque D ) {
    PtrToNode ptrToNewNode = (PtrToNode)malloc(sizeof(struct Node));
    ptrToNewNode->Element = X;
    ptrToNewNode->Next = D->Front->Next;
    ptrToNewNode->Last = D->Front;

    if (D->Front->Next)
        D->Front->Next->Last = ptrToNewNode;
    else
        D->Rear = ptrToNewNode;
    D->Front->Next = ptrToNewNode;
    return 1;
}

ElementType Pop( Deque D ) {
    if (D->Front == D->Rear) return ERROR;
    ElementType e = D->Front->Next->Element;
    D->Front->Next = D->Front->Next->Next;
    if (!D->Front->Next) D->Rear = D->Front;
    return e;
}

int Inject( ElementType X, Deque D ) {
    PtrToNode ptrToNewNode = (PtrToNode)malloc(sizeof(struct Node));
    ptrToNewNode->Element = X;
    ptrToNewNode->Next = NULL;
    ptrToNewNode->Last = D->Rear;
    D->Rear = D->Rear->Next = ptrToNewNode;
    return 1;
}

ElementType Eject( Deque D ) {
    if (D->Front == D->Rear) return ERROR;
    ElementType e = D->Rear->Element;
    D->Rear = D->Rear->Last;
    D->Rear->Next = NULL;
    return e;
}

6-2 Two Stacks In One Array

Stack CreateStack( int MaxElements ) {
    Stack stack = (Stack)malloc(sizeof(struct StackRecord));
    stack->Array = (ElementType*)calloc(MaxElements, sizeof(ElementType));
    stack->Top1 = -1, stack->Top2 = MaxElements;
    stack->Capacity = MaxElements;
    return stack;
}

int IsEmpty( Stack S, int Stacknum ) {
    return Stacknum == 1 ? S->Top1 == -1 : S->Top2 == S->Capacity;
}

int IsFull( Stack S ) {
    return S->Top1 + 1 == S->Top2;
}

int Push( ElementType X, Stack S, int Stacknum ) {
    if (S->Top1 + 1 == S->Top2) return 0;
    if (Stacknum == 1)
        S->Array[++S->Top1] = X;
    else
        S->Array[--S->Top2] = X;
    return 1;
}

ElementType Top_Pop( Stack S, int Stacknum ) {
    if (Stacknum == 1) {
        if (S->Top1 != -1) return S->Array[S->Top1--];
        else return ERROR;
    } else {
        if (S->Top2 != S->Capacity) return S->Array[S->Top2++];
        else return ERROR;
    }
    return ERROR;
}

6-3 Add Two Polynomials

Polynomial Add( Polynomial a, Polynomial b ) {
    Polynomial res = (Polynomial)malloc(sizeof(struct Node));
    PtrToNode p = res, p1 = a->Next, p2 = b->Next;
    while (p1 && p2) {
        PtrToNode t = (PtrToNode)malloc(sizeof(struct Node));
        if (p1->Exponent < p2->Exponent) {
            t->Coefficient = p2->Coefficient;
            t->Exponent = p2->Exponent;
            p2 = p2->Next;
        } else if (p1->Exponent > p2->Exponent) {
            t->Coefficient = p1->Coefficient;
            t->Exponent = p1->Exponent;
            p1 = p1->Next;
        } else {
            if (p1->Coefficient + p2->Coefficient == 0) {
                p1 = p1->Next;
                p2 = p2->Next;
                continue;
            }
            t->Coefficient = p1->Coefficient + p2->Coefficient;
            t->Exponent = p1->Exponent;
            p1 = p1->Next;
            p2 = p2->Next;
        }
        p = p->Next = t;
    }
    p->Next = NULL;
    if (p1) p->Next = p1;
    if (p2) p->Next = p2;
    return res;
}

6-4 Reverse Linked List

List Reverse( List L ) {
    List l = L->Next;
    if (!l) return L;
    PtrToNode left = NULL, mid = l, right = l->Next;
    while (right) {
        mid->Next = left;
        left = mid;
        mid = right;
        right = right->Next;
    }
    mid->Next = left;
    L->Next = mid;
    return L;
}

6-5 Evaluate Postfix Expression

ElementType parseNumber(char* p) {
    ElementType num = 0;
    int sign = 1;
    if (*p == '-') sign = -1, p++;
    while (*p && *p != ' ') {
        num = num * 10 + *p - '0';
        if (*++p == '.') break;
    }
    if (*p == '.') {
        double x = 0.1;
        while (*++p && *p != ' ') {
            num += (*p - '0') * x;
            x *= 0.1;
        }
    }
    return sign * num;
}

int isoperator(char* c) {
    if (*c == '-') return !isdigit(*(c + 1));
    return *c == '+' || *c == '*' || *c == '/';
}

ElementType eval(ElementType a, char op, ElementType b) {
    if (op == '+') return a + b;
    if (op == '-') return a - b;
    if (op == '*') return a * b;
    if (op == '/' && b) return a / b;
    return Infinity;
}

ElementType EvalPostfix( char *expr ) {
    int n = 0;
    ElementType stack[Max_Expr];
    for (char* p = expr; *p; p++) {
        if (*p == ' ') continue;
        if (isoperator(p)) {
            if (n <= 1) return Infinity;
            stack[n - 1] = eval(stack[n - 1], *p, stack[--n]);
            if (stack[n - 1] == Infinity) return Infinity;
        } else {
            stack[n++] = parseNumber(p);
            while (*(p + 1) && *(p + 1) != ' ') p++;
        }
    }
    if (n > 1) return Infinity;
    return stack[0];
}

6-6 ~ 6-10

6-6 Level-order Traversal

void Level_order ( Tree T, void (*visit)(Tree ThisNode) ) {
    if (!T) return;
    int h = 0, t = -1;
    Tree tree[MaxTree];
    tree[++t] = T;
    while (h <= t) {
        visit(tree[h]);
        if (tree[h]->Left) tree[++t] = tree[h]->Left;
        if (tree[h]->Right) tree[++t] = tree[h]->Right;
        h++;
    }
}

6-7 Isomorphic

int Isomorphic( Tree T1, Tree T2 ) {
    if (!T1 && !T2) return 1;
    if (!T1 || !T2 || T1->Element != T2->Element) return 0;
    return Isomorphic(T1->Left, T2->Left) && Isomorphic(T1->Right, T2->Right) || Isomorphic(T1->Left, T2->Right) && Isomorphic(T1->Right, T2->Left);
}

6-8 Percolate Up and Down

void PercolateUp( int p, PriorityQueue H ) {
    while (p > 1 && H->Elements[p] < H->Elements[p >> 1]) {
        ElementType t = H->Elements[p];
        H->Elements[p] = H->Elements[p >> 1];
        H->Elements[p >> 1] = t;
        p >>= 1;
    }
}

void PercolateDown( int p, PriorityQueue H ) {
    while (p <= H->Size / 2 && (H->Elements[p] > H->Elements[p << 1] || H->Elements[p] > H->Elements[p << 1 | 1])) {
        ElementType t = H->Elements[p];
        if (H->Elements[p << 1] <= H->Elements[p << 1 | 1]) {
            H->Elements[p] = H->Elements[p << 1];
            H->Elements[p << 1] = t;
        } else {
            H->Elements[p] = H->Elements[p << 1 | 1];
            H->Elements[p << 1 | 1] = t;
        }
        p <<= 1;
    }
}

6-9 Sort Three Distinct Keys

void MySort( ElementType A[], int N ) {
    int cnt[3];
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < N; i++) cnt[A[i]]++;
    cnt[2] += cnt[1];
    int j = 0;
    for (; j < cnt[1]; j++) A[j] = false;
    for (; j < cnt[2]; j++) A[j] = maybe;
    for (; j < N; j++) A[j] = true;
}

6-10 Strongly Connected Components

int num[MaxVertices], low[MaxVertices], dfsn, cnt;
int sccno[MaxVertices], st[MaxVertices], top, len[MaxVertices], nodes[MaxVertices][MaxVertices];

void dfs(Graph G, Vertex u) {
    st[top++] = u;
    low[u] = num[u] = ++dfsn;
    for (PtrToVNode p = G->Array[u]; p; p = p->Next) {
        Vertex v = p->Vert;
        if (!num[v]) dfs(G, v);
        if (!sccno[v] && low[v] < low[u]) low[u] = low[v];
    }
    if (num[u] != low[u]) return;
    cnt++;
    while (1) {
        Vertex v = st[--top];
        sccno[v] = cnt;
        nodes[cnt][len[cnt]++] = v;
        if (u == v) break;
    }
}

void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) ) {
    for (Vertex u = 0; u < G->NumOfVertices; u++)
        if (!num[u]) dfs(G, u);
    for (int i = 1; i <= cnt; i++) {
        for (int j = 0; j < len[i]; j++)
            visit(nodes[i][j]);
        printf("\n");
    }
}

6-11 ~ 6-15

6-11 Shortest Path [1]

/**
 * Nv:Number of vertexs
 * Ne: Number of edges
*/
#define INFINITY -1
typedef struct QNode* Queue;
struct QNode {
    Vertex* Data;
    Vertex front;
    Vertex rear;
};

Queue CreateQueue(int MaxSize) {
    Queue Q = (Queue)malloc(sizeof(struct QNode));
    Q->Data = (Vertex*)malloc(MaxSize * sizeof(Vertex));
    Q->front = Q->rear = 0;
    return Q;
}

bool IsEmpty(Queue Q) {
    return Q->front == Q->rear;
}

void AddQ(Queue Q, Vertex X) {
    Q->rear = (Q->rear + 1) % MaxVertexNum;
    Q->Data[Q->rear] = X;
}

Vertex DeleteQ(Queue Q) {
    Q->front = (Q->front + 1) % MaxVertexNum;
    return Q->Data[Q->front];
}

void ShortestDist(LGraph Graph, int dist[], Vertex S) {
    Vertex V;
    PtrToAdjVNode W;
    Queue Q;

    Q = CreateQueue(Graph->Nv);

    for (V = 0; V < Graph->Nv; V++)
        dist[V] = INFINITY;

    dist[S] = 0;
    AddQ(Q, S);

    while (!IsEmpty(Q)) {
        V = DeleteQ(Q);
        for (W = Graph->G[V].FirstEdge; W; W = W->Next)
            if (dist[W->AdjV] == INFINITY) {
                dist[W->AdjV] = dist[V] + 1;
                AddQ(Q, W->AdjV);
            }
    }
}

6-12 Shortest Path [2]

void ShortestDist( MGraph Graph, int dist[], Vertex S ) { // SPFA
    int q[100], h = 0, t = -1;
    bool inq[MaxVertexNum];
    for (int i = 0; i < Graph->Nv; i++) {
        inq[i] = false;
        dist[i] = INFINITY;
    }
    q[++t] = S;
    inq[S] = true;
    dist[S] = 0;
    while (h <= t) {
        int u = q[h++];
        inq[u] = false;
        for (int v = 0; v < Graph->Nv; v++) {
            if (Graph->G[u][v] == INFINITY) continue;
            if (dist[u] + Graph->G[u][v] < dist[v]) {
                dist[v] = dist[u] + Graph->G[u][v];
                if (!inq[v]) {
                    q[++t] = v;
                    inq[v] = true;
                }
            }
        }
    }
    for (int i = 0; i < Graph->Nv; i++)
        dist[i] = dist[i] == INFINITY ? -1 : dist[i];
}

6-13 Topological Sort

/**
 * Adjacency list
*/
bool TopSort( LGraph Graph, Vertex TopOrder[] ) {
    int indegree[Graph->Nv];
    for (Vertex u = 0; u < Graph->Nv; u++) indegree[u] = 0;
    for (Vertex u = 0; u < Graph->Nv; u++)
        for (PtrToAdjVNode p = Graph->G[u].FirstEdge; p; p = p->Next)
            indegree[p->AdjV]++;
    int q[100000], h = 0, t = -1, cnt = 0;
    for (Vertex u = 0; u < Graph->Nv; u++) 
        if (!indegree[u]) q[++t] = u;
    while (h <= t) {
        Vertex u = TopOrder[cnt++] = q[h++];
        for (PtrToAdjVNode p = Graph->G[u].FirstEdge; p; p = p->Next)
            if (!--indegree[p->AdjV]) q[++t] = p->AdjV;
    }
    if (cnt < Graph->Nv) return false;
    return true;
}

6-14 Count Connected Components

int find(Vertex u, int s[]) {
    return u == s[u] ? u : (s[u] = find(s[u], s));
}

int CountConnectedComponents( LGraph Graph ) {
    int s[Graph->Nv];
    for (Vertex u = 0; u < Graph->Nv; u++) s[u] = u;
    for (Vertex u = 0; u < Graph->Nv; u++) {
        for (PtrToAdjVNode p = Graph->G[u].FirstEdge; p; p = p->Next) {
            Vertex v = p->AdjV;
            s[find(v, s)] = find(u, s);
        }
    }
    int count = 0;
    for (Vertex u = 0; u < Graph->Nv; u++)
        if (s[u] == u) count++;
    return count;
}

6-15 Iterative Mergesort

#define min(a, b) (a <= b ? a : b)

void merge_pass( ElementType list[], ElementType sorted[], int N, int length ) {
    for (int i = 0, j = length, p = 0; i < N; i += 2 * length, j += 2 * length) {
        int l = i, r = j, to1 = i + length, to2 = min(j + length, N);
        while (l < to1 && r < to2) {
            if (list[l] <= list[r]) sorted[p++] = list[l++];
            else sorted[p++] = list[r++];
        }
        while (l < to1) sorted[p++] = list[l++];
        while (r < to2) sorted[p++] = list[r++];
    }
}

6-16 ~ 6-17

6-16 Shortest Path [3]

void ShortestDist( MGraph Graph, int dist[], int count[], Vertex S ) {
    bool collected[MaxVertexNum];
    Vertex V, W;
    for (V = 0; V < Graph->Nv; V++) {
        dist[V] = Graph->G[S][V];
        if (dist[V] < INFINITY) count[V] = 1;
        else count[V] = 0;
        collected[V] = false;
    }

    dist[S] = 0;
    collected[S] = true;
    count[S] = 1;

    while (true) {
        V = -1;
        for (W = 0; W < Graph->Nv; W++)
            if (collected[W] == false && (V == -1 || dist[W] < dist[V]))
                V = W;
        if (V == -1) break;
        collected[V] = true;
        for (W = 0; W < Graph->Nv; W++)
            if (collected[W] == false && Graph->G[V][W] < INFINITY)
                if (dist[V] + Graph->G[V][W] < dist[W]) {
                    dist[W] = dist[V] + Graph->G[V][W];
                    count[W] = count[V];
                } else if (dist[V] + Graph->G[V][W] == dist[W])
                    count[W] += count[V];
    }
    for (Vertex u = 0; u < Graph->Nv; u++)
        dist[u] = dist[u] == INFINITY ? -1 : dist[u];
}

6-17 Shortest Path [4]

void ShortestDist( MGraph Graph, int dist[], int path[], Vertex S ) {
    bool collected[MaxVertexNum];
    Vertex V, W;

    for (V = 0; V < Graph->Nv; V++) {
        dist[V] = Graph->G[S][V];
        if (dist[V] < INFINITY) path[V] = S;
        else path[V] = -1;
        collected[V] = false;
    }

    dist[S] = 0;
    collected[S] = true;
    path[S] = -1;

    while (true) {
        V = -1;
        for (W = 0; W < Graph->Nv; W++)
            if (collected[W] == false && (V == -1 || dist[W] < dist[V]))
                V = W;
        if (V == -1) break;
        collected[V] = true;
        for (W = 0; W < Graph->Nv; W++)
            if (collected[W] == false && Graph->G[V][W] < INFINITY)
                if (dist[V] + Graph->G[V][W] < dist[W]) {
                    dist[W] = dist[V] + Graph->G[V][W];
                    path[W] = V;
                }
    }
    for (Vertex u = 0; u < Graph->Nv; u++)
        dist[u] = dist[u] == INFINITY ? -1 : dist[u];
}

持续更新中~

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南宫谨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值