中国大学MOOC_浙大数据结构_第三周编程作业
第三周编程作业
1、树的同构
利用结构数组表示二叉树。
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> // bool true false #define MAX 10 + 1 #define SIZE 26 + 1 #define NONE -1 struct RawData { char ch; int left; int right; // 用 -1 表示不存在 }; typedef struct RawData* MyRawData; struct Tree { int a; int b; }; typedef struct Tree* MyTree; MyRawData mrds1[MAX]; MyRawData mrds2[MAX]; MyTree tr1[SIZE] = {NULL}; MyTree tr2[SIZE] = {NULL}; void rawData2tree(int N, MyRawData mrds[], MyTree tr[]) { int k, temp; for (int i = 0; i != N; ++i) { // 1. 计算字母所对应的下标 k = mrds[i]->ch - 'A'; // 2. 初始化结点 tr[k] = (MyTree) malloc(sizeof(struct Tree)); tr[k]->a = NONE; tr[k]->b = NONE; // 3. 将子结点信息保存到当前下标的结点 if (mrds[i]->left != NONE) { tr[k]->a = mrds[mrds[i]->left]->ch; // 将 结点值 直接保存到 a b } if (mrds[i]->right != NONE) { tr[k]->b = mrds[mrds[i]->right]->ch; } // 4. 排序便于比较 if (tr[k]->a < tr[k]->b) { temp = tr[k]->a; tr[k]->a = tr[k]->b; tr[k]->b = temp; } } } bool check(MyTree tr1[], MyTree tr2[]) { for (int i = 0; i != SIZE; ++i) { if (tr1[i]) { // 相同结点是否存在? if (tr2[i]) { // 其子结点是否一致 if (tr1[i]->a == tr2[i]->a && tr1[i]->b == tr2[i]->b) { // } else { return false; } } else { return false; } } } return true; } int main() { int N; scanf("%d\n", &N); // \n不能漏!!!否则会被下面的scanf("%c", &c)读走! // 1. 保存原始数据 char c1, c2, c3; for (int i = 0; i != N; ++i) { mrds1[i] = (MyRawData) malloc(sizeof(struct RawData)); scanf("%c %c %c\n", &c1, &c2, &c3); mrds1[i]->ch = c1; mrds1[i]->left = c2 == '-' ? NONE : c2 - '0'; mrds1[i]->right = c3 == '-' ? NONE : c3 - '0'; } int N2; scanf("%d\n", &N2); if (N != N2) { printf("No"); return 0; } for (int i = 0; i != N2; ++i) { mrds2[i] = (MyRawData) malloc(sizeof(struct RawData)); scanf("%c %c %c\n", &c1, &c2, &c3); mrds2[i]->ch = c1; mrds2[i]->left = c2 == '-' ? NONE : c2 - '0'; mrds2[i]->right = c3 == '-' ? NONE : c3 - '0'; } // 2. 将树映射到以 结点值 为下标的数组中 rawData2tree(N, mrds1, tr1); rawData2tree(N, mrds2, tr2); // 3. 同一 下标的结点应该具有相同的子结点 printf("%s\n", check(tr1, tr2) ? "Yes" : "No"); return 0; }
2、List Leaves
层序遍历
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> // bool true false #include <memory.h> // memset 或者 <string.h> #define MAX_SIZE 10 + 1 int L[MAX_SIZE] = {-1}, R[MAX_SIZE] = {-1}; // R[MAX_SIZE] = {-1} 只有首个元素被初始化为 -1 int buildTree() { memset(L, -1, sizeof(L)); memset(R, -1, sizeof(R)); int N, tmpL, tmpR; scanf("%d\n", &N); for (int i = 0; i != N; ++i) { scanf("%c %c\n", &tmpL, &tmpR); if (tmpL != '-') { L[i] = tmpL - '0'; } if (tmpR != '-') { R[i] = tmpR - '0'; } } int root; int flag[MAX_SIZE]; memset(flag, 0, sizeof(flag)); for (int i = 0; i != N; ++i) { if (L[i] != -1) flag[L[i]] = 1; if (R[i] != -1) flag[R[i]] = 1; } for (int i = 0; i != N; ++i) { if (flag[i] == 0) { root = i; break; } } return root; } struct _Queue { int data[MAX_SIZE]; int front, rear; }; typedef struct _Queue* Queue; Queue buildQueue() { Queue q = (Queue) malloc(sizeof(struct _Queue)); q->front = q->rear = -1; return q; } void push(Queue q, int x) { q->rear++; q->data[q->rear] = x; } int pop(Queue q) { if (q->front + 1 > q->rear) return -1; q->front++; return q->data[q->front]; } int ans[MAX_SIZE]; void levelOrderTraversal(int root) { memset(ans, -1, sizeof(ans)); Queue q = buildQueue(); push(q, root); int x , i = 0; while ((x = pop(q)) != -1) { if (L[x] != -1) { push(q, L[x]); } if (R[x] != -1) { push(q, R[x]); } if (L[x] == -1 && R[x] == -1) { ans[i++] = x; } } } void printAns() { int k = 0; printf("%d", ans[0]); while (ans[++k] != -1) { printf(" %d", ans[k]); } } int main() { int root = buildTree(); levelOrderTraversal(root); printAns(); return 0; }
3、Tree Traversals Again
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #define MAX 100 typedef struct _BinTree* BinTree; typedef BinTree Node; struct _BinTree { int data; BinTree left; BinTree right; bool visited; }; Node buildNode(int data) { Node node = (Node) malloc(sizeof(struct _BinTree)); node->data = data; node->left = NULL; node->right = NULL; node->visited = false; return node; } typedef struct _Stack* Stack; struct _Stack { Node nodes[MAX]; int top; }; Stack buildStack() { Stack s = (Stack) malloc(sizeof(struct _Stack)); s->top = -1; return s; } bool push(Stack s, Node node) { if (s->top == MAX - 1) return false; s->nodes[++(s->top)] = node; return true; } bool isEmpty(Stack s) { return s->top == -1; } Node getTop(Stack s) { if (isEmpty(s)) return NULL; return s->nodes[s->top]; } Node pop(Stack s) { if (isEmpty(s)) return NULL; return s->nodes[(s->top)--]; } int ans[MAX]; int ans_i = 0; void postTraversal(Node root) { if (root) { postTraversal(root->left); postTraversal(root->right); ans[ans_i++] = root->data; } } int main() { BinTree root, tempNode, lastPop = NULL; int n, tempData; char ch[5]; scanf("%d", &n); scanf("%s %d", ch, &tempData); root = buildNode(tempData); Stack s = buildStack(); push(s, root); // 边模拟入栈出栈边构造树。 for (int i = 1; i != 2*n; ++i) { scanf("%s", ch); if (ch[1] == 'u') { scanf("%d", &tempData); tempNode = buildNode(tempData); if (lastPop != NULL) { lastPop->right = tempNode; lastPop = NULL; } else { getTop(s)->left = tempNode; } push(s, tempNode); } if (ch[1] == 'o') { lastPop = pop(s); } } postTraversal(root); for (int i = 0; i != n - 1; ++i) { printf("%d ", ans[i]); } printf("%d", ans[n - 1]); return 0; }
用堆栈实现后序遍历的非递归程序
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #define MAX 100 typedef struct _BinTree* BinTree; struct _BinTree { int data; BinTree left; BinTree right; }; typedef struct _Block* Block; struct _Block { // 代码块 BinTree node; int statement; }; typedef struct _Stack* Stack; struct _Stack { Block blocks[MAX]; int top; }; BinTree buildNode(int data) { BinTree node = (BinTree) malloc(sizeof(struct _BinTree)); node->data = data; node->left = NULL; node->right = NULL; return node; } Stack buildStack() { Stack s = (Stack) malloc(sizeof(struct _Stack)); s->top = -1; return s; } bool push(Stack s, Block b) { if (s->top == MAX - 1) return false; s->blocks[++(s->top)] = b; return true; } bool isEmpty(Stack s) { return s->top == -1; } Block getTop(Stack s) { if (isEmpty(s)) return NULL; return s->blocks[s->top]; } Block pop(Stack s) { if (isEmpty(s)) return NULL; return s->blocks[(s->top)--]; } Block buildBlock(BinTree node) { Block b = (Block) malloc(sizeof(struct _Block)); b->node = node; b->statement = 0; return b; } void inorderTraversal(BinTree root) { Block first = buildBlock(root); Stack s = buildStack(); push(s, first); Block curBlock; BinTree curNode; while (!isEmpty(s)) { curBlock = getTop(s); curNode = curBlock->node; if (curBlock->statement == 0) { curBlock->statement++; if (curNode->left != NULL) { push(s, buildBlock(curNode->left)); continue; // 将当前代码块暂时压入栈底,执行新的代码块 } } if (curBlock->statement == 1) { curBlock->statement++; printf("%d ", curNode->data); } if (curBlock->statement == 2) { curBlock->statement++; if (curNode->right != NULL) { push(s, buildBlock(curNode->right)); continue; } } pop(s); // 当前代码块相当于执行完了 } printf("(inorderTraversal)\n"); } void postorderTraversal(BinTree root) { Block first = buildBlock(root); Stack s = buildStack(); push(s, first); Block curBlock; BinTree curNode; while (!isEmpty(s)) { curBlock = getTop(s); curNode = curBlock->node; if (curBlock->statement == 0) { curBlock->statement++; if (curNode->left != NULL) { push(s, buildBlock(curNode->left)); continue; // 将当前代码块暂时压入栈底,执行新的代码块 } } if (curBlock->statement == 1) { curBlock->statement++; if (curNode->right != NULL) { push(s, buildBlock(curNode->right)); continue; } } if (curBlock->statement == 2) { curBlock->statement++; printf("%d ", curNode->data); } pop(s); // 压入栈底是因为没有执行完,而弹出则表示代码块执行完了。 } printf("(postorderTraversal)\n"); } int main() { BinTree root = buildNode(1); // 手动创建一棵树 BinTree node2 = buildNode(2); BinTree node3 = buildNode(3); BinTree node4 = buildNode(4); BinTree node5 = buildNode(5); BinTree node6 = buildNode(6); root->left = node2; root->right = node5; node2->left = node3; node2->right = node4; node5->left = node6; inorderTraversal(root); postorderTraversal(root); return 0; }