目录
6-5 Evaluate Postfix Expression
6-10 Strongly Connected Components
6-14 Count Connected Components
即使你没有在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];
}
持续更新中~