diff --git a/CLion/ExerciseBook/06.33-06.34/06.33-06.34.c b/CLion/ExerciseBook/06.33-06.34/06.33-06.34.c new file mode 100644 index 0000000..303a2ae --- /dev/null +++ b/CLion/ExerciseBook/06.33-06.34/06.33-06.34.c @@ -0,0 +1,102 @@ +#include +#include "Status.h" //**▲01 绪论**// + +/* 元素最大数量 */ +#define MAX 100 + +/* + * 根据左/右孩子列表,判断u是否为v的子孙 + */ +Status Algo_6_33(int L[MAX + 1], int R[MAX + 1], int u, int v); + +/* + * 根据双亲结点列表,判断u是否为v的子孙 + */ +Status Algo_6_34(int T[MAX + 1], int u, int v); + + +int main(int argc, char* argv[]) { + int T[MAX + 1] = {0, 0, 1, 1, 2, 2, 3, 5, 5, 6}; // 0号单元弃用 + int L[MAX + 1] = {0, 2, 4, 6, 0, 7, 0, 0, 0, 0}; + int R[MAX + 1] = {0, 3, 5, 0, 0, 8, 9, 0, 0, 0}; + int u, v; + + printf("作为示例,建立如下的树:\n"); + printf(" → 1 2 3 4 5 6 7 8 9\n"); // 序号 + printf("T[n]→ 0 1 1 2 2 3 5 5 6\n"); // 双亲结点列表 + printf("L[n]→ 2 4 6 0 7 0 0 0 0\n"); // 左孩子列表 + printf("R[n]→ 3 5 0 0 8 9 0 0 0\n"); // 右孩子列表 + printf("\n"); + + printf("请输入需要验证的子孙及祖先...\n\n"); + + printf("子孙(1~9) u = "); + scanf("%d", &u); + printf("祖先(1~9) v = "); + scanf("%d", &v); + printf("\n"); + + printf("███题 6.33 验证...███\n"); + { + if(Algo_6_33(L, R, u, v) == TRUE) { + printf("u=%d 是 v=%d 的子孙!\n", u, v); + } else { + printf("u=%d 不是 v=%d 的子孙!!\n", u, v); + } + + printf("\n"); + } + + + printf("███题 6.34 验证...███\n"); + { + if(Algo_6_34(T, u, v) == TRUE) { + printf("u=%d 是 v=%d 的子孙!\n", u, v); + } else { + printf("u=%d 不是 v=%d 的子孙!!\n", u, v); + } + + printf("\n"); + } + + return 0; +} + + +/* + * 根据左/右孩子列表,判断u是否为v的子孙 + */ +Status Algo_6_33(int L[MAX + 1], int R[MAX + 1], int u, int v) { + // 如果u是v的孩子 + if(L[v] == u || R[v] == u) { + return TRUE; + } else { + // 如果存在左孩子,向左搜索 + if(L[v]!=0 && Algo_6_33(L, R, u, L[v])==TRUE) { + return TRUE; + } + + // 如果存在右孩子,向左搜索 + if(R[v]!=0 && Algo_6_33(L, R, u, R[v])==TRUE) { + return TRUE; + } + } + + return FALSE; +} + +/* + * 根据双亲结点列表,判断u是否为v的子孙 + */ +Status Algo_6_34(int T[MAX + 1], int u, int v) { + // 如果u的双亲是v + if(T[u] == v) { + return TRUE; + } else { + if(T[u] != 0 && Algo_6_34(T, T[u], v) == TRUE) { + return TRUE; + } + } + + return FALSE; +} diff --git a/CLion/ExerciseBook/06.33-06.34/CMakeLists.txt b/CLion/ExerciseBook/06.33-06.34/CMakeLists.txt new file mode 100644 index 0000000..09d3349 --- /dev/null +++ b/CLion/ExerciseBook/06.33-06.34/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.33-06.34 06.33-06.34.c) +# 链接公共库 +target_link_libraries(06.33-06.34 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/06.35/06.35.c b/CLion/ExerciseBook/06.35/06.35.c new file mode 100644 index 0000000..f1309b0 --- /dev/null +++ b/CLion/ExerciseBook/06.35/06.35.c @@ -0,0 +1,45 @@ +#include + +/* 结点数量 */ +#define N 15 + +/* + * 求符合题意的整数值 + */ +int Algo_6_35(char* BiTree, int i); + + +int main(int argc, char* argv[]) { + // 顺序存储的二叉树(结点从0号单元开始存储) + char BiTree[N] = {'A', 'B', 'C', 'D', 'E', 'F', '\0', 'G', '\0', 'H', 'I', '\0', 'J', '\0', '\0'}; + int i, j; + + printf("作为示例,建立二叉树的顺序存储结构(^代表空字符,即此处没有结点信息):ABCDEF^G^HI^J^^"); + printf("\n"); + + printf("请输入结点索引(0~%d):", N); + scanf("%d", &i); + printf("\n"); + + j = Algo_6_35(BiTree, i); + + if(j != -1) { + printf("结点 %d 对应的十进制整数为 %d 。\n", i, j); + } else { + printf("此处结点不存在!\n"); + } + + return 0; +} + + +/* + * 求符合题意的整数值 + */ +int Algo_6_35(char* BiTree, int i) { + if(BiTree[i] == '\0') { + return -1; // 此处不存在结点 + } + + return i + 1; +} diff --git a/CLion/ExerciseBook/06.35/CMakeLists.txt b/CLion/ExerciseBook/06.35/CMakeLists.txt new file mode 100644 index 0000000..2597089 --- /dev/null +++ b/CLion/ExerciseBook/06.35/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.35 06.35.c) +# 链接公共库 +target_link_libraries(06.35 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/06.36/06.36.c b/CLion/ExerciseBook/06.36/06.36.c new file mode 100644 index 0000000..cd2e140 --- /dev/null +++ b/CLion/ExerciseBook/06.36/06.36.c @@ -0,0 +1,63 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* + * 判断两棵二叉树是否相似 + */ +Status Algo_6_36(BiTree B1, BiTree B2); + + +int main(int argc, char* argv[]) { + BiTree B1, B2, B3; + + printf("创建二叉树 B1 :...\n"); + CreateBiTree(&B1, "TestData_B1.txt"); + PrintGraph(B1); + printf("\n"); + + printf("创建二叉树 B2 :...\n"); + CreateBiTree(&B2, "TestData_B2.txt"); + PrintGraph(B2); + printf("\n"); + + printf("创建二叉树 B3 :...\n"); + CreateBiTree(&B3, "TestData_B3.txt"); + PrintGraph(B3); + printf("\n"); + + if(Algo_6_36(B1, B2) == TRUE) { + printf("B1与B2相似!\n"); + } else { + printf("B1与B2不相似!!\n"); + } + + if(Algo_6_36(B2, B3) == TRUE) { + printf("B2与B3相似!\n"); + } else { + printf("B2与B3不相似!!\n"); + } + + return 0; +} + + +/* + * 判断两棵二叉树是否相似 + */ +Status Algo_6_36(BiTree B1, BiTree B2) { + // 都为空树 + if(BiTreeEmpty(B1) && BiTreeEmpty(B2)) { + return TRUE; + } else { + // 都不为空树 + if(!BiTreeEmpty(B1) && !BiTreeEmpty(B2)) { + // 判断左右子树 + if(Algo_6_36(B1->lchild, B2->lchild) && Algo_6_36(B1->rchild, B2->rchild)) { + return TRUE; + } + } + } + + return FALSE; +} diff --git a/CLion/ExerciseBook/06.36/BiTree.c b/CLion/ExerciseBook/06.36/BiTree.c new file mode 100644 index 0000000..1696ecc --- /dev/null +++ b/CLion/ExerciseBook/06.36/BiTree.c @@ -0,0 +1,178 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.36/BiTree.h b/CLion/ExerciseBook/06.36/BiTree.h new file mode 100644 index 0000000..2169f83 --- /dev/null +++ b/CLion/ExerciseBook/06.36/BiTree.h @@ -0,0 +1,76 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.36/CMakeLists.txt b/CLion/ExerciseBook/06.36/CMakeLists.txt new file mode 100644 index 0000000..b0deff2 --- /dev/null +++ b/CLion/ExerciseBook/06.36/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.36 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.36.c) +# 链接公共库 +target_link_libraries(06.36 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.36/LinkQueue.c b/CLion/ExerciseBook/06.36/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.36/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.36/LinkQueue.h b/CLion/ExerciseBook/06.36/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.36/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.36/TestData_B1.txt b/CLion/ExerciseBook/06.36/TestData_B1.txt new file mode 100644 index 0000000..f9de9ab --- /dev/null +++ b/CLion/ExerciseBook/06.36/TestData_B1.txt @@ -0,0 +1 @@ +先序序列→ABD^^E^^C^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.36/TestData_B2.txt b/CLion/ExerciseBook/06.36/TestData_B2.txt new file mode 100644 index 0000000..5c7c159 --- /dev/null +++ b/CLion/ExerciseBook/06.36/TestData_B2.txt @@ -0,0 +1 @@ +先序序列→FGH^^I^^J^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.36/TestData_B3.txt b/CLion/ExerciseBook/06.36/TestData_B3.txt new file mode 100644 index 0000000..2ffe34f --- /dev/null +++ b/CLion/ExerciseBook/06.36/TestData_B3.txt @@ -0,0 +1 @@ +先序序列→KLM^^N^^OP^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.37-06.38/06.37-06.38.c b/CLion/ExerciseBook/06.37-06.38/06.37-06.38.c new file mode 100644 index 0000000..74c3dd2 --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/06.37-06.38.c @@ -0,0 +1,133 @@ +#include +#include "Status.h" //**01 绪论**// +#include "SqStack.h" //**03 栈和队列**// +#include "BiTree.h" //**06 树和二叉树**// + +/* + * 先序遍历的非递归形式 + */ +Status Algo_6_37(BiTree T); + +/* + * 后序遍历的非递归形式 + */ +Status Algo_6_38(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("创建二叉树 T :...\n"); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("███题 6.37 验证...███\n"); + { + printf("二叉树先序遍历序列为:"); + Algo_6_37(T); + printf("\n"); + } + + printf("███题 6.38 验证...███\n"); + { + printf("二叉树后序遍历序列为:"); + Algo_6_38(T); + printf("\n"); + } + + return 0; +} + + +/* + * 先序遍历的非递归形式 + */ +Status Algo_6_37(BiTree T) { + SqStack S; + SElemType e; + + if(BiTreeEmpty(T)) { + printf("\n"); + return ERROR; + } + + InitStack(&S); + Push(&S, T); + + while(!StackEmpty(S)) { + GetTop(S, &e); + printf("%c ", e->data); + + if(e->lchild) { + Push(&S, e->lchild); + } else { + while(!StackEmpty(S)) { + Pop(&S, &e); + + if(e->rchild) { + Push(&S, e->rchild); + break; + } + } + } + } + + printf("\n"); + return OK; +} + +/* + * 后序遍历的非递归形式 + */ +Status Algo_6_38(BiTree T) { + SqStack S; + BiTree p; + SElemType e; + int StackMark[100] = {0}; // 标记栈,设置各结点访问标记(初始化为0) + int k; + + if(BiTreeEmpty(T)) { + printf("\n"); + return ERROR; + } + + InitStack(&S); + p = T; + k = -1; + + while(TRUE) { + while(p) { + Push(&S, p); + k++; + StackMark[k] = 1; // 设置第一次访问的标记 + p = p->lchild; + } + + // p为空但栈不为空 + while(!p && !StackEmpty(S)) { + GetTop(S, &p); + + // 已访问过一次,当前是第二次访问 + if(StackMark[k] == 1) { + StackMark[k] = 2; + p = p->rchild; + + // 已访问过两次,当前是第三次访问 + } else { + printf("%c ", p->data); + Pop(&S, &e); + StackMark[k] = 0; + k--; + p = NULL; + } + } + + if(StackEmpty(S)) { + break; + } + } + + printf("\n"); + return OK; +} diff --git a/CLion/ExerciseBook/06.37-06.38/BiTree.c b/CLion/ExerciseBook/06.37-06.38/BiTree.c new file mode 100644 index 0000000..1696ecc --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/BiTree.c @@ -0,0 +1,178 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.37-06.38/BiTree.h b/CLion/ExerciseBook/06.37-06.38/BiTree.h new file mode 100644 index 0000000..2169f83 --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/BiTree.h @@ -0,0 +1,76 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.37-06.38/CMakeLists.txt b/CLion/ExerciseBook/06.37-06.38/CMakeLists.txt new file mode 100644 index 0000000..daeb149 --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.37-06.38 SqStack.h SqStack.c LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.37-06.38.c) +# 链接公共库 +target_link_libraries(06.37-06.38 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.37-06.38/LinkQueue.c b/CLion/ExerciseBook/06.37-06.38/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.37-06.38/LinkQueue.h b/CLion/ExerciseBook/06.37-06.38/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.37-06.38/SqStack.c b/CLion/ExerciseBook/06.37-06.38/SqStack.c new file mode 100644 index 0000000..c7e31cc --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/SqStack.c @@ -0,0 +1,106 @@ +/*========================= + * 栈的顺序存储结构(顺序栈) + ==========================*/ + +#include "SqStack.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空栈。初始化成功则返回OK,否则返回ERROR。 + */ +Status InitStack(SqStack* S) { + if(S == NULL) { + return ERROR; + } + + (*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); + } + + (*S).top = (*S).base; + (*S).stacksize = STACK_INIT_SIZE; + + return OK; +} + +/* + * 判空 + * + * 判断顺序栈中是否包含有效数据。 + * + * 返回值: + * TRUE : 顺序栈为空 + * FALSE: 顺序栈不为空 + */ +Status StackEmpty(SqStack S) { + if(S.top == S.base) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 取值 + * + * 返回栈顶元素,并用e接收。 + */ +Status GetTop(SqStack S, SElemType* e) { + if(S.base == NULL || S.top == S.base) { + return 0; + } + + // 不会改变栈中元素 + *e = *(S.top - 1); + + return OK; +} + +/* + * 入栈 + * + * 将元素e压入到栈顶。 + */ +Status Push(SqStack* S, SElemType e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + // 栈满时,追加存储空间 + if((*S).top - (*S).base >= (*S).stacksize) { + (*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); // 存储分配失败 + } + + (*S).top = (*S).base + (*S).stacksize; + (*S).stacksize += STACKINCREMENT; + } + + // 进栈先赋值,栈顶指针再自增 + *(S->top++) = e; + + return OK; +} + +/* + * 出栈 + * + * 将栈顶元素弹出,并用e接收。 + */ +Status Pop(SqStack* S, SElemType* e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + if((*S).top == (*S).base) { + return ERROR; + } + + // 出栈栈顶指针先递减,再赋值 + *e = *(--(*S).top); + + return OK; +} diff --git a/CLion/ExerciseBook/06.37-06.38/SqStack.h b/CLion/ExerciseBook/06.37-06.38/SqStack.h new file mode 100644 index 0000000..2c6fe24 --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/SqStack.h @@ -0,0 +1,67 @@ +/*========================= + * 栈的顺序存储结构(顺序栈) + ==========================*/ + +#ifndef SQSTACK_H +#define SQSTACK_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 宏定义 */ +#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量 +#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量 + +/* 顺序栈元素类型定义 */ +typedef BiTree SElemType; + +// 顺序栈元素结构 +typedef struct { + SElemType* base; // 栈底指针 + SElemType* top; // 栈顶指针 + int stacksize; // 当前已分配的存储空间,以元素为单位 +} SqStack; + + +/* + * 初始化 + * + * 构造一个空栈。初始化成功则返回OK,否则返回ERROR。 + */ +Status InitStack(SqStack* S); + +/* + * 判空 + * + * 判断顺序栈中是否包含有效数据。 + * + * 返回值: + * TRUE : 顺序栈为空 + * FALSE: 顺序栈不为空 + */ +Status StackEmpty(SqStack S); + +/* + * 取值 + * + * 返回栈顶元素,并用e接收。 + */ +Status GetTop(SqStack S, SElemType* e); + +/* + * 入栈 + * + * 将元素e压入到栈顶。 + */ +Status Push(SqStack* S, SElemType e); + +/* + * 出栈 + * + * 将栈顶元素弹出,并用e接收。 + */ +Status Pop(SqStack* S, SElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.37-06.38/TestData.txt b/CLion/ExerciseBook/06.37-06.38/TestData.txt new file mode 100644 index 0000000..39e3f58 --- /dev/null +++ b/CLion/ExerciseBook/06.37-06.38/TestData.txt @@ -0,0 +1 @@ +先序序列→ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.39/06.39.c b/CLion/ExerciseBook/06.39/06.39.c new file mode 100644 index 0000000..464a222 --- /dev/null +++ b/CLion/ExerciseBook/06.39/06.39.c @@ -0,0 +1,153 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型,这里设置为字符 */ +typedef char TElemType; + +/* 二叉树的结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 + struct BiTNode* parent; + int mark; +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + +/* + * 后序遍历的递推形式 + */ +void Algo_6_39(BiTree T); + +// 构造二叉树(先序序列) +Status CreateBiTree(BiTree* T, char* path); + +// 构造二叉树的内部实现,p用来追踪子树根结点 +void CreateTree(BiTree* T, BiTree p, FILE* fp); + +// 以图形化形式输出当前二叉树 +void PrintGraph(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("创建二叉树 T ...\n"); + CreateBiTree(&T, NULL); + PrintGraph(T); + + printf("二叉树后序遍历序列为:"); + Algo_6_39(T); + + return 0; +} + + +/* + * 后序遍历的递推形式 + */ +void Algo_6_39(BiTree T) { + BiTree p = T; + + while(p != NULL) { + // mark==0:还未访问,则先向左访问 + if(p->mark == 0) { + p->mark = 1; + if(p->lchild != NULL) { + p = p->lchild; + } + + // mark==1:左侧已访问,则再向右访问 + } else if(p->mark == 1) { + p->mark = 2; + if(p->rchild != NULL) { + p = p->rchild; + } + + // mark==2:左右都访问完了,则打印根结点 + } else { + printf("%c ", p->data); + p->mark = 0; // 标记重置 + p = p->parent; + } + } + + printf("\n"); +} + +// 构造二叉树(先序序列) +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + + fp = fopen("TestData.txt", "r"); + CreateTree(T, NULL, fp); + fclose(fp); + + return OK; +} + +// 构造二叉树的内部实现,p用来追踪子树根结点 +void CreateTree(BiTree* T, BiTree p, FILE* fp) { + char ch; + + ReadData(fp, "%c", &ch); + + if(ch == '^') { + *T = NULL; + } else { + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + (*T)->parent = p; + (*T)->mark = 0; + CreateTree(&(*T)->lchild, *T, fp); + CreateTree(&(*T)->rchild, *T, fp); + } +} + +// 以图形化形式输出当前二叉树 +void PrintGraph(BiTree T) { + BiTree p = T; + int i = 1; + + while(p != NULL) { + // mark==0:还未访问,则先向左访问 + if(p->mark == 0) { + printf("%c ", p->data); + i++; + p->mark = 1; + if(p->lchild != NULL) { + p = p->lchild; + } else { + printf("^\n"); + i--; + } + + // mark==1:左侧已访问,则再向右访问 + } else if(p->mark == 1) { + p->mark = 2; + i++; + + if(p->rchild != NULL) { + printf("%*c", 2 * (i - 1), ' '); + p = p->rchild; + } else { + printf("%*c^\n", 2 * (i - 1), ' '); + i--; + } + + // mark==2:左右都访问完了,则打印根结点 + } else { + p->mark = 0; // 标记重置 + p = p->parent; + i--; + } + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/06.39/CMakeLists.txt b/CLion/ExerciseBook/06.39/CMakeLists.txt new file mode 100644 index 0000000..80abc7c --- /dev/null +++ b/CLion/ExerciseBook/06.39/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.39 06.39.c) +# 链接公共库 +target_link_libraries(06.39 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.39/TestData.txt b/CLion/ExerciseBook/06.39/TestData.txt new file mode 100644 index 0000000..39e3f58 --- /dev/null +++ b/CLion/ExerciseBook/06.39/TestData.txt @@ -0,0 +1 @@ +先序序列→ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.40/06.40.c b/CLion/ExerciseBook/06.40/06.40.c new file mode 100644 index 0000000..e2075ad --- /dev/null +++ b/CLion/ExerciseBook/06.40/06.40.c @@ -0,0 +1,169 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型,这里设置为字符 */ +typedef char TElemType; + +/* 二叉树的结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 + struct BiTNode* parent; +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + +/* + * 中序遍历的递推形式 + * + *【注】 + * 遍历的关键是分辨当前结点第几次被访问。 + */ +void Algo_6_40(BiTree T); + +// 构造二叉树(先序序列) +Status CreateBiTree(BiTree* T, char* path); + +// 构造二叉树的内部实现,p用来追踪子树根结点 +void CreateTree(BiTree* T, BiTree p, FILE* fp); + +// 以图形化形式输出当前二叉树 +void PrintGraph(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("创建二叉树 T ...\n"); + CreateBiTree(&T, NULL); + PrintGraph(T); + + printf("二叉树中序遍历序列为:"); + Algo_6_40(T); + + return 0; +} + + +/* + * 中序遍历的递推形式 + * + *【注】 + * 遍历的关键是分辨当前结点第几次被访问。 + */ +void Algo_6_40(BiTree T) { + BiTree p = T; + + while(p != NULL) { + // 第一次访问结点,向左访问 + if(p->lchild != NULL) { + p = p->lchild; + } else { + // 从左子树返回的结点第二次被访问,要输出 + printf("%c ", p->data); + + // 若当前结点属于右分支,返回到父结点后要跳过父结点 + while(p->rchild == NULL) { + // 从右子树返回的结点第三次被访问,不输出 + while(p->parent != NULL && p->parent->rchild == p) { + p = p->parent; + } + + if(p->parent != NULL) { + // 若当前结点属于左分支,返回到父结点后要访问父结点 + if(p->parent->lchild == p) { + p = p->parent; + printf("%c ", p->data); // 同样返回自左子树 + } + } else { + printf("\n"); + + // 从右子树返回到根结点时,遍历完成 + return; + } + } + + p = p->rchild; + } + } +} + +// 构造二叉树(先序序列) +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + + fp = fopen("TestData.txt", "r"); + CreateTree(T, NULL, fp); + fclose(fp); + + return OK; +} + +// 构造二叉树的内部实现,p用来追踪子树根结点 +void CreateTree(BiTree* T, BiTree p, FILE* fp) { + char ch; + + ReadData(fp, "%c", &ch); + + if(ch == '^') { + *T = NULL; + } else { + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + (*T)->parent = p; + CreateTree(&(*T)->lchild, *T, fp); + CreateTree(&(*T)->rchild, *T, fp); + } +} + +// 以图形化形式输出当前二叉树 +void PrintGraph(BiTree T) { + BiTree p = T; + int i = 1; + + while(p != NULL) { + // 从左子树返回的结点第二次被访问,要输出 + printf("%c ", p->data); + i++; + + // 第一次访问结点,向左访问 + if(p->lchild != NULL) { + p = p->lchild; + } else { + printf("^\n"); + + // 若当前结点属于右分支,返回到父结点后要跳过父结点 + while(p->rchild == NULL) { + printf("%*c^\n", 2 * (i - 1), ' '); + i--; + + // 从右子树返回的结点第三次被访问,不输出 + while(p->parent != NULL && p->parent->rchild == p) { + p = p->parent; + i--; + } + + if(p->parent != NULL) { + // 若当前结点属于左分支,返回到父结点后要访问父结点 + if(p->parent->lchild == p) { + p = p->parent; + } + } else { + printf("\n"); + + // 从右子树返回到根结点时,遍历完成 + return; + } + } + + printf("%*c", 2 * (i - 1), ' '); + p = p->rchild; + } + } +} diff --git a/CLion/ExerciseBook/06.40/CMakeLists.txt b/CLion/ExerciseBook/06.40/CMakeLists.txt new file mode 100644 index 0000000..d24ce21 --- /dev/null +++ b/CLion/ExerciseBook/06.40/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.40 06.40.c) +# 链接公共库 +target_link_libraries(06.40 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.40/TestData.txt b/CLion/ExerciseBook/06.40/TestData.txt new file mode 100644 index 0000000..39e3f58 --- /dev/null +++ b/CLion/ExerciseBook/06.40/TestData.txt @@ -0,0 +1 @@ +先序序列→ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.41-06.49/06.41-06.49.c b/CLion/ExerciseBook/06.41-06.49/06.41-06.49.c new file mode 100644 index 0000000..b5e5243 --- /dev/null +++ b/CLion/ExerciseBook/06.41-06.49/06.41-06.49.c @@ -0,0 +1,503 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +#define MAX_TREE_DEPTH 20 // 二叉树最大层数 +#define MAX_TREE_SIZE 1024 // 二叉树元素数量最大值 + +/* + * 求先序序列中第k个结点的值,order用来计数。 + */ +Status Algo_6_41(BiTree T, int k, int* order, TElemType* e); + +/* + * 计算二叉树中叶子结点数目 + */ +int Algo_6_42(BiTree T); + +/* + * 交换二叉树的左右子树 + */ +void Algo_6_43(BiTree T); + +/* + * 求二叉树中子树'x'的深度 + */ +int Algo_6_44(BiTree T, TElemType x); + +/* + * 删除二叉树T中的子树x + */ +Status Algo_6_45(BiTree* T, TElemType x); + +/* + * 复制二叉树的非递归算法 + */ +void Algo_6_46(BiTree T, BiTree* Tx); + +/* + * 层序遍历二叉树 + */ +void Algo_6_47(BiTree T); + +/* + * 求两结点的共同祖先 + */ +BiTree Algo_6_48(BiTree T, TElemType a, TElemType b); + +/* + * 判断二叉树是否为完全二叉树 + */ +Status Algo_6_49(BiTree T); + +/* + * 遍历树寻找根结点到p结点的路径,path存储路径上各结点指针(不包含p结点的指针) + */ +static int FindPath(BiTree T, TElemType e, BiTree path[]); + +// 返回指向二叉树结点e的指针 +static BiTree EPtr(BiTree T, TElemType e); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("创建二叉树 T ...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("███题 6.41 验证...███\n"); + { + int k = 9; + int order = 0; // 计数 + TElemType e; + + if(Algo_6_41(T, k, &order, &e)) { + printf("先序序列中第 %d 个元素为 %c \n", k, e); + } else { + printf("此处元素不存在!\n"); + } + + printf("\n"); + } + + printf("███题 6.42 验证...███\n"); + { + printf("二叉树的叶子结点个数为:%d\n", Algo_6_42(T)); + printf("\n"); + } + + printf("███题 6.43 验证...███\n"); + { + printf("交换二叉树左右子树后二叉树变为:\n"); + Algo_6_43(T); + PrintGraph(T); + printf("\n"); + } + + printf("███题 6.44 验证...███\n"); + { + char x = 'E'; + + printf("子树 %c 的深度为: %d\n", x, Algo_6_44(T, x)); + printf("\n"); + } + + printf("███题 6.45 验证...███\n"); + { + char x = 'D'; + + printf("删除子树 %c 后,二叉树为:\n", x); + if(Algo_6_45(&T, x)) { + PrintGraph(T); + } + printf("\n"); + } + + printf("███题 6.46 验证...███\n"); + { + BiTree Tx; + + printf("复制 T 到 Tx 后,二叉树Tx为:\n"); + Algo_6_46(T, &Tx); + PrintGraph(Tx); + printf("\n"); + } + + printf("███题 6.47 验证...███\n"); + { + printf("二叉树层序遍历序列为:"); + Algo_6_47(T); + printf("\n"); + } + + printf("███题 6.48 验证...███\n"); + { + BiTree Tmp = NULL; + TElemType a = 'I'; + TElemType b = 'H'; + + if((Tmp = Algo_6_48(T, a, b)) != NULL) { + printf("'%c' 和 '%c' 的最近共同祖先为:'%c'\n", a, b, Tmp->data); + } + printf("\n"); + } + + printf("███题 6.49 验证...███\n"); + { + if(Algo_6_49(T)) { + printf("此二叉树是完全二叉树!\n"); + } else { + printf("此二叉树不是完全二叉树!!\n"); + } + } + + return 0; +} + + +/* + * 求先序序列中第k个结点的值,order用来计数。 + */ +Status Algo_6_41(BiTree T, int k, int* order, TElemType* e) { + + if(T == NULL) { + *e = '\0'; + return ERROR; + } + + (*order)++; + + if(*order == k) { + *e = T->data; + return OK; + } else { + if(Algo_6_41(T->lchild, k, order, e)) { + return OK; + } + + if(Algo_6_41(T->rchild, k, order, e)) { + return OK; + } + } + + return ERROR; +} + +/* + * 计算二叉树中叶子结点数目 + */ +int Algo_6_42(BiTree T) { + int count = 0; + + if(T != NULL) { + if(T->lchild == NULL && T->rchild == NULL) { + count++; + } else { + count += Algo_6_42(T->lchild); // 左子树叶子结点数量 + count += Algo_6_42(T->rchild); // 右子树叶子结点数量 + } + } + + return count; +} + +/* + * 交换二叉树的左右子树 + */ +void Algo_6_43(BiTree T) { + BiTree p; + + if(T != NULL) { + p = T->lchild; + T->lchild = T->rchild; + T->rchild = p; + + // 递归交换 + Algo_6_43(T->lchild); + Algo_6_43(T->rchild); + } +} + +/* + * 求二叉树T中子树'x'的深度 + */ +int Algo_6_44(BiTree T, TElemType x) { + BiTree p; + + p = EPtr(T, x); // 第一个递归求出x的位置,以指针形式返回 + + return BiTreeDepth(p); // 第二个递归求出子树x的深度 +} + +/* + * 删除二叉树T中的子树x + */ +Status Algo_6_45(BiTree* T, TElemType x) { + + if(*T == NULL) { + return ERROR; + } + + // 如果找到了该结点,则递归清空子树 + if((*T)->data == x) { + ClearBiTree(T); + return OK; + // 递归向左右子树寻找该结点 + } else { + if(Algo_6_45(&((*T)->lchild), x)) { + return OK; + } + + if(Algo_6_45(&((*T)->rchild), x)) { + return OK; + } + + return ERROR; + } +} + +/* + * 复制二叉树的非递归算法 + */ +void Algo_6_46(BiTree T, BiTree* Tx) { + int front, rear; + BiTree queue[MAX_TREE_SIZE] = {NULL}; // 树指针数组,用来模拟队列,初始化元素为NULL + BiTree tree[MAX_TREE_SIZE]; // 新建的二叉树 + BiTree p; + int parent; + + if(T == NULL) { + *Tx = NULL; + return; + } + + front = rear = 0; + + queue[rear] = T; + + while(front <= rear) { + p = queue[front]; + + if(p == NULL) { + front++; + continue; + } + + // 创建新结点 + tree[front] = (BiTree) malloc(sizeof(BiTNode)); + tree[front]->data = p->data; + tree[front]->lchild = tree[front]->rchild = NULL; + + // 为该结点挂接在父结点上 + if(front > 0) { + parent = (front - 1) / 2; + + // 如果当前结点作为左孩子 + if(2 * parent + 1 == front) { + tree[parent]->lchild = tree[front]; + } else { + tree[parent]->rchild = tree[front]; + } + } + + if(p->lchild != NULL) { + rear = 2 * front + 1; + queue[rear] = p->lchild; + } + + if(p->rchild != NULL) { + rear = 2 * front + 2; + queue[rear] = p->rchild; + } + + front++; + } + + *Tx = tree[0]; +} + +/* + * 层序遍历二叉树 + */ +void Algo_6_47(BiTree T) { + int front, rear; + BiTree queue[MAX_TREE_SIZE]; // 树指针数组,用来模拟队列 + BiTree p; + + if(T == NULL) { + return; + } + + front = rear = 0; + + queue[rear++] = T; + + while(front != rear) { + p = queue[front++]; + + printf("%c ", p->data); + + if(p->lchild != NULL) { + queue[rear++] = p->lchild; + } + + if(p->rchild != NULL) { + queue[rear++] = p->rchild; + } + } + + printf("\n"); +} + +/* + * 求两结点的共同祖先 + */ +BiTree Algo_6_48(BiTree T, TElemType a, TElemType b) { + BiTree pa[MAX_TREE_DEPTH] = {NULL}; + BiTree pb[MAX_TREE_DEPTH] = {NULL}; + int lenA, lenB; + int i, j; + + // 借助于路径寻找函数 + if((lenA = FindPath(T, a, pa)) != 0 && (lenB = FindPath(T, b, pb)) != 0) { + for(i = lenA - 1; pa[i] != NULL; i--) { + for(j = lenB - 1; pb[j] != NULL; j--) { + if(pa[i]->data == pb[j]->data) { + return pa[i]; + } + } + } + } + + return NULL; +} + +/* + * 判断二叉树是否为完全二叉树 + * + * 完全二叉树的特点是层序遍历时序号与满二叉树一致 + */ +Status Algo_6_49(BiTree T) { + int front, rear; + BiTree queue[MAX_TREE_SIZE]; // 树指针数组,模拟队列 + int order[MAX_TREE_SIZE]; + BiTree p; + int count; + + if(T == NULL) { + return OK; + } + + front = rear = 0; + count = 1; + + queue[rear] = T; + order[rear] = 1; + rear++; + + // 遍历的同时为各结点编号 + while(front < rear) { + if(order[front] != count) { + return ERROR; + } + + p = queue[front]; // 获取队头元素 + + if(p->lchild != NULL) { + queue[rear] = p->lchild; + order[rear] = 2 * order[front]; + rear++; + } + + if(p->rchild != NULL) { + queue[rear] = p->rchild; + order[rear] = 2 * order[front] + 1; + rear++; + } + + front++; + count++; // 每出队一个,计数增一 + } + + return OK; +} + +// 返回指向二叉树结点e的指针 +static BiTree EPtr(BiTree T, TElemType e) { + BiTree pl, pr; + + if(T == NULL) { + return NULL; + } + + // 如果找到了目标结点,直接返回其指针 + if(T->data == e) { + return T; + } + + // 在左子树中查找e + pl = EPtr(T->lchild, e); + if(pl != NULL) { + return pl; + } + + // 在右子树中查找e + pr = EPtr(T->rchild, e); + if(pr != NULL) { + return pr; + } + + return NULL; +} + +// 遍历树寻找根结点到p结点的路径,path存储路径上各结点指针(不包含p结点的指针) +static int FindPath(BiTree T, TElemType e, BiTree path[]) { + int i = -1; + int mark[MAX_TREE_DEPTH] = {0}; // 访问标记栈 + BiTree p; + + p = T; + + while(TRUE) { + // 如果没有遇到满足条件的结点,先尝试向左子树查找 + while(p != NULL && p->data != e) { + i++; + + // 记下当前结点的指针 + path[i] = p; + + // 已访问过该结点的左子树 + mark[i] = 1; + p = p->lchild; + } + + // 遇到了满足条件的结点 + if(p != NULL) { + return i + 1; + } + + // 回到父结点 + p = path[i]; + + // 如果右子树不存在,或者该右子树已被访问过,则回到它的父结点 + while(p->rchild == NULL || mark[i] == 2) { + path[i] = NULL; // 置空该位置 + + i--; + if(i == -1) { + return 0; + } + + // 回退到父结点 + p = path[i]; + } + + // 已访问过该结点的右子树 + mark[i] = 2; + p = p->rchild; + } +} diff --git a/CLion/ExerciseBook/06.41-06.49/BiTree.c b/CLion/ExerciseBook/06.41-06.49/BiTree.c new file mode 100644 index 0000000..23d4976 --- /dev/null +++ b/CLion/ExerciseBook/06.41-06.49/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // 在*T不为空时进行递归清理 + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.41-06.49/BiTree.h b/CLion/ExerciseBook/06.41-06.49/BiTree.h new file mode 100644 index 0000000..5bd67ff --- /dev/null +++ b/CLion/ExerciseBook/06.41-06.49/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T); + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.41-06.49/CMakeLists.txt b/CLion/ExerciseBook/06.41-06.49/CMakeLists.txt new file mode 100644 index 0000000..7cf57b9 --- /dev/null +++ b/CLion/ExerciseBook/06.41-06.49/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.41-06.49 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.41-06.49.c) +# 链接公共库 +target_link_libraries(06.41-06.49 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.41-06.49/LinkQueue.c b/CLion/ExerciseBook/06.41-06.49/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.41-06.49/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.41-06.49/LinkQueue.h b/CLion/ExerciseBook/06.41-06.49/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.41-06.49/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.41-06.49/TestData.txt b/CLion/ExerciseBook/06.41-06.49/TestData.txt new file mode 100644 index 0000000..39e3f58 --- /dev/null +++ b/CLion/ExerciseBook/06.41-06.49/TestData.txt @@ -0,0 +1 @@ +先序序列→ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.50/06.50.c b/CLion/ExerciseBook/06.50/06.50.c new file mode 100644 index 0000000..88318ed --- /dev/null +++ b/CLion/ExerciseBook/06.50/06.50.c @@ -0,0 +1,83 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +#define MAX_TREE_SIZE 1024 // 二叉树元素数量最大值 + +/* + * 读取预定格式的结点信息,按层序创建二叉树。 + */ +Status Algo_6_50(BiTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + BiTree T; + FILE* fp; + + printf("创建二叉树(层序序列)...\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_50(&T, fp); + fclose(fp); + printf("\n"); + + printf("二叉树T为:\n"); + PrintGraph(T); + + return 0; +} + + +/* + * 读取预定格式的结点信息,按层序创建二叉树。 + */ +Status Algo_6_50(BiTree* T, FILE* fp) { + char s[4]; + BiTree tmp[MAX_TREE_SIZE]; // 按层序存储遇到的每个结点的指针 + int m, n; + BiTree p; + + m = n = 0; + + *T= NULL; + + while(TRUE) { + ReadData(fp, "%s", s); + printf("%s\n", s); + + // 退出标志 + if(s[1] == '^') { + return OK; + } + + p = (BiTree) malloc(sizeof(BiTNode)); + if(p==NULL) { + exit(OVERFLOW); + } + p->data = s[1]; + p->lchild = p->rchild = NULL; + + // 根结点 + if(s[0] == '^') { + *T = p; + tmp[n++] = p; + } else { + // 寻找子树结点 + while(mdata != s[0]) { + m++; + } + + if(m>=n) { + return ERROR; + } + + if(s[2] == 'L') { + tmp[m]->lchild = p; + } else { + tmp[m]->rchild = p; + } + } + + tmp[n++] = p; + } +} diff --git a/CLion/ExerciseBook/06.50/BiTree.c b/CLion/ExerciseBook/06.50/BiTree.c new file mode 100644 index 0000000..6dc871b --- /dev/null +++ b/CLion/ExerciseBook/06.50/BiTree.c @@ -0,0 +1,121 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.50/BiTree.h b/CLion/ExerciseBook/06.50/BiTree.h new file mode 100644 index 0000000..ee19645 --- /dev/null +++ b/CLion/ExerciseBook/06.50/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.50/CMakeLists.txt b/CLion/ExerciseBook/06.50/CMakeLists.txt new file mode 100644 index 0000000..d3db647 --- /dev/null +++ b/CLion/ExerciseBook/06.50/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.50 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.50.c) +# 链接公共库 +target_link_libraries(06.50 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.50/LinkQueue.c b/CLion/ExerciseBook/06.50/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.50/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.50/LinkQueue.h b/CLion/ExerciseBook/06.50/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.50/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.50/TestData.txt b/CLion/ExerciseBook/06.50/TestData.txt new file mode 100644 index 0000000..43ff76f --- /dev/null +++ b/CLion/ExerciseBook/06.50/TestData.txt @@ -0,0 +1,9 @@ +^AL +ABL +ACR +BDL +CEL +CFR +DGR +FHL +^^L \ No newline at end of file diff --git a/CLion/ExerciseBook/06.51/06.51.c b/CLion/ExerciseBook/06.51/06.51.c new file mode 100644 index 0000000..112f619 --- /dev/null +++ b/CLion/ExerciseBook/06.51/06.51.c @@ -0,0 +1,90 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* + * 输出算术表达式构成的二叉树(中序遍历) + */ +void Algo_6_51(BiTree T); + +// 判断字符c是否为操作符 +Status IsOperator(char c); + +// 判断两个操作符的优先级 +Status Priority(char a, char b); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("创建二叉树(先序序列)T...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("输出算术表达式:"); + Algo_6_51(T); + printf("\n"); + + return 0; +} + + +/* + * 输出算术表达式构成的二叉树(中序遍历) + */ +void Algo_6_51(BiTree T) { + if(T == NULL) { + return; + } + + if(T->lchild != NULL) { + // 当前结点的左孩子是操作符且优先级低于当前结点 + if(IsOperator(T->lchild->data) && Priority(T->lchild->data, T->data) < 0) { + printf("("); + Algo_6_51(T->lchild); + printf(")"); + } else { + Algo_6_51(T->lchild); + } + } + + printf("%c", T->data); + + if(T->rchild != NULL) { + // 当前结点的右孩子是操作符且优先级低于当前结点 + if(IsOperator(T->rchild->data) && Priority(T->rchild->data, T->data) < 0) { + printf("("); + Algo_6_51(T->rchild); + printf(")"); + } else { + Algo_6_51(T->rchild); + } + } +} + +// 判断字符c是否为操作符 +Status IsOperator(char c) { + if(c == '+' || c == '-' || c == '*' || c == '/') { + return TRUE; + } else { + return ERROR; + } +} + +// 判断两个操作符的优先级 +Status Priority(char a, char b) { + // a的优先级低 + if((a == '+' || a == '-') && (b == '*' || b == '/')) { + return -1; + + // a的优先级高 + } else if((a == '*' || a == '/') && (b == '+' || b == '-')) { + return 1; + + // 优先级相同 + } else { + return 0; + } +} diff --git a/CLion/ExerciseBook/06.51/BiTree.c b/CLion/ExerciseBook/06.51/BiTree.c new file mode 100644 index 0000000..23d4976 --- /dev/null +++ b/CLion/ExerciseBook/06.51/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // 在*T不为空时进行递归清理 + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.51/BiTree.h b/CLion/ExerciseBook/06.51/BiTree.h new file mode 100644 index 0000000..5bd67ff --- /dev/null +++ b/CLion/ExerciseBook/06.51/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T); + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.51/CMakeLists.txt b/CLion/ExerciseBook/06.51/CMakeLists.txt new file mode 100644 index 0000000..a70fd43 --- /dev/null +++ b/CLion/ExerciseBook/06.51/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.51 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.51.c) +# 链接公共库 +target_link_libraries(06.51 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.51/LinkQueue.c b/CLion/ExerciseBook/06.51/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.51/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.51/LinkQueue.h b/CLion/ExerciseBook/06.51/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.51/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.51/TestData.txt b/CLion/ExerciseBook/06.51/TestData.txt new file mode 100644 index 0000000..e664c85 --- /dev/null +++ b/CLion/ExerciseBook/06.51/TestData.txt @@ -0,0 +1 @@ +先序序列→*/*+a^^b^^-c^^d^^e^^-g^^h^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.52/06.52.c b/CLion/ExerciseBook/06.52/06.52.c new file mode 100644 index 0000000..5ac0df3 --- /dev/null +++ b/CLion/ExerciseBook/06.52/06.52.c @@ -0,0 +1,90 @@ +#include +#include // 提供pow、log原型 +#include "BiTree.h" //**▲06 树和二叉树**// + +#define MAX_TREE_SIZE 1024 // 二叉树元素数量最大值 + +/* + * 计算二叉树的繁茂度:宽度x高度 + * 注:宽度为各层结点数的最大值 + */ +int Algo_6_52(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("创建二叉树(先序序列)T...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("树的繁茂度为: %d", Algo_6_52(T)); + printf("\n"); + + return 0; +} + + +/* + * 计算二叉树的繁茂度:宽度x高度 + * 注:宽度为各层结点数的最大值 + */ +int Algo_6_52(BiTree T) { + int lux; // 繁茂度 + int col, width; // 各层宽度和最大宽度 + int row, high; // 当前结点所在层数和最大高度 + BiTree queue[MAX_TREE_SIZE]; // 树指针数组,模拟队列 + int level[MAX_TREE_SIZE]; // 记录当前结点在第几层 + BiTree p; + int m, n; + + if(T==NULL) { + return 0; + } + + width = high = 0; + m = n = 0; + col = 1; + + queue[n] = T; + level[n] = 1; + n++; + + while(mhigh) { + high = row; + col = 1; // 换行时要重置列数 + } else { + col++; + } + + if(col>width) { + width = col; + } + + if(p->lchild!=NULL) { + queue[n] = p->lchild; + level[n] = row+1; + n++; + } + + if(p->rchild!=NULL) { + queue[n] = p->rchild; + level[n] = row+1; + n++; + } + + + } + + lux = width * high; + + return lux; +} diff --git a/CLion/ExerciseBook/06.52/BiTree.c b/CLion/ExerciseBook/06.52/BiTree.c new file mode 100644 index 0000000..23d4976 --- /dev/null +++ b/CLion/ExerciseBook/06.52/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // 在*T不为空时进行递归清理 + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.52/BiTree.h b/CLion/ExerciseBook/06.52/BiTree.h new file mode 100644 index 0000000..5bd67ff --- /dev/null +++ b/CLion/ExerciseBook/06.52/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T); + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.52/CMakeLists.txt b/CLion/ExerciseBook/06.52/CMakeLists.txt new file mode 100644 index 0000000..8b51ae5 --- /dev/null +++ b/CLion/ExerciseBook/06.52/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.52 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.52.c) +# 链接公共库 +target_link_libraries(06.52 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.52/LinkQueue.c b/CLion/ExerciseBook/06.52/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.52/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.52/LinkQueue.h b/CLion/ExerciseBook/06.52/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.52/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.52/TestData.txt b/CLion/ExerciseBook/06.52/TestData.txt new file mode 100644 index 0000000..39e3f58 --- /dev/null +++ b/CLion/ExerciseBook/06.52/TestData.txt @@ -0,0 +1 @@ +先序序列→ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.53/06.53.c b/CLion/ExerciseBook/06.53/06.53.c new file mode 100644 index 0000000..195be76 --- /dev/null +++ b/CLion/ExerciseBook/06.53/06.53.c @@ -0,0 +1,87 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +#define MAX_TREE_DEPTH 20 // 二叉树最大层数 + +/* + * 寻找根结点到叶子结点最长路径中最靠左的一条 + */ +int Algo_6_53(BiTree T, BiTree path[]); + + +int main(int argc, char* argv[]) { + BiTree T; + BiTree way[MAX_TREE_DEPTH] = {NULL}; + int i, n; + + printf("创建二叉树(先序序列)T...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("输出根结点到叶子结点最长路径中最靠左的一条:"); + n = Algo_6_53(T, way); + for(i = 0; i < n; i++) { + printf("%c ", way[i]->data); + } + printf("\n"); + + return 0; +} + + +/* + * 寻找根结点到叶子结点最长路径中最靠左的一条 + */ +int Algo_6_53(BiTree T, BiTree path[]) { + int i = -1; + int mark[MAX_TREE_DEPTH] = {0}; // 访问标记栈 + BiTree p; + int depth; + + // 先判断树的深度 + depth = BiTreeDepth(T); + + p = T; + + while(TRUE) { + // 先尝试向左子树查找 + while(p != NULL) { + i++; + + // 记下当前结点的指针 + path[i] = p; + + // 已访问过该结点的左子树 + mark[i] = 1; + p = p->lchild; + } + + // 向左走向尽头,判断其路径长度是否符合题意 + if(i + 1 == depth) { + return depth; + } + + // 回到父结点 + p = path[i]; + + // 如果右子树不存在,或者该右子树已被访问过,则回到它的父结点 + while(p->rchild == NULL || mark[i] == 2) { + path[i] = NULL; // 置空该位置 + + i--; + if(i == -1) { + return 0; + } + + // 回退到父结点 + p = path[i]; + } + + // 已访问过该结点的右子树 + mark[i] = 2; + p = p->rchild; + } +} diff --git a/CLion/ExerciseBook/06.53/BiTree.c b/CLion/ExerciseBook/06.53/BiTree.c new file mode 100644 index 0000000..23d4976 --- /dev/null +++ b/CLion/ExerciseBook/06.53/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // 在*T不为空时进行递归清理 + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.53/BiTree.h b/CLion/ExerciseBook/06.53/BiTree.h new file mode 100644 index 0000000..5bd67ff --- /dev/null +++ b/CLion/ExerciseBook/06.53/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T); + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.53/CMakeLists.txt b/CLion/ExerciseBook/06.53/CMakeLists.txt new file mode 100644 index 0000000..7d91075 --- /dev/null +++ b/CLion/ExerciseBook/06.53/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.53 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.53.c) +# 链接公共库 +target_link_libraries(06.53 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.53/LinkQueue.c b/CLion/ExerciseBook/06.53/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.53/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.53/LinkQueue.h b/CLion/ExerciseBook/06.53/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.53/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.53/TestData.txt b/CLion/ExerciseBook/06.53/TestData.txt new file mode 100644 index 0000000..030585a --- /dev/null +++ b/CLion/ExerciseBook/06.53/TestData.txt @@ -0,0 +1 @@ +先序序列→ABD^^EG^^^CF^HI^^J^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.54/06.54.c b/CLion/ExerciseBook/06.54/06.54.c new file mode 100644 index 0000000..f640b56 --- /dev/null +++ b/CLion/ExerciseBook/06.54/06.54.c @@ -0,0 +1,64 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +#define MAX_TREE_SIZE 1024 // 二叉树元素数量最大值 + +/* + * 根据二叉树的层序序列创建链式二叉树 + */ +Status Algo_6_54(BiTree* T, TElemType sa[100]); + + +int main(int argc, char* argv[]) { + BiTree T; + TElemType sa[MAX_TREE_SIZE] = "ABCDEF^G^HI^J"; // 层序序列 + + printf("创建二叉树(层序序列)...\n"); + Algo_6_54(&T, sa); + PrintGraph(T); + + return 0; +} + + +/* + * 根据二叉树的层序序列创建链式二叉树 + */ +Status Algo_6_54(BiTree* T, TElemType sa[]) { + BiTree tree[MAX_TREE_SIZE]; // 临时存放遍历中各结点指针的复制品 + int p, i; + + i = 0; + + while(sa[i] != '\0') { + if(sa[i] == '^') { + tree[i] = NULL; + } else { + tree[i] = (BiTree) malloc(sizeof(BiTNode)); + if(tree[i] == NULL) { + exit(OVERFLOW); + } + tree[i]->data = sa[i]; + tree[i]->lchild = tree[i]->rchild = NULL; + } + + if(i > 0) { + p = (i - 1) / 2; // 父结点序号 + + // 当前结点是左孩子 + if(2 * p + 1 == i) { + tree[p]->lchild = tree[i]; + } else { + tree[p]->rchild = tree[i]; + } + } + + i++; + } + + *T = tree[0]; + + return OK; +} diff --git a/CLion/ExerciseBook/06.54/BiTree.c b/CLion/ExerciseBook/06.54/BiTree.c new file mode 100644 index 0000000..6dc871b --- /dev/null +++ b/CLion/ExerciseBook/06.54/BiTree.c @@ -0,0 +1,121 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.54/BiTree.h b/CLion/ExerciseBook/06.54/BiTree.h new file mode 100644 index 0000000..ee19645 --- /dev/null +++ b/CLion/ExerciseBook/06.54/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.54/CMakeLists.txt b/CLion/ExerciseBook/06.54/CMakeLists.txt new file mode 100644 index 0000000..020bfb8 --- /dev/null +++ b/CLion/ExerciseBook/06.54/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.54 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.54.c) +# 链接公共库 +target_link_libraries(06.54 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.54/LinkQueue.c b/CLion/ExerciseBook/06.54/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.54/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.54/LinkQueue.h b/CLion/ExerciseBook/06.54/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.54/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.55/06.55.c b/CLion/ExerciseBook/06.55/06.55.c new file mode 100644 index 0000000..9f4fc76 --- /dev/null +++ b/CLion/ExerciseBook/06.55/06.55.c @@ -0,0 +1,64 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* + * 计算二叉树中每个结点的子孙数目 + */ +int Algo_6_55(BiTree T); + +// 先序输出二叉树及各结点其子孙数目 +void PreOrderPrint(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("创建二叉树(先序序列)T...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("先序输出二叉树结点值及其相应的子孙数目:\n"); + Algo_6_55(T); + PreOrderPrint(T); + + return 0; +} + + +/* + * 计算二叉树中每个结点的子孙数目 + */ +int Algo_6_55(BiTree T) { + int l, r; + + if(T == NULL) { + return 0; + } else { + T->DescNum = 0; + + if(T->lchild != NULL) { + l = Algo_6_55(T->lchild); + T->DescNum += l + 1; + } + + if(T->rchild != NULL) { + r = Algo_6_55(T->rchild); + T->DescNum += r + 1; + } + } + + return T->DescNum; +} + +// 先序输出二叉树及各结点其子孙数目 +void PreOrderPrint(BiTree T) { + if(T != NULL) { + printf("结点 %c 的子孙数目 %d\n", T->data, T->DescNum); + PreOrderPrint(T->lchild); + PreOrderPrint(T->rchild); + } +} diff --git a/CLion/ExerciseBook/06.55/BiTree.c b/CLion/ExerciseBook/06.55/BiTree.c new file mode 100644 index 0000000..23d4976 --- /dev/null +++ b/CLion/ExerciseBook/06.55/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // 在*T不为空时进行递归清理 + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.55/BiTree.h b/CLion/ExerciseBook/06.55/BiTree.h new file mode 100644 index 0000000..30f9027 --- /dev/null +++ b/CLion/ExerciseBook/06.55/BiTree.h @@ -0,0 +1,92 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 + + int DescNum; // 该结点的子孙数量 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T); + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.55/CMakeLists.txt b/CLion/ExerciseBook/06.55/CMakeLists.txt new file mode 100644 index 0000000..f7e0e6e --- /dev/null +++ b/CLion/ExerciseBook/06.55/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.55 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.55.c) +# 链接公共库 +target_link_libraries(06.55 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.55/LinkQueue.c b/CLion/ExerciseBook/06.55/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.55/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.55/LinkQueue.h b/CLion/ExerciseBook/06.55/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.55/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.55/TestData.txt b/CLion/ExerciseBook/06.55/TestData.txt new file mode 100644 index 0000000..39e3f58 --- /dev/null +++ b/CLion/ExerciseBook/06.55/TestData.txt @@ -0,0 +1 @@ +先序序列→ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.56-06.58/06.56-06.58.c b/CLion/ExerciseBook/06.56-06.58/06.56-06.58.c new file mode 100644 index 0000000..189086b --- /dev/null +++ b/CLion/ExerciseBook/06.56-06.58/06.56-06.58.c @@ -0,0 +1,502 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "BiThrTree.h" //**▲06 树和二叉树**// + +/* + * 在先序后继线索二叉树中寻找结点p的后继 + */ +BiThrTree Algo_6_56(BiThrTree p); + +// 测试方法Algo_6_56:输出树的先序序列 +void PreTraverse(BiThrTree Thrt); + + +/* + * 在后序后继线索二叉树中寻找结点p的后继 + */ +BiThrTree Algo_6_57(BiThrTree p); + +// 测试方法Algo_6_57:输出树的后序序列 +void PosTraverse(BiThrTree Thrt); + + +/* + * 将根结点为x,且结点x只有左子树的中序全线索二叉树插入为结点p的左子树, + * 其中,结点p所在的树也是中序全线索二叉树,Thrx指向线索二叉树x的头结点。 + * 注:如果结点p已经包含左子树,则将其左子树摘下,嫁接为根结点x的右子树 + */ +Status Algo_6_58(BiThrTree p, BiThrTree x, BiThrTree Thrx); + + +// 先序遍历二叉树T,并将其后继线索化 +Status PreOrderThreading(BiThrTree* Thrt, BiThrTree T); + +// 先序后继线索化的内部实现 +void PreTheading(BiThrTree p); + +// 对先序后继线索二叉树进行先序遍历(非递归算法) +Status PreOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)); + + +// 后序遍历二叉树T,并将其后继线索化(顺便会初始化parent域) +Status PosOrderThreading(BiThrTree* Thrt, BiThrTree T); + +// 后序后继线索化的内部实现(采用了逆先序的遍历方式) +void PosTheading(BiThrTree p); + +// 对后序后继线索二叉树进行后序遍历(非递归算法) +Status PosOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)); + + +// 测试函数,打印元素 +Status PrintElem(TElemType c); + + + +int main(int argc, char* argv[]) { + + printf("███题 6.56 验证...███\n"); + { + BiThrTree T; // 二叉树 + BiThrTree Thr; // 先序后继线索二叉树 + + printf("█ 按先序序列(ABDG^^^EH^^I^^CF^J^^^)创建二叉树...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf("█ 对二叉树进行先序后继线索化...\n"); + PreOrderThreading(&Thr, T); + + printf("█ 先序遍历先序后继线索二叉树:"); + PreOrderTraverse_Thr(Thr, PrintElem); + + printf("█ 测试方法Algo_6_56:输出树的先序序列:"); + PreTraverse(Thr); + } + PressEnterToContinue(); + + + printf("███题 6.57 验证...███\n"); + { + BiThrTree T; // 二叉树 + BiThrTree Thr; // 后序后继线索二叉树 + + printf("█ 按先序序列(ABDG^^^EH^^I^^CF^J^^^)创建二叉树...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf("█ 对二叉树进行后序后继线索化...\n"); + PosOrderThreading(&Thr, T); + + printf("█ 后序遍历后序后继线索二叉树:"); + PosOrderTraverse_Thr(Thr, PrintElem); + + printf("█ 测试方法Algo_6_57:输出树的后序序列:"); + PosTraverse(Thr); + } + PressEnterToContinue(); + + + printf("███题 6.58 验证...███\n"); + { + BiThrTree T; // 二叉树 + BiThrTree Thr; // 中序全线索二叉树 + + BiThrTree Tx; // 待插入的二叉树 + BiThrTree Thrx; // 待插入的中序全线索二叉树 + + BiThrTree p; + + printf("█ 按先序序列(ABDG^^^EH^^I^^CF^J^^^)创建二叉树...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf("█ 对二叉树进行中序全线索化...\n"); + InOrderThreading(&Thr, T); + + printf("█ 中序遍历中序全线索二叉树:"); + InOrderTraverse_Thr(Thr, PrintElem); + + printf("█ ===============================================\n"); + + printf("█ 按先序序列(012^47^^^35^^68^^9^^^)创建二叉树...\n"); + CreateBiTree(&Tx, "TestData_x.txt"); + + printf("█ 对二叉树进行中序全线索化...\n"); + InOrderThreading(&Thrx, Tx); + + printf("█ 中序遍历中序全线索二叉树:"); + InOrderTraverse_Thr(Thrx, PrintElem); + + printf("█ ===============================================\n"); + + p = T->lchild->rchild; + printf("█ 按照题意,将子树 x 插入到树 T 的 %c 结点上...\n", p->data); + Algo_6_58(p, Tx, Thrx); + + printf("█ 插入完成后的中序全线索二叉树为:"); + InOrderTraverse_Thr(Thr, PrintElem); + } + PressEnterToContinue(); + +} + + + +/* + * 在先序后继线索二叉树中寻找结点p的后继 + */ +BiThrTree Algo_6_56(BiThrTree p) { + if(p == NULL) { + return NULL; + } + + // 如果存在后继线索,直接获取后继信息 + if(p->RTag == Thread) { + p = p->rchild; + } else { + if(p->lchild != NULL) { + p = p->lchild; + } else { + p = p->rchild; + } + } + + return p; +} + +// 测试方法Algo_6_56:输出树的先序序列 +void PreTraverse(BiThrTree Thrt) { + BiThrTree p = Thrt->rchild; + + while(p != Thrt) { + printf("%c", p->data); + p = Algo_6_56(p); + } + + printf("\n"); +} + + +/* + * 在后序后继线索二叉树中寻找结点p的后继 + */ +BiThrTree Algo_6_57(BiThrTree p) { + if(p == NULL) { + return NULL; + } + + // 如果存在后继线索,直接获取后继信息 + if(p->RTag == Thread) { + p = p->rchild; + } else { + // 如果当前结点是左孩子 + if(p == p->parent->rchild) { + p = p->parent; + } else { + // 如果父结点没有右孩子 + if(p->parent->rchild == NULL || p->parent->RTag == Thread) { + p = p->parent; + } else { + p = p->parent->rchild; + + /* 查找右兄弟结点的左子树的最右端 */ + + while(p->lchild != NULL) { + p = p->lchild; + } + + while(p->rchild != NULL && p->RTag == Link) { + p = p->rchild; + } + } + } + } + + return p; +} + +// 测试方法Algo_6_57:输出树的后序序列 +void PosTraverse(BiThrTree Thrt) { + BiThrTree p = Thrt->rchild; + + while(p != Thrt) { + printf("%c", p->data); + p = Algo_6_57(p); + } + + printf("\n"); +} + + +/* + * 将根结点为x,且结点x只有左子树的中序全线索二叉树插入为结点p的左子树, + * 其中,结点p所在的树也是中序全线索二叉树,Thrx指向线索二叉树x的头结点。 + * 注:如果结点p已经包含左子树,则将其左子树摘下,嫁接为根结点x的右子树 + */ +Status Algo_6_58(BiThrTree p, BiThrTree x, BiThrTree Thrx) { + BiThrTree pPre; // 结点p的前驱 + + BiThrTree xFirst; // 树x的中序序列的第一个结点 + BiThrTree xLast; // 树x的中序序列的最后一个结点 + + BiThrTree lt; // p的左子树 + BiThrTree ltFirst; // 子树lt的中序序列的第一个结点 + + if(p==NULL || x==NULL) { + return ERROR; + } + + // x结点不允许存在右孩子 + if(x->RTag==Link) { + return ERROR; + } + + // 获取树x的中序序列的第一个结点和最后一个结点 + xFirst = Thrx->lchild; + // 如果存在左子树,一直向左遍历 + while(xFirst->LTag==Link){ + xFirst = xFirst->lchild; + } + xLast = Thrx->rchild; + + // 如果结点p不存在左子树 + if(p->LTag==Thread) { + pPre = p->lchild; // 直接获取p的前驱 + + p->LTag = Link; // 修改p的左线索为左孩子 + p->lchild = x; // 插入子树x + + xFirst->lchild = pPre; // 重置xFirst的左线索 + xLast->rchild = p; // 重置xLast的右线索 + + // 如果结点p存在左子树 + } else { + // 指向结点p的左子树 + lt = p->lchild; + + // 查找子树lt的中序序列的第一个结点 + ltFirst = lt; + // 如果存在左孩子,则一直向左遍历 + while(ltFirst->LTag==Link){ + ltFirst = ltFirst->lchild; + } + + x->RTag = Link; // 将lt插入为x的右子树 + x->rchild = lt; + + xFirst->lchild = ltFirst->lchild; // 接管子树lt的左线索 + ltFirst->lchild = x; // 子树lt的左线索指向x + + p->lchild = x; // 更新p的左子树 + } + + // 将x从Thrx上移除 + Thrx->lchild = Thrx->rchild = Thrx; + + return OK; +} + + +// 先序遍历二叉树T,并将其后继线索化 +Status PreOrderThreading(BiThrTree* Thrt, BiThrTree T) { + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(*Thrt == NULL) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + (*Thrt)->LTag = Link; + (*Thrt)->RTag = Thread; + (*Thrt)->rchild = NULL; + + // 空树只有线索头结点 + if(!T) { + (*Thrt)->lchild = (*Thrt)->rchild = *Thrt; + } else { + (*Thrt)->lchild = T; + pre = *Thrt; // 指向头结点 + + PreTheading(T); // 开始线索化 + + pre->RTag = Thread; // 最后一个结点线索化 + pre->rchild = *Thrt; // 最后一个结点指回头结点 + + (*Thrt)->rchild = T; // 头结点指向第一个结点,建立【循环】联系 + } + + return OK; +} + +// 先序后继线索化的内部实现 +void PreTheading(BiThrTree p) { + if(p == NULL) { + return; + } + + // 为上一个结点右子树建立后继线索 + if(pre->rchild == NULL) { + pre->RTag = Thread; + pre->rchild = p; + } else { + // 如果右子树不为空,则添加Link标记 + pre->RTag = Link; + } + + // pre向前挪一步 + pre = p; + + // 线索化左子树 + PreTheading(p->lchild); + + // 如果存在右子树,线索化右子树 + if(p->rchild != NULL && p->RTag == Link) { + PreTheading(p->rchild); + } +} + +// 遍历:对先序后继线索二叉树进行先序遍历(非递归算法) +Status PreOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)) { + BiThrTree p = Thrt; // p指向二叉树线索结点 + + while(p->rchild != Thrt) { + // 先向左访问,直到尽头 + while(p->lchild != NULL) { + p = p->lchild; + if(Visit(p->data) == ERROR) { + return ERROR; + } + } + + // 向左访问到头,则向右访问(通过线索) + if(p->rchild != Thrt) { + p = p->rchild; + if(Visit(p->data) == ERROR) { + return ERROR; + } + } + } + + printf("\n"); + + return OK; +} + + +// 后序遍历二叉树T,并将其后继线索化(顺便会初始化parent域) +Status PosOrderThreading(BiThrTree* Thrt, BiThrTree T) { + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(*Thrt == NULL) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + (*Thrt)->LTag = Link; + (*Thrt)->RTag = Thread; + (*Thrt)->rchild = *Thrt; + + if(T == NULL) { + (*Thrt)->lchild = (*Thrt)->rchild = *Thrt; + } else { + (*Thrt)->lchild = T; + pre = *Thrt; // 指向头结点 + + T->parent = *Thrt; + + PosTheading(T); // 开始线索化 + + (*Thrt)->rchild = pre; // 头结点的右线索指向后序第一个结点,建立【循环】联系 + } + + return OK; +} + +// 后序后继线索化的内部实现(采用了逆先序的遍历方式) +void PosTheading(BiThrTree p) { + if(p == NULL) { + return; + } + + // 为当前结点右子树建立后继线索 + if(p->rchild == NULL) { + p->RTag = Thread; + p->rchild = pre; + } else { + // 如果右子树不为空,则添加Link标记 + p->RTag = Link; + } + + // pre在正常顺序中为后一个结点 + pre = p; + + // 线索化右子树 + if(p->RTag != Thread) { + if(p->rchild != NULL) { + p->rchild->parent = p; + } + + PosTheading(p->rchild); + } + + if(p->lchild != NULL) { + p->lchild->parent = p; + } + + // 线索化左子树 + PosTheading(p->lchild); +} + +// 遍历:对后序后继线索二叉树进行后序遍历(非递归算法) +Status PosOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)) { + BiThrTree r = Thrt->rchild; // p指向后序第一个结点 + BiThrTree p; + + // 树不为空 + while(r != Thrt) { + if(Visit(r->data) == ERROR) { + return ERROR; + } + + // 存在后继线索 + if(r->RTag == Thread) { + r = r->rchild; + } else { + p = r->parent; + if(p == Thrt) { + break; // 已经遍历完成 + } + + // 如果当前结点是右孩子 + if(r == p->rchild) { + r = p; + + // 如果当前结点是左孩子 + } else { + // 父结点的右孩子为NULL + if(p->rchild == NULL || p->RTag == Thread) { + r = p; + } else { + r = p->rchild; + + /* 查找r结点左子树的最右端 */ + + while(r->lchild != NULL) { + r = r->lchild; + } + + while(r->rchild != NULL && r->RTag == Link) { + r = r->rchild; + } + } + } + } + } + + printf("\n"); + + return OK; +} + + +// 测试函数,打印元素 +Status PrintElem(TElemType c) { + printf("%c", c); + return OK; +} diff --git a/CLion/ExerciseBook/06.56-06.58/BiThrTree.c b/CLion/ExerciseBook/06.56-06.58/BiThrTree.c new file mode 100644 index 0000000..3b16b83 --- /dev/null +++ b/CLion/ExerciseBook/06.56-06.58/BiThrTree.c @@ -0,0 +1,182 @@ +/*======================= + * 线索二叉树 + * + * 包含算法: 6.5、6.6、6.7 + ========================*/ + +#include "BiThrTree.h" + +/* + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiThrTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * ████████ 算法6.6 ████████ + * + * 中序遍历二叉树T,并将其全线索化为线索二叉树Thrt。 + * 注:这里的线索包括前驱线索与后继线索。 + */ +Status InOrderThreading(BiThrTree* Thrt, BiThrTree T) { + // 建立头结点 + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(!*Thrt) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + + (*Thrt)->LTag = Link; // 左孩子,需要指向二叉树的根结点 + (*Thrt)->RTag = Thread; // 右指针,需要指向中序序列最后一个元素,以便逆中序遍历线索二叉树 + + (*Thrt)->rchild = *Thrt; + + // 若二叉树为空,则左指针回指 + if(!T) { + (*Thrt)->lchild = *Thrt; + } else { + (*Thrt)->lchild = T; // 指向二叉树头结点 + pre = *Thrt; // 记录前驱信息,初始化为线索二叉树头结点 + + InTheading(T); // 中序遍历,以进行中序线索化 + + pre->rchild = *Thrt; // 最后一个结点指回线索二叉树头结点 + pre->RTag = Thread; // 最后一个结点线索化 + (*Thrt)->rchild = pre; // 头结点指向最后一个结点,建立双向联系 + } + + return OK; + +} + +/* + * ████████ 算法6.5 ████████ + * + * 中序遍历中序全线索二叉树(非递归算法)。 + */ +Status InOrderTraverse_Thr(BiThrTree T, Status(Visit)(TElemType)) { + BiThrTree p = T->lchild; // p指向二叉树根结点(不同于线索二叉树的头结点) + + // 空树或遍历结束时,p==T + while(p != T) { + // 如果存在左孩子,则持续向左访问 + while(p->LTag == Link) { + p = p->lchild; + } + + // 访问左子树为空的结点(最左边) + if(!Visit(p->data)) { + return ERROR; + } + + // 如果存在后继线索(即没有右子树) + while(p->RTag == Thread && p->rchild != T) { + p = p->rchild; // 将p指向其后继 + Visit(p->data); // 访问后继结点 + } + + // 访问右子树 + p = p->rchild; + } + + printf("\n"); + + return OK; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiThrTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiThrTree) malloc(sizeof(BiThrNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + +/* + * ████████ 算法6.7 ████████ + * + * 中序全线索化的内部实现 + */ +static void InTheading(BiThrTree p) { + if(p) { + InTheading(p->lchild); // 线索化左子树 + + // 如果当前结点的左子树为空,则需要建立前驱线索 + if(!p->lchild) { + p->LTag = Thread; + p->lchild = pre; + + // 如果左子树不为空,添加左孩子标记(教材中缺少这一步骤) + } else { + p->LTag = Link; + } + + // 如果前驱结点的右子树为空,则为前驱结点建立后继线索 + if(!pre->rchild) { + pre->RTag = Thread; + pre->rchild = p; + + // 如果右子树不为空,添加右孩子标记(教材中缺少这一步骤) + } else { + p->RTag = Link; + } + + pre = p; // pre向前挪一步 + + InTheading(p->rchild); // 线索化右子树 + } +} diff --git a/CLion/ExerciseBook/06.56-06.58/BiThrTree.h b/CLion/ExerciseBook/06.56-06.58/BiThrTree.h new file mode 100644 index 0000000..eff37e1 --- /dev/null +++ b/CLion/ExerciseBook/06.56-06.58/BiThrTree.h @@ -0,0 +1,89 @@ +/*======================= + * 线索二叉树 + * + * 包含算法: 6.5、6.6、6.7 + ========================*/ + +#ifndef BITHRTREE_H +#define BITHRTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 线索二叉树结点类型标记 */ +typedef enum { + Link, Thread // Link==0:指针(孩子);Thread==1:线索 +} PointerTag; + +/* 线索二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 线索二叉树结点定义 */ +typedef struct BiThrNode { + TElemType data; // 结点元素 + struct BiThrNode* lchild; // 左孩子指针 + struct BiThrNode* rchild; // 右孩子指针 + PointerTag LTag; // 左指针标记 + PointerTag RTag; // 右指针标记 + + struct BiThrNode* parent; // 双亲结点指针,仅在非递归后序遍历后序后继线索二叉树时使用 +} BiThrNode; + +/* 指向线索二叉树结点的指针 */ +typedef BiThrNode* BiThrTree; + + +/* 全局变量 */ +static BiThrTree pre; // 指向当前访问结点的上一个结点(前驱) + + +/* + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiThrTree* T, char* path); + +/* + * ████████ 算法6.6 ████████ + * + * 中序遍历二叉树T,并将其全线索化为线索二叉树Thrt。 + * 注:这里的线索包括前驱线索与后继线索。 + */ +Status InOrderThreading(BiThrTree* Thrt, BiThrTree T); + +/* + * ████████ 算法6.5 ████████ + * + * 中序遍历中序全线索二叉树T(非递归算法)。 + */ +Status InOrderTraverse_Thr(BiThrTree T, Status(Visit)(TElemType)); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiThrTree* T, FILE* fp); + +/* + * ████████ 算法6.7 ████████ + * + * 中序全线索化的内部实现 + */ +static void InTheading(BiThrTree p); + +#endif diff --git a/CLion/ExerciseBook/06.56-06.58/CMakeLists.txt b/CLion/ExerciseBook/06.56-06.58/CMakeLists.txt new file mode 100644 index 0000000..202d3d2 --- /dev/null +++ b/CLion/ExerciseBook/06.56-06.58/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.56-06.58 BiThrTree.h BiThrTree.c 06.56-06.58.c) +# 链接公共库 +target_link_libraries(06.56-06.58 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.56-06.58/TestData_T.txt b/CLion/ExerciseBook/06.56-06.58/TestData_T.txt new file mode 100644 index 0000000..a4a4d99 --- /dev/null +++ b/CLion/ExerciseBook/06.56-06.58/TestData_T.txt @@ -0,0 +1 @@ +先序序列(朝上的三角代表空结点):ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.56-06.58/TestData_x.txt b/CLion/ExerciseBook/06.56-06.58/TestData_x.txt new file mode 100644 index 0000000..e9d57a8 --- /dev/null +++ b/CLion/ExerciseBook/06.56-06.58/TestData_x.txt @@ -0,0 +1 @@ +先序序列(朝上的三角代表空结点):012^47^^^35^^68^^9^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.59-06.62/06.59-06.62.c b/CLion/ExerciseBook/06.59-06.62/06.59-06.62.c new file mode 100644 index 0000000..a9c8f37 --- /dev/null +++ b/CLion/ExerciseBook/06.59-06.62/06.59-06.62.c @@ -0,0 +1,173 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "CSTree.h" //**▲06 树和二叉树**// + +#define MAX_TREE_SIZE 1024 // 树中元素数量最大值 + +/* + * 输出树的各条边 + */ +void Algo_6_59(CSTree T); + +/* + * 求树的叶子结点个数 + */ +int Algo_6_60(CSTree T); + +/* + * 求树的度:树中各结点度的最大值 + */ +int Algo_6_61(CSTree T); + +/* + * 求树的深度 + */ +int Algo_6_62(CSTree T); + + +int main(int argc, char* argv[]) { + CSTree T; + + printf("创建树(先序序列)T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("███题 6.59 验证...███\n"); + { + printf("输出所有边...\n"); + Algo_6_59(T); + printf("\n\n"); + } + + printf("███题 6.60 验证...███\n"); + { + int count; + + count = Algo_6_60(T); + printf("叶子结点个数为:count = %d\n", count); + printf("\n"); + } + + printf("███题 6.61 验证...███\n"); + { + int degree; + + degree = Algo_6_61(T); + printf("树的度为:degree = %d\n", degree); + printf("\n"); + } + + printf("███题 6.62 验证...███\n"); + { + int depth; + + depth = Algo_6_62(T); + printf("树的深度为:depth = %d\n", depth); + printf("\n"); + } + + return 0; +} + + +/* + * 输出树的各条边 + */ +void Algo_6_59(CSTree T) { + CSTree p, q; + + if(T == NULL) { + return; + } + + p = T; + q = T->firstchild; + + while(q != NULL) { + printf("(%c, %c) ", p->data, q->data); + q = q->nextsibling; + } + + Algo_6_59(T->firstchild); + Algo_6_59(T->nextsibling); +} + +/* + * 求树的叶子结点个数 + */ +int Algo_6_60(CSTree T) { + if(T == NULL) { + return 0; + } + + // 遇到叶子结点 + if(T->firstchild == NULL) { + return 1 + Algo_6_60(T->nextsibling); + } else { + return Algo_6_60(T->firstchild) + Algo_6_60(T->nextsibling); + } +} + +/* + * 求树的度:树中各结点度的最大值 + */ +int Algo_6_61(CSTree T) { + CSTree queue[MAX_TREE_SIZE]; // 按层序存储访问过的结点 + int parent[MAX_TREE_SIZE]; // 存储每个结点的父结点 + int order[MAX_TREE_SIZE]; // 存储每个结点的编号 + CSTree p, r; + int col, max; + int m, n; + int curParent; // 记录访问结点的父结点 + + if(T == NULL || T->firstchild == NULL) { + return 0; + } + + curParent = -2; + max = 0; + + m = n = 0; + + queue[n] = T; + parent[n] = -1; + order[n] = 0; + n++; + + while(m < n) { + p = queue[m]; + + // 遇到新的父结点 + if(parent[m] != curParent) { + curParent = parent[m]; + col = 1; // 重置列 + } else { + col++; + } + + if(col > max) { + max = col; + } + + // 存储子结点 + for(r = p->firstchild; r != NULL; r = r->nextsibling) { + queue[n] = r; + parent[n] = order[m]; // 为子结点存储父结点编号 + order[n] = n; // 记录当前结点的编号 + n++; + } + + m++; + } + + return max; +} + +/* + * 求树的深度 + */ +int Algo_6_62(CSTree T) { + return TreeDepth(T); // 已定义 +} diff --git a/CLion/ExerciseBook/06.59-06.62/CMakeLists.txt b/CLion/ExerciseBook/06.59-06.62/CMakeLists.txt new file mode 100644 index 0000000..9593cfd --- /dev/null +++ b/CLion/ExerciseBook/06.59-06.62/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.59-06.62 CSTree.h CSTree.c 06.59-06.62.c) +# 链接公共库 +target_link_libraries(06.59-06.62 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.59-06.62/CSTree.c b/CLion/ExerciseBook/06.59-06.62/CSTree.c new file mode 100644 index 0000000..318a093 --- /dev/null +++ b/CLion/ExerciseBook/06.59-06.62/CSTree.c @@ -0,0 +1,166 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#include "CSTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【先序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(CSTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入树的先序序列,如果没有孩子结点或没有兄弟节点,使用^代替:"); + Create(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CSTree T) { + int max = 0; + + Depth(T, 0, &max); + + return max; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(CSTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (CSTree) malloc(sizeof(CSNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + Create(&((*T)->firstchild), fp); // 创建长子 + Create(&((*T)->nextsibling), fp); // 创建右兄弟 + } +} + +// 计算树的深度的内部实现 +static void Depth(CSTree T, int d, int* max) { + if(T == NULL) { + return; + } + + d++; // 指示当前所在的层数 + + if(d > *max) { + *max = d; + } + + Depth(T->firstchild, d, max); // 向下遍历 + Depth(T->nextsibling, --d, max); // 向右遍历 +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T) { + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // 访问当前结点 + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/CLion/ExerciseBook/06.59-06.62/CSTree.h b/CLion/ExerciseBook/06.59-06.62/CSTree.h new file mode 100644 index 0000000..45a60c2 --- /dev/null +++ b/CLion/ExerciseBook/06.59-06.62/CSTree.h @@ -0,0 +1,87 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* (孩子-兄弟)树的结点定义 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // 指向长子 + struct CSNode* nextsibling; // 指向右兄弟 +} CSNode; + +/* (孩子-兄弟)树类型定义 */ +typedef CSNode* CSTree; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T); + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(CSTree* T, char* path); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T); + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CSTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(CSTree* T, FILE* fp); + +// 计算树的深度的内部实现 +static void Depth(CSTree T, int d, int *max); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T); + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row); + +#endif diff --git a/CLion/ExerciseBook/06.59-06.62/TestData.txt b/CLion/ExerciseBook/06.59-06.62/TestData.txt new file mode 100644 index 0000000..0b1431c --- /dev/null +++ b/CLion/ExerciseBook/06.59-06.62/TestData.txt @@ -0,0 +1 @@ +RAD^E^^B^CFG^H^K^^^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.63/06.63.c b/CLion/ExerciseBook/06.63/06.63.c new file mode 100644 index 0000000..c0a96d2 --- /dev/null +++ b/CLion/ExerciseBook/06.63/06.63.c @@ -0,0 +1,32 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "CTree.h" //**▲06 树和二叉树**// + +/* + * 计算孩子链表表示的树的深度 + */ +int Algo_6_63(CTree T); + + +int main(int argc, char* argv[]) { + CTree T; + + printf("创建树T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("此树的深度为: %d\n", Algo_6_63(T)); + printf("\n"); + + return 0; +} + + +/* + * 计算孩子链表表示的树的深度 + */ +int Algo_6_63(CTree T) { + return TreeDepth(T); // 已定义 +} diff --git a/CLion/ExerciseBook/06.63/CMakeLists.txt b/CLion/ExerciseBook/06.63/CMakeLists.txt new file mode 100644 index 0000000..28e8a9d --- /dev/null +++ b/CLion/ExerciseBook/06.63/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.63 LinkQueue.h LinkQueue.c CTree.h CTree.c 06.63.c) +# 链接公共库 +target_link_libraries(06.63 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.63/CTree.c b/CLion/ExerciseBook/06.63/CTree.c new file mode 100644 index 0000000..34f17d1 --- /dev/null +++ b/CLion/ExerciseBook/06.63/CTree.c @@ -0,0 +1,405 @@ +/*============================= + * 树的孩子链表(带双亲)的存储表示 + =============================*/ + +#include "CTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // 所有数据清零 + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(CTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入树的元素信息,对于空结点,使用^代替...\n"); + Create(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CTree T) { + int k, level; + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + return 0; + } + + /* + * 将k初始化为最后一个结点的位置 + * 由于树的结点按层序存储,故最后存储的结点必定位于最大层 + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(CTree* T, FILE* fp) { + int r; // 树的根结点的位置(索引) + int n; // 记录元素数量 + int cur; // 游标 + TElemType ch; + LinkQueue Q; + QElemType e; // 队列元素指示结点的位置 + char s[MAX_CHILD_COUNT + 1]; + int i; + ChildPtr p, pc; + + InitQueue(&Q); + + n = 0; + + // 读取根结点的位置 + if(fp == NULL) { + printf("请输入根结点的位置(0~%d):", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("请输入根结点的值:"); + scanf("%s", s); + ch = s[0]; + + // 树根入队 + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // 父结点的位置出队 + + printf("请依次输入 %c 的孩子结点,不存在孩子时输入一个^:", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // 当前结点位置入队 + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // 父结点的长子 + p = T->nodes[e].firstchild; + + // 包装当前结点 + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // 将当前结点添加到父结点的孩子链表中 + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // 找到链表尾部 + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // 录入根结点的位置 + ReadData(fp, "%d", &r); + cur = r; + + // 录入根结点的值 + ReadData(fp, "%s", s); + ch = s[0]; + printf("录入根结点的值:%c\n", ch); + + // 树根入队 + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("依次录入 %c 结点的孩子:", ch); + + // 录入孩子结点 + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // 父结点位置出队 + + // 遍历孩子 + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // 当前结点位置入队 + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // 包装当前结点 + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // 父结点的长子 + p = T->nodes[e].firstchild; + + // 将当前结点添加到父结点的孩子链表中 + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // 找到链表尾部 + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // 根结点的位置入队 + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // 父结点所在的层 + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // 如果行数发生了改变 + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // 结点e的孩子计数归0 + + // 每个结点出队时,先设置其最后一个孩子信息为无效,因为不是每个结点都有孩子结点 + pt[e].lastChild = -1; + + // 指向该结点的孩子链表 + cp = T.nodes[e].firstchild; + + // 释放该结点处的孩子链表所占内存 + while(cp != NULL) { + // 当前结点位置入队 + EnQueue(&Q, cp->child); + + // 记录行数 + pt[cp->child].row = pt[e].row + 1; + + // 记录列数 + pt[cp->child].col = ++count; + + // 记录当前结点是第几个孩子 + pt[cp->child].childIndex = ++n; + + // 为父结点跟新最后一个孩子的信息 + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // 计算T中结点的位置信息 + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("存储结构:\n"); + PrintFramework(T); +} + +// 图形化输出当前结构内部实现 +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // 初始化为无效的索引 + int rightBrother; + int k; + + // 访问当前结点 + printf("%c ", T.nodes[i].data); + + // 相比双亲表存储结构,求长子更容易了 + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // 遍历长子(需要先确定长子的身份) + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // 遍历右兄弟(需要先确定右兄弟的身份) + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // 访问当前结点的右兄弟前,如果当前结点不是最后一个孩子,则进行一次换行 + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/CLion/ExerciseBook/06.63/CTree.h b/CLion/ExerciseBook/06.63/CTree.h new file mode 100644 index 0000000..b75d508 --- /dev/null +++ b/CLion/ExerciseBook/06.63/CTree.h @@ -0,0 +1,129 @@ +/*============================= + * 树的孩子链表(带双亲)的存储表示 + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* 树的最大结点数 */ +#define MAX_TREE_SIZE 1024 + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 孩子结点定义 */ +typedef struct CTNode { + int child; // 该孩子在树中的索引 + struct CTNode* next; // 指向下一个孩子 +} CTNode; + +/* 指向孩子结点的指针 */ +typedef CTNode* ChildPtr; + +/* (双亲)树的结点定义 */ +typedef struct { + int parent; // 双亲位置域 + TElemType data; // 当前结点 + ChildPtr firstchild; // 孩子链表头指针 +} CTBox; + +/* + * (双亲)树类型定义 + * + *【注】 + * 1.树中结点在nodes中"紧邻"存储,没有空隙 + * 2.树根r可能出现在nodes的任意位置 + * 3.除根结点外,其他结点依次按层序顺着根结点往下排列(这一点与教材图示可能会有区别) + * 4.nodes数组是循环使用的(这一点教材未提到) + * 5.这里假设nodes空间是足够大的,可以视需求将其改为动态分配存储 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 存储树中结点 + int r; // 树根位置(索引) + int n; // 树的结点数 +} CTree; + + +/* + * 树中某个结点的信息 + * + * 注:相比双亲表存储结构,不需要再寄来当前结点的第一个孩子在树中的索引 + * */ +typedef struct{ + int row; // 当前结点所处的行 + int col; // 当前结点所处的列 + int childIndex; // 当前结点是第几个孩子 + int lastChild; // 当前结点的最后一个孩子在树中的索引 +} Pos; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CTree* T); + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(CTree* T, char* path); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CTree T); + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(CTree* T, FILE* fp); + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos(CTree T, Pos pt[]); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CTree T); + +// 图形化输出当前结构内部实现 +static void Print(CTree T, Pos pt[], int i); + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework(CTree T); + +#endif diff --git a/CLion/ExerciseBook/06.63/LinkQueue.c b/CLion/ExerciseBook/06.63/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.63/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.63/LinkQueue.h b/CLion/ExerciseBook/06.63/LinkQueue.h new file mode 100644 index 0000000..ec9c0e1 --- /dev/null +++ b/CLion/ExerciseBook/06.63/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// + +/* 链队元素类型定义 */ +typedef int QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.63/TestData.txt b/CLion/ExerciseBook/06.63/TestData.txt new file mode 100644 index 0000000..5a30a1c --- /dev/null +++ b/CLion/ExerciseBook/06.63/TestData.txt @@ -0,0 +1,12 @@ +根结点位置:5 +根结点的值:R +R的孩子结点:ABC +A的孩子结点:DE +B的孩子结点:^ +C的孩子结点:F +D的孩子结点:^ +E的孩子结点:^ +F的孩子结点:GHK +G的孩子结点:^ +H的孩子结点:^ +K的孩子结点:^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.64/06.64.c b/CLion/ExerciseBook/06.64/06.64.c new file mode 100644 index 0000000..425284d --- /dev/null +++ b/CLion/ExerciseBook/06.64/06.64.c @@ -0,0 +1,32 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "PTree.h" //**▲06 树和二叉树**// + +/* + * 计算双亲表表示的树的深度 + */ +int Algo_6_64(PTree T); + + +int main(int argc, char* argv[]) { + PTree T; + + printf("创建树T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("此树的深度为: %d\n", Algo_6_64(T)); + printf("\n"); + + return 0; +} + + +/* + * 计算双亲表表示的树的深度 + */ +int Algo_6_64(PTree T) { + return TreeDepth(T); // 已定义 +} diff --git a/CLion/ExerciseBook/06.64/CMakeLists.txt b/CLion/ExerciseBook/06.64/CMakeLists.txt new file mode 100644 index 0000000..de4a802 --- /dev/null +++ b/CLion/ExerciseBook/06.64/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.64 LinkQueue.h LinkQueue.c LinkList.h LinkList.c PTree.h PTree.c 06.64.c) +# 链接公共库 +target_link_libraries(06.64 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.64/LinkList.c b/CLion/ExerciseBook/06.64/LinkList.c new file mode 100644 index 0000000..563724e --- /dev/null +++ b/CLion/ExerciseBook/06.64/LinkList.c @@ -0,0 +1,163 @@ +/*=============================== + * 线性表的链式存储结构(链表) + * + * 包含算法: 2.8、2.9、2.10、2.11 + ================================*/ + +#include "LinkList.h" //**▲02 线性表**// + +/* + * 初始化 + * + * 只是初始化一个头结点。 + * 初始化成功则返回OK,否则返回ERROR。 + */ +Status InitList(LinkList* L) { + (*L) = (LinkList) malloc(sizeof(LNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + (*L)->next = NULL; + + return OK; +} + +/* + * 销毁(结构) + * + * 释放链表所占内存,头结点也会被清理。 + */ +Status DestroyList(LinkList* L) { + LinkList p; + + // 确保链表结构存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + + while(p != NULL) { + p = (*L)->next; + free(*L); + (*L) = p; + } + + *L = NULL; + + return OK; +} + +/* + * 置空(内容) + * + * 这里需要释放链表中非头结点处的空间。 + */ +Status ClearList(LinkList L) { + LinkList pre, p; + + // 确保链表存在 + if(L == NULL) { + return ERROR; + } + + p = L->next; + + // 释放链表上所有结点所占内存 + while(p != NULL) { + pre = p; + p = p->next; + free(pre); + } + + L->next = NULL; + + return OK; +} + +/* + * 查找 + * + * 返回链表中首个与e满足Compare关系的元素位序。 + * 如果不存在这样的元素,则返回0。 + * + *【备注】 + * 元素e是Compare函数第二个形参 + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + LinkList p; + + // 确保链表存在且不为空表 + if(L == NULL || L->next == NULL) { + return 0; + } + + i = 1; // i的初值为第1个元素的位序 + p = L->next; // p的初值为第1个元素的指针 + + while(p != NULL && !Compare(p->data, e)) { + i++; + p = p->next; + } + + if(p != NULL) { + return i; + } else { + return 0; + } +} + +/* + * ████████ 算法2.9 ████████ + * + * 插入 + * + * 向链表第i个位置上插入e,插入成功则返回OK,否则返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数 + */ +Status ListInsert(LinkList L, int i, ElemType e) { + LinkList p, s; + int j; + + // 确保链表存 + if(L == NULL) { + return ERROR; + } + + p = L; + j = 0; + + // 寻找第i-1个结点,且保证该结点本身不为NULL + while(p != NULL && j < i - 1) { + p = p->next; + ++j; + } + + // 如果遍历到头了,或者i的值不合规(比如i<=0),说明没找到合乎目标的结点 + if(p == NULL || j > i - 1) { + return ERROR; + } + + // 生成新结点 + s = (LinkList) malloc(sizeof(LNode)); + if(s == NULL) { + exit(OVERFLOW); + } + s->data = e; + s->next = p->next; + p->next = s; + + return OK; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 新增函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 判断线性表中两个元素是否相等 +Status Equal(ElemType e1, ElemType e2) { + return e1 == e2 ? TRUE : FALSE; +} diff --git a/CLion/ExerciseBook/06.64/LinkList.h b/CLion/ExerciseBook/06.64/LinkList.h new file mode 100644 index 0000000..5b2ddfe --- /dev/null +++ b/CLion/ExerciseBook/06.64/LinkList.h @@ -0,0 +1,82 @@ +/*=============================== + * 线性表的链式存储结构(链表) + * + * 包含算法: 2.8、2.9、2.10、2.11 + ================================*/ + +#ifndef LINKLIST_H +#define LINKLIST_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include // 提供 strstr 原型 +#include "Status.h" //**▲01 绪论**// + +/* 单链表元素类型定义 */ +typedef int ElemType; + +/* + * 单链表结构 + * + * 注:这里的单链表存在头结点 + */ +typedef struct LNode { + ElemType data; // 数据结点 + struct LNode* next; // 指向下一个结点的指针 +} LNode; + +// 指向单链表结点的指针 +typedef LNode* LinkList; + + +/* + * 初始化 + * + * 初始化成功则返回OK,否则返回ERROR。 + */ +Status InitList(LinkList* L); + +/* + * 销毁(结构) + * + * 释放链表所占内存。 + */ +Status DestroyList(LinkList* L); + +/* + * 置空(内容) + * + * 这里需要释放链表中非头结点处的空间。 + */ +Status ClearList(LinkList L); + +/* + * 查找 + * + * 返回链表中首个与e满足Compare关系的元素位序。 + * 如果不存在这样的元素,则返回0。 + * + *【备注】 + * 元素e是Compare函数第二个形参 + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * ████████ 算法2.9 ████████ + * + * 插入 + * + * 向链表第i个位置上插入e,插入成功则返回OK,否则返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数 + */ +Status ListInsert(LinkList L, int i, ElemType e); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 新增函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 判断线性表中两个元素是否相等 +Status Equal(ElemType e1, ElemType e2); + +#endif diff --git a/CLion/ExerciseBook/06.64/LinkQueue.c b/CLion/ExerciseBook/06.64/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.64/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.64/LinkQueue.h b/CLion/ExerciseBook/06.64/LinkQueue.h new file mode 100644 index 0000000..ec9c0e1 --- /dev/null +++ b/CLion/ExerciseBook/06.64/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// + +/* 链队元素类型定义 */ +typedef int QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.64/PTree.c b/CLion/ExerciseBook/06.64/PTree.c new file mode 100644 index 0000000..27cd05c --- /dev/null +++ b/CLion/ExerciseBook/06.64/PTree.c @@ -0,0 +1,348 @@ +/*================== + * 树的双亲表存储表示 + ===================*/ + +#include "PTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(PTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // 所有数据清零 + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(PTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入树的元素信息,对于空结点,使用^代替...\n"); + Create(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(PTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(PTree T) { + int k, level; + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + return 0; + } + + /* + * 将k初始化为最后一个结点的位置 + * 由于树的结点按层序存储,故最后存储的结点必定位于最大层 + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(PTree* T, FILE* fp) { + int r; // 树的根结点的位置(索引) + int n; // 记录元素数量 + int cur; // 游标 + TElemType ch; + LinkQueue Q; + QElemType e; // 队列元素指示结点的位置 + char s[MAX_CHILD_COUNT + 1]; + int i; + + InitQueue(&Q); + + n = 0; + + // 读取根结点的位置 + if(fp == NULL) { + printf("请输入根结点的位置(0~%d):", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("请输入根结点的值:"); + scanf("%s", s); + ch = s[0]; + + // 树根入队 + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // 父结点位置出队 + + printf("请依次输入 %c 的孩子结点,不存在孩子时输入一个^:", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // 当前结点位置入队 + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // 录入根结点的位置 + ReadData(fp, "%d", &r); + cur = r; + + // 录入根结点的值 + ReadData(fp, "%s", s); + ch = s[0]; + printf("录入根结点的值:%c\n", ch); + + // 树根入队 + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("依次录入 %c 结点的孩子:", ch); + + // 录入孩子结点 + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // 父结点位置出队 + + // 遍历孩子 + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // 当前结点位置入队 + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos(PTree T, Pos pt[]) { + LinkList Lt, Lt_parent, Lt_child; + int m, n, p, k, s; + int level; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + return; + } + + InitList(&Lt_parent); + InitList(&Lt_child); + + // 根结点的parent为-1 + ListInsert(Lt_parent, 1, -1); + + level = 1; + k = T.r; + m = n = 0; + s = -1; // 初始化头结点的父结点为-1 + + while(k != (T.r + T.n) % MAX_TREE_SIZE) { + // 结点k第一个孩子在树中的索引初始化为-1 + pt[k].firstChild = -1; + + // 结点k最后一个孩子在树中的索引初始化为-1 + pt[k].lastChild = -1; + + // 当前结点k的父结点 + p = T.nodes[k].parent; + if(p != s) { + s = p; // 追踪父结点的变化 + n = 0; // 父结点改变时,需要重新计数 + } + + // 判断当前结点是否为第level-1层结点的孩子 + if(LocateElem(Lt_parent, p, Equal)) { + ListInsert(Lt_child, ++m, k); + + pt[k].row = level; + pt[k].col = m; + pt[k].childIndex = ++n; + + // 确保当前结点父结点存在 + if(p != -1) { + // 第一个孩子在树中的索引 + if(pt[p].firstChild==-1) { + pt[p].firstChild = k; + } + + // 最后一个孩子在树中的索引 + pt[p].lastChild = k; + } + + k = (k + 1) % MAX_TREE_SIZE; + } else { + Lt = Lt_parent; + Lt_parent = Lt_child; + Lt_child = Lt; + ClearList(Lt_child); + + level++; + m = 0; + } + } + + DestroyList(&Lt_parent); + DestroyList(&Lt_child); +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(PTree T) { + Pos pt[MAX_TREE_SIZE]; + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // 计算T中结点的位置信息 + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("存储结构:\n"); + PrintFramework(T); +} + +// 图形化输出当前结构内部实现 +static void Print(PTree T, Pos pt[], int i) { + int firstChild; + int rightBrother; + int k; + + // 访问当前结点 + printf("%c ", T.nodes[i].data); + + firstChild = pt[i].firstChild; + + // 遍历长子(需要先确定长子的身份) + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // 遍历右兄弟(需要先确定右兄弟的身份) + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // 访问当前结点的右兄弟前,如果当前结点不是最后一个孩子,则进行一次换行 + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework(PTree T) { + int k; + + if(T.n == 0) { + printf("\n"); + return; + } + + printf("+---------+\n"); + printf("| i e p |\n"); + printf("+---------+\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + printf("| %2d %c %2d |\n", k, T.nodes[k].data, T.nodes[k].parent); + } + + printf("+---------+\n"); +} diff --git a/CLion/ExerciseBook/06.64/PTree.h b/CLion/ExerciseBook/06.64/PTree.h new file mode 100644 index 0000000..9b8cb2e --- /dev/null +++ b/CLion/ExerciseBook/06.64/PTree.h @@ -0,0 +1,117 @@ +/*================== + * 树的双亲表存储表示 + ===================*/ + +#ifndef PTREE_H +#define PTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// +#include "LinkList.h" //**▲02 线性表**// +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* 树的最大结点数 */ +#define MAX_TREE_SIZE 1024 + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* (双亲)树的结点定义 */ +typedef struct PTNode { + TElemType data; + int parent; // 双亲位置域 +} PTNode; + +/* + * (双亲)树类型定义 + * + *【注】 + * 1.树中结点在nodes中"紧邻"存储,没有空隙 + * 2.树根r可能出现在nodes的任意位置 + * 3.除根结点外,其他结点依次按层序顺着根结点往下排列(这一点与教材图示可能会有区别) + * 4.nodes数组是循环使用的(这一点教材未提到) + * 5.这里假设nodes空间是足够大的,可以视需求将其改为动态分配存储 + */ +typedef struct { + PTNode nodes[MAX_TREE_SIZE]; // 存储树中结点 + int r; // 树根位置(索引) + int n; // 树的结点数 +} PTree; + + +/* 树中某个结点的信息 */ +typedef struct{ + int row; // 当前结点所处的行 + int col; // 当前结点所处的列 + int childIndex; // 当前结点是第几个孩子 + int firstChild; // 当前结点的第一个孩子在树中的索引 + int lastChild; // 当前结点的最后一个孩子在树中的索引 +} Pos; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(PTree* T); + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(PTree* T, char* path); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(PTree T); + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(PTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(PTree* T, FILE* fp); + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos(PTree T, Pos pt[]); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(PTree T); + +// 图形化输出当前结构内部实现 +static void Print(PTree T, Pos pt[], int i); + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework(PTree T); + +#endif diff --git a/CLion/ExerciseBook/06.64/TestData.txt b/CLion/ExerciseBook/06.64/TestData.txt new file mode 100644 index 0000000..5a30a1c --- /dev/null +++ b/CLion/ExerciseBook/06.64/TestData.txt @@ -0,0 +1,12 @@ +根结点位置:5 +根结点的值:R +R的孩子结点:ABC +A的孩子结点:DE +B的孩子结点:^ +C的孩子结点:F +D的孩子结点:^ +E的孩子结点:^ +F的孩子结点:GHK +G的孩子结点:^ +H的孩子结点:^ +K的孩子结点:^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.65/06.65.c b/CLion/ExerciseBook/06.65/06.65.c new file mode 100644 index 0000000..02ce904 --- /dev/null +++ b/CLion/ExerciseBook/06.65/06.65.c @@ -0,0 +1,85 @@ +#include +#include // 提供strlen原型 +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 全局变量 */ +char Pre[] = "ABDGEHICFJ"; // 前序序列 +char In[] = "GDBHEIAFJC"; // 中序序列 + +/* + * 由前序序列和中序序列构造二叉树 + */ +Status Algo_6_65(BiTree* T); + +// 构造二叉树的内部实现 +BiTree BuildTree(int pre_start, int pre_end, int in_start, int in_end); //递归创建二叉树 + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("二叉树先序序列为:%s\n", Pre); + printf("二叉树中序序列为:%s\n", In); + printf("\n"); + + printf("由此构造的二叉树为 T = \n"); + Algo_6_65(&T); + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * 由前序序列和中序序列构造二叉树 + */ +Status Algo_6_65(BiTree* T) { + int len_pre, len_in; + + len_pre = strlen(Pre); + len_in = strlen(In); + + if(len_pre == 0 || len_in == 0 || len_pre != len_in) { + return ERROR; + } + + *T = BuildTree(0, len_pre - 1, 0, len_in - 1); + + return OK; +} + +// 构造二叉树的内部实现 +BiTree BuildTree(int pre_start, int pre_end, int in_start, int in_end) { + BiTree T; + int i, LTreeLen, RTreeLen; + + T = (BiTree) malloc(sizeof(BiTNode)); // 建立根结点 + if(T == NULL) { + exit(OVERFLOW); + } + T->data = Pre[pre_start]; // 遍历前序存储的结点 + T->lchild = T->rchild = NULL; // 初始化时置空左右孩子指针 + + i = in_start; + while(In[i] != T->data) { // 在中序序列中寻找根结点位置 + i++; + } + + LTreeLen = i - in_start; // 左子树长度 + RTreeLen = in_end - i; // 右子树长度 + + // 左子树存在 + if(LTreeLen) { + T->lchild = BuildTree(pre_start + 1, pre_start + LTreeLen, in_start, i - 1); + } + + // 右子树存在 + if(RTreeLen) { + T->rchild = BuildTree(pre_start + LTreeLen + 1, pre_end, i + 1, in_end); + } + + return T; +} diff --git a/CLion/ExerciseBook/06.65/BiTree.c b/CLion/ExerciseBook/06.65/BiTree.c new file mode 100644 index 0000000..6dc871b --- /dev/null +++ b/CLion/ExerciseBook/06.65/BiTree.c @@ -0,0 +1,121 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.65/BiTree.h b/CLion/ExerciseBook/06.65/BiTree.h new file mode 100644 index 0000000..ee19645 --- /dev/null +++ b/CLion/ExerciseBook/06.65/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.65/CMakeLists.txt b/CLion/ExerciseBook/06.65/CMakeLists.txt new file mode 100644 index 0000000..958ca23 --- /dev/null +++ b/CLion/ExerciseBook/06.65/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.65 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.65.c) +# 链接公共库 +target_link_libraries(06.65 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.65/LinkQueue.c b/CLion/ExerciseBook/06.65/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.65/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.65/LinkQueue.h b/CLion/ExerciseBook/06.65/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.65/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.66/06.66.c b/CLion/ExerciseBook/06.66/06.66.c new file mode 100644 index 0000000..9e27a96 --- /dev/null +++ b/CLion/ExerciseBook/06.66/06.66.c @@ -0,0 +1,74 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "PTree.h" //**▲06 树和二叉树**// +#include "CSTree.h" //**▲06 树和二叉树**// + +/* + * 树的双亲表示法转为树的孩子-兄弟表示法 + */ +CSTree Algo_6_66(PTree T); + + +int main(int argc, char* argv[]) { + PTree PT; + CSTree CST; + + printf("创建树T...\n"); + InitTree_P(&PT); + CreateTree_P(&PT, "TestData.txt"); + PrintGraph_P(PT); + printf("\n"); + + printf("树的双亲表示法转为树的孩子-兄弟表示法:\n"); + CST = Algo_6_66(PT); + PrintGraph_CS(CST); + printf("\n"); + + return 0; +} + + +/* + * 树的双亲表示法转为树的孩子-兄弟表示法 + */ +CSTree Algo_6_66(PTree T) { + CSTree p, q; + CSTree tree[MAX_TREE_SIZE] = {NULL}; + int i, j, k; + + // 双亲表按层序存储 + for(i = T.r, j = T.r; i != (T.r + T.n) % MAX_TREE_SIZE; i = (i + 1) % MAX_TREE_SIZE) { + // 获取该结点的父结点 + k = T.nodes[i].parent; + + // 复制结点信息 + p = (CSTree) malloc(sizeof(CSNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->data = T.nodes[i].data; + p->firstchild = p->nextsibling = NULL; + + // 当前结点存在父结点 + if(k != -1) { + // 当前结点作为了第一个孩子 + if(tree[k]->firstchild == NULL) { + tree[k]->firstchild = p; + + // 当前结点不是第一个孩子,则首先查找其父结点的孩子链表的尾部 + } else { + for(q = tree[k]->firstchild; q->nextsibling != NULL; q = q->nextsibling) { + // 寻找孩子链表的末端 + } + + q->nextsibling = p; + } + } + + tree[j] = p; + j = (j + 1) % MAX_TREE_SIZE; + } + + return tree[T.r]; +} diff --git a/CLion/ExerciseBook/06.66/CMakeLists.txt b/CLion/ExerciseBook/06.66/CMakeLists.txt new file mode 100644 index 0000000..923b785 --- /dev/null +++ b/CLion/ExerciseBook/06.66/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.66 LinkQueue.h LinkQueue.c LinkList.h LinkList.c PTree.h PTree.c CSTree.h CSTree.c 06.66.c) +# 链接公共库 +target_link_libraries(06.66 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.66/CSTree.c b/CLion/ExerciseBook/06.66/CSTree.c new file mode 100644 index 0000000..8d2245e --- /dev/null +++ b/CLion/ExerciseBook/06.66/CSTree.c @@ -0,0 +1,67 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#include "CSTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree_CS(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty_CS(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// 以图形化形式输出当前结构 +void PrintGraph_CS(CSTree T) { + + // 遇到空树则无需继续计算 + if(TreeEmpty_CS(T)) { + printf("\n"); + return; + } + + Print_CS(T, 0); + + printf("\n"); +} + +// 图形化输出当前结构内部实现 +static void Print_CS(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // 访问当前结点 + printf("%c ", T->data); + + Print_CS(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print_CS(T->nextsibling, row); + } +} diff --git a/CLion/ExerciseBook/06.66/CSTree.h b/CLion/ExerciseBook/06.66/CSTree.h new file mode 100644 index 0000000..e2ff2c0 --- /dev/null +++ b/CLion/ExerciseBook/06.66/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* (孩子-兄弟)树的结点定义 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // 指向长子 + struct CSNode* nextsibling; // 指向右兄弟 +} CSNode; + +/* (孩子-兄弟)树类型定义 */ +typedef CSNode* CSTree; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree_CS(CSTree* T); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty_CS(CSTree T); + +// 以图形化形式输出当前结构 +void PrintGraph_CS(CSTree T); + +// 图形化输出当前结构内部实现 +static void Print_CS(CSTree T, int row); + +#endif diff --git a/CLion/ExerciseBook/06.66/LinkList.c b/CLion/ExerciseBook/06.66/LinkList.c new file mode 100644 index 0000000..563724e --- /dev/null +++ b/CLion/ExerciseBook/06.66/LinkList.c @@ -0,0 +1,163 @@ +/*=============================== + * 线性表的链式存储结构(链表) + * + * 包含算法: 2.8、2.9、2.10、2.11 + ================================*/ + +#include "LinkList.h" //**▲02 线性表**// + +/* + * 初始化 + * + * 只是初始化一个头结点。 + * 初始化成功则返回OK,否则返回ERROR。 + */ +Status InitList(LinkList* L) { + (*L) = (LinkList) malloc(sizeof(LNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + (*L)->next = NULL; + + return OK; +} + +/* + * 销毁(结构) + * + * 释放链表所占内存,头结点也会被清理。 + */ +Status DestroyList(LinkList* L) { + LinkList p; + + // 确保链表结构存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + + while(p != NULL) { + p = (*L)->next; + free(*L); + (*L) = p; + } + + *L = NULL; + + return OK; +} + +/* + * 置空(内容) + * + * 这里需要释放链表中非头结点处的空间。 + */ +Status ClearList(LinkList L) { + LinkList pre, p; + + // 确保链表存在 + if(L == NULL) { + return ERROR; + } + + p = L->next; + + // 释放链表上所有结点所占内存 + while(p != NULL) { + pre = p; + p = p->next; + free(pre); + } + + L->next = NULL; + + return OK; +} + +/* + * 查找 + * + * 返回链表中首个与e满足Compare关系的元素位序。 + * 如果不存在这样的元素,则返回0。 + * + *【备注】 + * 元素e是Compare函数第二个形参 + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + LinkList p; + + // 确保链表存在且不为空表 + if(L == NULL || L->next == NULL) { + return 0; + } + + i = 1; // i的初值为第1个元素的位序 + p = L->next; // p的初值为第1个元素的指针 + + while(p != NULL && !Compare(p->data, e)) { + i++; + p = p->next; + } + + if(p != NULL) { + return i; + } else { + return 0; + } +} + +/* + * ████████ 算法2.9 ████████ + * + * 插入 + * + * 向链表第i个位置上插入e,插入成功则返回OK,否则返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数 + */ +Status ListInsert(LinkList L, int i, ElemType e) { + LinkList p, s; + int j; + + // 确保链表存 + if(L == NULL) { + return ERROR; + } + + p = L; + j = 0; + + // 寻找第i-1个结点,且保证该结点本身不为NULL + while(p != NULL && j < i - 1) { + p = p->next; + ++j; + } + + // 如果遍历到头了,或者i的值不合规(比如i<=0),说明没找到合乎目标的结点 + if(p == NULL || j > i - 1) { + return ERROR; + } + + // 生成新结点 + s = (LinkList) malloc(sizeof(LNode)); + if(s == NULL) { + exit(OVERFLOW); + } + s->data = e; + s->next = p->next; + p->next = s; + + return OK; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 新增函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 判断线性表中两个元素是否相等 +Status Equal(ElemType e1, ElemType e2) { + return e1 == e2 ? TRUE : FALSE; +} diff --git a/CLion/ExerciseBook/06.66/LinkList.h b/CLion/ExerciseBook/06.66/LinkList.h new file mode 100644 index 0000000..5b2ddfe --- /dev/null +++ b/CLion/ExerciseBook/06.66/LinkList.h @@ -0,0 +1,82 @@ +/*=============================== + * 线性表的链式存储结构(链表) + * + * 包含算法: 2.8、2.9、2.10、2.11 + ================================*/ + +#ifndef LINKLIST_H +#define LINKLIST_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include // 提供 strstr 原型 +#include "Status.h" //**▲01 绪论**// + +/* 单链表元素类型定义 */ +typedef int ElemType; + +/* + * 单链表结构 + * + * 注:这里的单链表存在头结点 + */ +typedef struct LNode { + ElemType data; // 数据结点 + struct LNode* next; // 指向下一个结点的指针 +} LNode; + +// 指向单链表结点的指针 +typedef LNode* LinkList; + + +/* + * 初始化 + * + * 初始化成功则返回OK,否则返回ERROR。 + */ +Status InitList(LinkList* L); + +/* + * 销毁(结构) + * + * 释放链表所占内存。 + */ +Status DestroyList(LinkList* L); + +/* + * 置空(内容) + * + * 这里需要释放链表中非头结点处的空间。 + */ +Status ClearList(LinkList L); + +/* + * 查找 + * + * 返回链表中首个与e满足Compare关系的元素位序。 + * 如果不存在这样的元素,则返回0。 + * + *【备注】 + * 元素e是Compare函数第二个形参 + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * ████████ 算法2.9 ████████ + * + * 插入 + * + * 向链表第i个位置上插入e,插入成功则返回OK,否则返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数 + */ +Status ListInsert(LinkList L, int i, ElemType e); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 新增函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 判断线性表中两个元素是否相等 +Status Equal(ElemType e1, ElemType e2); + +#endif diff --git a/CLion/ExerciseBook/06.66/LinkQueue.c b/CLion/ExerciseBook/06.66/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.66/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.66/LinkQueue.h b/CLion/ExerciseBook/06.66/LinkQueue.h new file mode 100644 index 0000000..ec9c0e1 --- /dev/null +++ b/CLion/ExerciseBook/06.66/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// + +/* 链队元素类型定义 */ +typedef int QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.66/PTree.c b/CLion/ExerciseBook/06.66/PTree.c new file mode 100644 index 0000000..4693531 --- /dev/null +++ b/CLion/ExerciseBook/06.66/PTree.c @@ -0,0 +1,320 @@ +/*================== + * 树的双亲表存储表示 + ===================*/ + +#include "PTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree_P(PTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // 所有数据清零 + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree_P(PTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入树的元素信息,对于空结点,使用^代替...\n"); + Create_P(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create_P(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty_P(PTree T) { + return T.n == 0 ? TRUE : FALSE; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create_P(PTree* T, FILE* fp) { + int r; // 树的根结点的位置(索引) + int n; // 记录元素数量 + int cur; // 游标 + TElemType ch; + LinkQueue Q; + QElemType e; // 队列元素指示结点的位置 + char s[MAX_CHILD_COUNT + 1]; + int i; + + InitQueue(&Q); + + n = 0; + + // 读取根结点的位置 + if(fp == NULL) { + printf("请输入根结点的位置(0~%d):", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("请输入根结点的值:"); + scanf("%s", s); + ch = s[0]; + + // 树根入队 + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // 父结点位置出队 + + printf("请依次输入 %c 的孩子结点,不存在孩子时输入一个^:", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // 当前结点位置入队 + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // 录入根结点的位置 + ReadData(fp, "%d", &r); + cur = r; + + // 录入根结点的值 + ReadData(fp, "%s", s); + ch = s[0]; + printf("录入根结点的值:%c\n", ch); + + // 树根入队 + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("依次录入 %c 结点的孩子:", ch); + + // 录入孩子结点 + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // 父结点位置出队 + + // 遍历孩子 + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // 当前结点位置入队 + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos_P(PTree T, Pos pt[]) { + LinkList Lt, Lt_parent, Lt_child; + int m, n, p, k, s; + int level; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // 遇到空树则无需继续计算 + if(TreeEmpty_P(T)) { + return; + } + + InitList(&Lt_parent); + InitList(&Lt_child); + + // 根结点的parent为-1 + ListInsert(Lt_parent, 1, -1); + + level = 1; + k = T.r; + m = n = 0; + s = -1; // 初始化头结点的父结点为-1 + + while(k != (T.r + T.n) % MAX_TREE_SIZE) { + // 结点k第一个孩子在树中的索引初始化为-1 + pt[k].firstChild = -1; + + // 结点k最后一个孩子在树中的索引初始化为-1 + pt[k].lastChild = -1; + + // 当前结点k的父结点 + p = T.nodes[k].parent; + if(p != s) { + s = p; // 追踪父结点的变化 + n = 0; // 父结点改变时,需要重新计数 + } + + // 判断当前结点是否为第level-1层结点的孩子 + if(LocateElem(Lt_parent, p, Equal)) { + ListInsert(Lt_child, ++m, k); + + pt[k].row = level; + pt[k].col = m; + pt[k].childIndex = ++n; + + // 确保当前结点父结点存在 + if(p != -1) { + // 第一个孩子在树中的索引 + if(pt[p].firstChild==-1) { + pt[p].firstChild = k; + } + + // 最后一个孩子在树中的索引 + pt[p].lastChild = k; + } + + k = (k + 1) % MAX_TREE_SIZE; + } else { + Lt = Lt_parent; + Lt_parent = Lt_child; + Lt_child = Lt; + ClearList(Lt_child); + + level++; + m = 0; + } + } + + DestroyList(&Lt_parent); + DestroyList(&Lt_child); +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph_P(PTree T) { + Pos pt[MAX_TREE_SIZE]; + + // 遇到空树则无需继续计算 + if(TreeEmpty_P(T)) { + printf("\n"); + return; + } + + // 计算T中结点的位置信息 + getPos_P(T, pt); + + Print_P(T, pt, T.r); + + printf("\n"); + + printf("存储结构:\n"); + PrintFramework_P(T); +} + +// 图形化输出当前结构内部实现 +static void Print_P(PTree T, Pos pt[], int i) { + int firstChild; + int rightBrother; + int k; + + // 访问当前结点 + printf("%c ", T.nodes[i].data); + + firstChild = pt[i].firstChild; + + // 遍历长子(需要先确定长子的身份) + if(firstChild != -1) { + Print_P(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // 遍历右兄弟(需要先确定右兄弟的身份) + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // 访问当前结点的右兄弟前,如果当前结点不是最后一个孩子,则进行一次换行 + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print_P(T, pt, rightBrother); + } +} + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework_P(PTree T) { + int k; + + if(T.n == 0) { + printf("\n"); + return; + } + + printf("+---------+\n"); + printf("| i e p |\n"); + printf("+---------+\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + printf("| %2d %c %2d |\n", k, T.nodes[k].data, T.nodes[k].parent); + } + + printf("+---------+\n"); +} diff --git a/CLion/ExerciseBook/06.66/PTree.h b/CLion/ExerciseBook/06.66/PTree.h new file mode 100644 index 0000000..d4528fd --- /dev/null +++ b/CLion/ExerciseBook/06.66/PTree.h @@ -0,0 +1,110 @@ +/*================== + * 树的双亲表存储表示 + ===================*/ + +#ifndef PTREE_H +#define PTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// +#include "LinkList.h" //**▲02 线性表**// +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* 树的最大结点数 */ +#define MAX_TREE_SIZE 1024 + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* (双亲)树的结点定义 */ +typedef struct PTNode { + TElemType data; + int parent; // 双亲位置域 +} PTNode; + +/* + * (双亲)树类型定义 + * + *【注】 + * 1.树中结点在nodes中"紧邻"存储,没有空隙 + * 2.树根r可能出现在nodes的任意位置 + * 3.除根结点外,其他结点依次按层序顺着根结点往下排列(这一点与教材图示可能会有区别) + * 4.nodes数组是循环使用的(这一点教材未提到) + * 5.这里假设nodes空间是足够大的,可以视需求将其改为动态分配存储 + */ +typedef struct { + PTNode nodes[MAX_TREE_SIZE]; // 存储树中结点 + int r; // 树根位置(索引) + int n; // 树的结点数 +} PTree; + + +/* 树中某个结点的信息 */ +typedef struct{ + int row; // 当前结点所处的行 + int col; // 当前结点所处的列 + int childIndex; // 当前结点是第几个孩子 + int firstChild; // 当前结点的第一个孩子在树中的索引 + int lastChild; // 当前结点的最后一个孩子在树中的索引 +} Pos; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree_P(PTree* T); + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree_P(PTree* T, char* path); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty_P(PTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create_P(PTree* T, FILE* fp); + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos_P(PTree T, Pos pt[]); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph_P(PTree T); + +// 图形化输出当前结构内部实现 +static void Print_P(PTree T, Pos pt[], int i); + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework_P(PTree T); + +#endif diff --git a/CLion/ExerciseBook/06.66/TestData.txt b/CLion/ExerciseBook/06.66/TestData.txt new file mode 100644 index 0000000..5a30a1c --- /dev/null +++ b/CLion/ExerciseBook/06.66/TestData.txt @@ -0,0 +1,12 @@ +根结点位置:5 +根结点的值:R +R的孩子结点:ABC +A的孩子结点:DE +B的孩子结点:^ +C的孩子结点:F +D的孩子结点:^ +E的孩子结点:^ +F的孩子结点:GHK +G的孩子结点:^ +H的孩子结点:^ +K的孩子结点:^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.67/06.67.c b/CLion/ExerciseBook/06.67/06.67.c new file mode 100644 index 0000000..bdf0ebc --- /dev/null +++ b/CLion/ExerciseBook/06.67/06.67.c @@ -0,0 +1,84 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "CSTree.h" //**▲06 树和二叉树**// + +#define MAX_TREE_SIZE 1024 // 树中元素数量最大值 + +/* + * 创建树的孩子-兄弟结构 + */ +Status Algo_6_67(CSTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf("创建孩子-兄弟二叉树:\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_67(&T, fp); + fclose(fp); + printf("\n"); + + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * 创建树的孩子-兄弟结构 + */ +Status Algo_6_67(CSTree* T, FILE* fp) { + char input[3]; + CSTree tree[MAX_TREE_SIZE]; // 顺序存储遇到的每个结点 + CSTree p, q; + int m, n, count; + + m = n = 0; + count = 0; + + while(TRUE) { + printf("录入第 %2d 个二元组:", ++count); + ReadData(fp, "%s", input); + printf("%s\n", input); + + // 退出标志 + if(input[1] == '^') { + return OK; + } + + p = (CSTree) malloc(sizeof(CSNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->data = input[1]; // 当前结点信息 + p->firstchild = p->nextsibling = NULL; + + // 根结点 + if(input[0] == '^') { + *T = p; + } else { + // 查找根结点在tree中的位置 + while(tree[m]->data != input[0]) { + m++; + } + + // 当前结点作为第一个孩子 + if(tree[m]->firstchild == NULL) { + tree[m]->firstchild = p; + } else { + for(q = tree[m]->firstchild; q->nextsibling != NULL; q = q->nextsibling) { + // 寻找孩子链表的末端 + } + + // 插入当前结点 + q->nextsibling = p; + } + } + + tree[n++] = p; + } +} diff --git a/CLion/ExerciseBook/06.67/CMakeLists.txt b/CLion/ExerciseBook/06.67/CMakeLists.txt new file mode 100644 index 0000000..75c840f --- /dev/null +++ b/CLion/ExerciseBook/06.67/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.67 CSTree.h CSTree.c 06.67.c) +# 链接公共库 +target_link_libraries(06.67 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.67/CSTree.c b/CLion/ExerciseBook/06.67/CSTree.c new file mode 100644 index 0000000..37a4c27 --- /dev/null +++ b/CLion/ExerciseBook/06.67/CSTree.c @@ -0,0 +1,67 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#include "CSTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T) { + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // 访问当前结点 + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/CLion/ExerciseBook/06.67/CSTree.h b/CLion/ExerciseBook/06.67/CSTree.h new file mode 100644 index 0000000..ac663b1 --- /dev/null +++ b/CLion/ExerciseBook/06.67/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* (孩子-兄弟)树的结点定义 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // 指向长子 + struct CSNode* nextsibling; // 指向右兄弟 +} CSNode; + +/* (孩子-兄弟)树类型定义 */ +typedef CSNode* CSTree; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T); + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T); + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row); + +#endif diff --git a/CLion/ExerciseBook/06.67/TestData.txt b/CLion/ExerciseBook/06.67/TestData.txt new file mode 100644 index 0000000..3804274 --- /dev/null +++ b/CLion/ExerciseBook/06.67/TestData.txt @@ -0,0 +1,7 @@ +^A +AB +AC +AD +CE +CF +^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.68/06.68.c b/CLion/ExerciseBook/06.68/06.68.c new file mode 100644 index 0000000..fc23651 --- /dev/null +++ b/CLion/ExerciseBook/06.68/06.68.c @@ -0,0 +1,97 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "CSTree.h" //**▲06 树和二叉树**// + +#define MAX_TREE_SIZE 1024 // 树中元素数量最大值 + +/* + * 创建树的孩子-兄弟结构 + */ +Status Algo_6_68(CSTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf("创建孩子-兄弟二叉树:\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_68(&T, fp); + fclose(fp); + printf("\n"); + + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * 创建树的孩子-兄弟结构 + */ +Status Algo_6_68(CSTree* T, FILE* fp) { + CSTree queue[MAX_TREE_SIZE] = {NULL}; // 按层序存储遇到的结点 + int d[MAX_TREE_SIZE]; // 存储该结点的度 + int parent[MAX_TREE_SIZE]; // 存储该结点的父结点信息 + CSTree p; + int x; + char ch; + int m, n; + int i; + + d[0] = 1; + + for(m = 0, n = 1; m < n; m++) { + p = NULL; + i = 0; + + while(i < d[m]) { + // 跳过换行标记 + ch = getc(fp); + if(ch == '\n' || ch == '\r') { + continue; + } else { + ungetc(ch, fp); + } + + // 读取结点信息 + ReadData(fp, "%c%d", &ch, &x); + printf("%c %d\n", ch, x); + if(x < 0) { + return ERROR; + } + + d[n] = x; + parent[n] = m; + + // 创建新结点 + queue[n] = (CSTree) malloc(sizeof(CSNode)); + if(queue[n] == NULL) { + exit(OVERFLOW); + } + queue[n]->data = ch; + queue[n]->firstchild = queue[n]->nextsibling = NULL; + + // 追踪该层首个结点 + if(p == NULL) { + p = queue[n]; + } else { + // 将孩子结点串联到一起 + queue[n - 1]->nextsibling = queue[n]; + } + + n++; + i++; + } + + if(m > 0 && queue[m]->firstchild == NULL) { + queue[m]->firstchild = p; + } + } + + *T = queue[1]; + + return OK; +} diff --git a/CLion/ExerciseBook/06.68/CMakeLists.txt b/CLion/ExerciseBook/06.68/CMakeLists.txt new file mode 100644 index 0000000..107f58a --- /dev/null +++ b/CLion/ExerciseBook/06.68/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.68 CSTree.h CSTree.c 06.68.c) +# 链接公共库 +target_link_libraries(06.68 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.68/CSTree.c b/CLion/ExerciseBook/06.68/CSTree.c new file mode 100644 index 0000000..37a4c27 --- /dev/null +++ b/CLion/ExerciseBook/06.68/CSTree.c @@ -0,0 +1,67 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#include "CSTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T) { + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // 访问当前结点 + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/CLion/ExerciseBook/06.68/CSTree.h b/CLion/ExerciseBook/06.68/CSTree.h new file mode 100644 index 0000000..ac663b1 --- /dev/null +++ b/CLion/ExerciseBook/06.68/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* (孩子-兄弟)树的结点定义 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // 指向长子 + struct CSNode* nextsibling; // 指向右兄弟 +} CSNode; + +/* (孩子-兄弟)树类型定义 */ +typedef CSNode* CSTree; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T); + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T); + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row); + +#endif diff --git a/CLion/ExerciseBook/06.68/TestData.txt b/CLion/ExerciseBook/06.68/TestData.txt new file mode 100644 index 0000000..15fc534 --- /dev/null +++ b/CLion/ExerciseBook/06.68/TestData.txt @@ -0,0 +1,10 @@ +R 3 +A 2 +B 0 +C 1 +D 0 +E 0 +F 3 +G 0 +H 0 +K 0 \ No newline at end of file diff --git a/CLion/ExerciseBook/06.69/06.69.c b/CLion/ExerciseBook/06.69/06.69.c new file mode 100644 index 0000000..f16b581 --- /dev/null +++ b/CLion/ExerciseBook/06.69/06.69.c @@ -0,0 +1,45 @@ +#include +#include "BiTree.h" //**▲06 树和二叉树**// + +/* + * 逆中序遍历且按层序打印树 + * i代表相对根结点走了几步,隐含了层序信息 + */ +void Algo_6_69(BiTree T, int i); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("创建二叉树(先序序列)T...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("逆中序序列且按层序打印树:\n"); + Algo_6_69(T, 0); + printf("\n"); + + return 0; +} + + +/* + * 逆中序遍历且按层序打印树 + * i代表相对根结点走了几步,隐含了层序信息 + */ +void Algo_6_69(BiTree T, int i) { + int j; + + if(T) { + Algo_6_69(T->rchild, i + 1); // 先访问右子树 + + for(j = 1; j <= 2 * i; j++) { // i乘以2是为了输出效果美观,实际空格数减半 + printf(" "); + } + printf("%c\n", T->data); + + Algo_6_69(T->lchild, i + 1); // 最后访问左子树 + } +} diff --git a/CLion/ExerciseBook/06.69/BiTree.c b/CLion/ExerciseBook/06.69/BiTree.c new file mode 100644 index 0000000..23d4976 --- /dev/null +++ b/CLion/ExerciseBook/06.69/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // 在*T不为空时进行递归清理 + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入二叉树的先序序列,如果没有子结点,使用^代替:"); + CreateTree(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // 创建左子树 + CreateTree(&((*T)->rchild), fp); // 创建右子树 + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.69/BiTree.h b/CLion/ExerciseBook/06.69/BiTree.h new file mode 100644 index 0000000..30f9027 --- /dev/null +++ b/CLion/ExerciseBook/06.69/BiTree.h @@ -0,0 +1,92 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 + + int DescNum; // 该结点的子孙数量 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 置空 + * + * 清理二叉树中的数据,使其成为空树。 + */ +Status ClearBiTree(BiTree* T); + +/* + * ████████ 算法6.4 ████████ + * + * 创建 + * + * 按照预设的定义来创建二叉树。 + * 这里约定使用【先序序列】来创建二叉树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建二叉树的内部函数 +static void CreateTree(BiTree* T, FILE* fp); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.69/CMakeLists.txt b/CLion/ExerciseBook/06.69/CMakeLists.txt new file mode 100644 index 0000000..82c6dda --- /dev/null +++ b/CLion/ExerciseBook/06.69/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.69 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.69.c) +# 链接公共库 +target_link_libraries(06.69 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.69/LinkQueue.c b/CLion/ExerciseBook/06.69/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.69/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.69/LinkQueue.h b/CLion/ExerciseBook/06.69/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.69/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.69/TestData.txt b/CLion/ExerciseBook/06.69/TestData.txt new file mode 100644 index 0000000..f728fce --- /dev/null +++ b/CLion/ExerciseBook/06.69/TestData.txt @@ -0,0 +1 @@ +先序序列→AB^D^^CE^F^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.70/06.70.c b/CLion/ExerciseBook/06.70/06.70.c new file mode 100644 index 0000000..5467751 --- /dev/null +++ b/CLion/ExerciseBook/06.70/06.70.c @@ -0,0 +1,58 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* + * 创建二叉树的二叉链表结构 + */ +Status Algo_6_70(BiTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + BiTree T; + FILE* fp; + + printf("创建二叉树T...\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_70(&T, fp); + fclose(fp); + PrintGraph(T); + + return 0; +} + + +/* + * 创建二叉树的二叉链表结构 + */ +Status Algo_6_70(BiTree* T, FILE* fp) { + char c; + + while(TRUE) { + // 字符读取完毕 + if(feof(fp)!=0) { + return OK; + } + + ReadData(fp, "%c", &c); + + if(c == '#') { + *T = NULL; + } else if(c >= 'A' && c <= 'Z') { + *T = (BiTree) malloc(sizeof(BiTNode)); //根结点 + if(*T==NULL) { + exit(OVERFLOW); + } + (*T)->data = c; + (*T)->lchild = (*T)->rchild = NULL; + } else if(c == '(') { + Algo_6_70(&(*T)->lchild, fp); + Algo_6_70(&(*T)->rchild, fp); + } else { + break; + } + } + + return OK; +} diff --git a/CLion/ExerciseBook/06.70/BiTree.c b/CLion/ExerciseBook/06.70/BiTree.c new file mode 100644 index 0000000..6dc871b --- /dev/null +++ b/CLion/ExerciseBook/06.70/BiTree.c @@ -0,0 +1,121 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // 空树深度为0 + } else { + LD = BiTreeDepth(T->lchild); // 求左子树深度 + RD = BiTreeDepth(T->rchild); // 求右子树深度 + + return (LD >= RD ? LD : RD) + 1; + } +} + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // 遇到空树则无需继续计算 + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // (完全)二叉树结构高度 + width = (int)pow(2, level)-1; // (完全)二叉树结构宽度 + + // 动态创建行 + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // 动态创建列 + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // 初始化内存值为空字符 + memset(tmp[i], '\0', width); + } + + // 借助队列实现层序遍历 + InitQueue(&Q); + EnQueue(&Q, T); + + // 遍历树中所有元素,将其安排到二维数组tmp中合适的位置 + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // 二叉树当前层的宽度 + distance = width / w; // 二叉树当前层的元素间隔 + begin = width / (int) pow(2, i + 1); // 二叉树当前层首个元素之前的空格数 + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // 左孩子入队 + EnQueue(&Q, e->lchild); + + // 右孩子入队 + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/06.70/BiTree.h b/CLion/ExerciseBook/06.70/BiTree.h new file mode 100644 index 0000000..ee19645 --- /dev/null +++ b/CLion/ExerciseBook/06.70/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * 二叉树的二叉链表存储结构 + * + * 包含算法: 6.1、6.2、6.3、6.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include // 提供 pow 原型 +#include "Status.h" //**▲01 绪论**// + +/* 二叉树元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 二叉树结点定义 */ +typedef struct BiTNode { + TElemType data; // 结点元素 + struct BiTNode* lchild; // 左孩子指针 + struct BiTNode* rchild; // 右孩子指针 +} BiTNode; + +/* 指向二叉树结点的指针 */ +typedef BiTNode* BiTree; + + +/* + * 初始化 + * + * 构造空二叉树。 + */ +Status InitBiTree(BiTree* T); + +/* + * 判空 + * + * 判断二叉树是否为空树。 + */ +Status BiTreeEmpty(BiTree T); + +/* + * 树深 + * + * 返回二叉树的深度(层数)。 + */ +int BiTreeDepth(BiTree T); + +// 以图形化形式输出当前结构,仅限内部测试使用 +void PrintGraph(BiTree T); + +#endif diff --git a/CLion/ExerciseBook/06.70/CMakeLists.txt b/CLion/ExerciseBook/06.70/CMakeLists.txt new file mode 100644 index 0000000..b52092b --- /dev/null +++ b/CLion/ExerciseBook/06.70/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.70 LinkQueue.h LinkQueue.c BiTree.h BiTree.c 06.70.c) +# 链接公共库 +target_link_libraries(06.70 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.70/LinkQueue.c b/CLion/ExerciseBook/06.70/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.70/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.70/LinkQueue.h b/CLion/ExerciseBook/06.70/LinkQueue.h new file mode 100644 index 0000000..04cc75a --- /dev/null +++ b/CLion/ExerciseBook/06.70/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "BiTree.h" //**▲06 树和二叉树**// + +/* 链队元素类型定义 */ +typedef BiTree QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.70/TestData.txt b/CLion/ExerciseBook/06.70/TestData.txt new file mode 100644 index 0000000..1c5af96 --- /dev/null +++ b/CLion/ExerciseBook/06.70/TestData.txt @@ -0,0 +1 @@ +A(B(#,D),C(E(#,F),#)) \ No newline at end of file diff --git a/CLion/ExerciseBook/06.71/06.71.c b/CLion/ExerciseBook/06.71/06.71.c new file mode 100644 index 0000000..7514773 --- /dev/null +++ b/CLion/ExerciseBook/06.71/06.71.c @@ -0,0 +1,80 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "CSTree.h" //**▲06 树和二叉树**// + +/* + * 先序遍历按凹入表打印树 + * 方法1:直接使用递归,i初始设为0 + */ +void Algo_6_71_1(CSTree T, int i); + +/* + * 先序遍历按凹入表打印树 + * 方法2:在循环中使用递归,i初始设为0 + */ +void Algo_6_71_2(CSTree T, int i); + + +int main(int argc, char* argv[]) { + CSTree T; + + printf("创建树(先序序列)T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("方法 1:先序遍历按凹入表打印树:\n"); + Algo_6_71_1(T, 0); + printf("\n"); + + printf("方法 2:先序遍历按凹入表打印树:\n"); + Algo_6_71_2(T, 0); + printf("\n"); + + return 0; +} + + +/* + * 先序遍历按凹入表打印树 + * 方法1:直接使用递归,i初始设为0 + */ +void Algo_6_71_1(CSTree T, int i) { + int j; + + if(!T) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T->data); + + Algo_6_71_1(T->firstchild, i + 1); + Algo_6_71_1(T->nextsibling, i); // 此处为i +} + +/* + * 先序遍历按凹入表打印树 + * 方法2:在循环中使用递归,i初始设为0 + */ +void Algo_6_71_2(CSTree T, int i) { + int j; + CSTree p; + + if(!T) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T->data); + + // 遍历孩子结点 + for(p = T->firstchild; p; p = p->nextsibling) { + Algo_6_71_2(p, i + 1); + } +} diff --git a/CLion/ExerciseBook/06.71/CMakeLists.txt b/CLion/ExerciseBook/06.71/CMakeLists.txt new file mode 100644 index 0000000..cff250e --- /dev/null +++ b/CLion/ExerciseBook/06.71/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.71 CSTree.h CSTree.c 06.71.c) +# 链接公共库 +target_link_libraries(06.71 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.71/CSTree.c b/CLion/ExerciseBook/06.71/CSTree.c new file mode 100644 index 0000000..318a093 --- /dev/null +++ b/CLion/ExerciseBook/06.71/CSTree.c @@ -0,0 +1,166 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#include "CSTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【先序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(CSTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入树的先序序列,如果没有孩子结点或没有兄弟节点,使用^代替:"); + Create(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CSTree T) { + int max = 0; + + Depth(T, 0, &max); + + return max; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(CSTree* T, FILE* fp) { + char ch; + + // 读取当前结点的值 + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // 生成根结点 + *T = (CSTree) malloc(sizeof(CSNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + Create(&((*T)->firstchild), fp); // 创建长子 + Create(&((*T)->nextsibling), fp); // 创建右兄弟 + } +} + +// 计算树的深度的内部实现 +static void Depth(CSTree T, int d, int* max) { + if(T == NULL) { + return; + } + + d++; // 指示当前所在的层数 + + if(d > *max) { + *max = d; + } + + Depth(T->firstchild, d, max); // 向下遍历 + Depth(T->nextsibling, --d, max); // 向右遍历 +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T) { + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // 访问当前结点 + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/CLion/ExerciseBook/06.71/CSTree.h b/CLion/ExerciseBook/06.71/CSTree.h new file mode 100644 index 0000000..45a60c2 --- /dev/null +++ b/CLion/ExerciseBook/06.71/CSTree.h @@ -0,0 +1,87 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* (孩子-兄弟)树的结点定义 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // 指向长子 + struct CSNode* nextsibling; // 指向右兄弟 +} CSNode; + +/* (孩子-兄弟)树类型定义 */ +typedef CSNode* CSTree; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T); + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(CSTree* T, char* path); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T); + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CSTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(CSTree* T, FILE* fp); + +// 计算树的深度的内部实现 +static void Depth(CSTree T, int d, int *max); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T); + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row); + +#endif diff --git a/CLion/ExerciseBook/06.71/TestData.txt b/CLion/ExerciseBook/06.71/TestData.txt new file mode 100644 index 0000000..24661d5 --- /dev/null +++ b/CLion/ExerciseBook/06.71/TestData.txt @@ -0,0 +1 @@ +ABE^F^^CG^^D^^^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.72/06.72.c b/CLion/ExerciseBook/06.72/06.72.c new file mode 100644 index 0000000..a281393 --- /dev/null +++ b/CLion/ExerciseBook/06.72/06.72.c @@ -0,0 +1,91 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "CTree.h" //**▲06 树和二叉树**// + +/* + * 先序遍历按凹入表打印树 + * 方法1:直接使用递归,i初始设为0 + */ +void Algo_6_72_1(CTree T, int order, int i); + +/* + * 先序遍历按凹入表打印树 + * 方法2:在循环中使用递归,i初始设为0 + */ +void Algo_6_72_2(CTree T, int order, int i); + + +int main(int argc, char* argv[]) { + CTree T; + + printf("创建树T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("先序遍历按凹入表打印树:\n"); + Algo_6_72_1(T, T.r, 0); + printf("\n"); + + printf("先序遍历按凹入表打印树:\n"); + Algo_6_72_2(T, T.r, 0); + printf("\n"); + + return 0; +} + + +/* + * 先序遍历按凹入表打印树 + * 方法1:直接使用递归,i初始设为0 + */ +void Algo_6_72_1(CTree T, int order, int i) { + int j, k; + + if(!T.n) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T.nodes[order].data); + + // 访问孩子结点 + if(T.nodes[order].firstchild) { + Algo_6_72_1(T, T.nodes[order].firstchild->child, i + 1); + } + + // 获取结点order的右结点的位置 + k = (order + 1) % MAX_TREE_SIZE; + + // 如果存在右兄弟 + if(T.nodes[order].parent == T.nodes[k].parent) { + // 访问右兄弟结点 + Algo_6_72_1(T, k, i); + } +} + +/* + * 先序遍历按凹入表打印树 + * 方法2:在循环中使用递归,i初始设为0 + */ +void Algo_6_72_2(CTree T, int order, int i) { + int j; + ChildPtr p; + + if(!T.n) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T.nodes[order].data); + + // 遍历孩子结点 + for(p = T.nodes[order].firstchild; p; p = p->next) { + Algo_6_72_2(T, p->child, i + 1); + } +} diff --git a/CLion/ExerciseBook/06.72/CMakeLists.txt b/CLion/ExerciseBook/06.72/CMakeLists.txt new file mode 100644 index 0000000..99c48ca --- /dev/null +++ b/CLion/ExerciseBook/06.72/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.72 LinkQueue.h LinkQueue.c CTree.h CTree.c 06.72.c) +# 链接公共库 +target_link_libraries(06.72 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.72/CTree.c b/CLion/ExerciseBook/06.72/CTree.c new file mode 100644 index 0000000..34f17d1 --- /dev/null +++ b/CLion/ExerciseBook/06.72/CTree.c @@ -0,0 +1,405 @@ +/*============================= + * 树的孩子链表(带双亲)的存储表示 + =============================*/ + +#include "CTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // 所有数据清零 + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(CTree* T, char* path) { + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入树的元素信息,对于空结点,使用^代替...\n"); + Create(T, NULL); + } else { + // 打开文件,准备读取测试数据 + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CTree T) { + int k, level; + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + return 0; + } + + /* + * 将k初始化为最后一个结点的位置 + * 由于树的结点按层序存储,故最后存储的结点必定位于最大层 + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(CTree* T, FILE* fp) { + int r; // 树的根结点的位置(索引) + int n; // 记录元素数量 + int cur; // 游标 + TElemType ch; + LinkQueue Q; + QElemType e; // 队列元素指示结点的位置 + char s[MAX_CHILD_COUNT + 1]; + int i; + ChildPtr p, pc; + + InitQueue(&Q); + + n = 0; + + // 读取根结点的位置 + if(fp == NULL) { + printf("请输入根结点的位置(0~%d):", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("请输入根结点的值:"); + scanf("%s", s); + ch = s[0]; + + // 树根入队 + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // 父结点的位置出队 + + printf("请依次输入 %c 的孩子结点,不存在孩子时输入一个^:", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // 当前结点位置入队 + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // 父结点的长子 + p = T->nodes[e].firstchild; + + // 包装当前结点 + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // 将当前结点添加到父结点的孩子链表中 + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // 找到链表尾部 + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // 录入根结点的位置 + ReadData(fp, "%d", &r); + cur = r; + + // 录入根结点的值 + ReadData(fp, "%s", s); + ch = s[0]; + printf("录入根结点的值:%c\n", ch); + + // 树根入队 + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("依次录入 %c 结点的孩子:", ch); + + // 录入孩子结点 + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // 父结点位置出队 + + // 遍历孩子 + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // 当前结点位置入队 + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // 包装当前结点 + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // 父结点的长子 + p = T->nodes[e].firstchild; + + // 将当前结点添加到父结点的孩子链表中 + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // 找到链表尾部 + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // 根结点的位置入队 + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // 父结点所在的层 + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // 如果行数发生了改变 + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // 结点e的孩子计数归0 + + // 每个结点出队时,先设置其最后一个孩子信息为无效,因为不是每个结点都有孩子结点 + pt[e].lastChild = -1; + + // 指向该结点的孩子链表 + cp = T.nodes[e].firstchild; + + // 释放该结点处的孩子链表所占内存 + while(cp != NULL) { + // 当前结点位置入队 + EnQueue(&Q, cp->child); + + // 记录行数 + pt[cp->child].row = pt[e].row + 1; + + // 记录列数 + pt[cp->child].col = ++count; + + // 记录当前结点是第几个孩子 + pt[cp->child].childIndex = ++n; + + // 为父结点跟新最后一个孩子的信息 + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // 计算T中结点的位置信息 + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("存储结构:\n"); + PrintFramework(T); +} + +// 图形化输出当前结构内部实现 +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // 初始化为无效的索引 + int rightBrother; + int k; + + // 访问当前结点 + printf("%c ", T.nodes[i].data); + + // 相比双亲表存储结构,求长子更容易了 + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // 遍历长子(需要先确定长子的身份) + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // 遍历右兄弟(需要先确定右兄弟的身份) + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // 访问当前结点的右兄弟前,如果当前结点不是最后一个孩子,则进行一次换行 + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/CLion/ExerciseBook/06.72/CTree.h b/CLion/ExerciseBook/06.72/CTree.h new file mode 100644 index 0000000..b75d508 --- /dev/null +++ b/CLion/ExerciseBook/06.72/CTree.h @@ -0,0 +1,129 @@ +/*============================= + * 树的孩子链表(带双亲)的存储表示 + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* 树的最大结点数 */ +#define MAX_TREE_SIZE 1024 + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 孩子结点定义 */ +typedef struct CTNode { + int child; // 该孩子在树中的索引 + struct CTNode* next; // 指向下一个孩子 +} CTNode; + +/* 指向孩子结点的指针 */ +typedef CTNode* ChildPtr; + +/* (双亲)树的结点定义 */ +typedef struct { + int parent; // 双亲位置域 + TElemType data; // 当前结点 + ChildPtr firstchild; // 孩子链表头指针 +} CTBox; + +/* + * (双亲)树类型定义 + * + *【注】 + * 1.树中结点在nodes中"紧邻"存储,没有空隙 + * 2.树根r可能出现在nodes的任意位置 + * 3.除根结点外,其他结点依次按层序顺着根结点往下排列(这一点与教材图示可能会有区别) + * 4.nodes数组是循环使用的(这一点教材未提到) + * 5.这里假设nodes空间是足够大的,可以视需求将其改为动态分配存储 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 存储树中结点 + int r; // 树根位置(索引) + int n; // 树的结点数 +} CTree; + + +/* + * 树中某个结点的信息 + * + * 注:相比双亲表存储结构,不需要再寄来当前结点的第一个孩子在树中的索引 + * */ +typedef struct{ + int row; // 当前结点所处的行 + int col; // 当前结点所处的列 + int childIndex; // 当前结点是第几个孩子 + int lastChild; // 当前结点的最后一个孩子在树中的索引 +} Pos; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CTree* T); + +/* + * 创建 + * + * 按照预设的定义来创建树。 + * 这里约定使用【层序序列】来创建树。 + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateTree(CTree* T, char* path); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CTree T); + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 创建树的内部函数 +static void Create(CTree* T, FILE* fp); + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos(CTree T, Pos pt[]); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CTree T); + +// 图形化输出当前结构内部实现 +static void Print(CTree T, Pos pt[], int i); + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework(CTree T); + +#endif diff --git a/CLion/ExerciseBook/06.72/LinkQueue.c b/CLion/ExerciseBook/06.72/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.72/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.72/LinkQueue.h b/CLion/ExerciseBook/06.72/LinkQueue.h new file mode 100644 index 0000000..ec9c0e1 --- /dev/null +++ b/CLion/ExerciseBook/06.72/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// + +/* 链队元素类型定义 */ +typedef int QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.72/TestData.txt b/CLion/ExerciseBook/06.72/TestData.txt new file mode 100644 index 0000000..c9151fa --- /dev/null +++ b/CLion/ExerciseBook/06.72/TestData.txt @@ -0,0 +1,9 @@ +根结点位置:5 +根结点的值:A +A的孩子结点:BCD +B的孩子结点:EF +C的孩子结点:G +D的孩子结点:^ +E的孩子结点:^ +F的孩子结点:^ +G的孩子结点:^ \ No newline at end of file diff --git a/CLion/ExerciseBook/06.73-06.74/06.73-06.74.c b/CLion/ExerciseBook/06.73-06.74/06.73-06.74.c new file mode 100644 index 0000000..23a3403 --- /dev/null +++ b/CLion/ExerciseBook/06.73-06.74/06.73-06.74.c @@ -0,0 +1,97 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "CSTree.h" //**▲06 树和二叉树**// + +/* + * 创建孩子-兄弟链表 + */ +Status Algo_6_73(CSTree* T, FILE* fp); + +/* + * 按广义表方式打印孩子-兄弟链表 + */ +void Algo_6_74(CSTree T); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf("███ 题 6.73 验证... ███\n"); + printf("创建孩子-兄弟二叉树:\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_73(&T, fp); + fclose(fp); + PrintGraph(T); + printf("\n"); + + printf("███ 题 6.74 验证... ███\n"); + printf("按广义表打印孩子-兄弟链表...\n"); + Algo_6_74(T); + printf("\n"); + + return 0; +} + + +/* + * 创建孩子-兄弟链表 + */ +Status Algo_6_73(CSTree* T, FILE* fp) { + char c; + + while(TRUE) { + if(feof(fp) != 0) { + break; + } + + ReadData(fp, "%c", &c); + + if(c >= 'A' && c <= 'Z') { + *T = (CSTree) malloc(sizeof(CSNode)); //根结点 + if(*T == NULL) { + exit(OVERFLOW); + } + (*T)->data = c; + (*T)->firstchild = (*T)->nextsibling = NULL; + } else if(c == '(') { + Algo_6_73(&(*T)->firstchild, fp); + } else if(c == ',') { + Algo_6_73(&(*T)->nextsibling, fp); + break; // 注意此处应该返回 + } else { + break; + } + } + + return OK; +} + +/* + * 按广义表方式打印孩子-兄弟链表 + */ +void Algo_6_74(CSTree T) { + CSTree p; + + if(!T) { + return; + } + + printf("%c", T->data); + + if(T->firstchild) { + printf("("); + + for(p = T->firstchild; p; p = p->nextsibling) { + Algo_6_74(p); + + // 若不是最后一个兄弟,加"," + if(p->nextsibling) { + printf(","); + } + } + + printf(")"); + } +} diff --git a/CLion/ExerciseBook/06.73-06.74/CMakeLists.txt b/CLion/ExerciseBook/06.73-06.74/CMakeLists.txt new file mode 100644 index 0000000..7a74533 --- /dev/null +++ b/CLion/ExerciseBook/06.73-06.74/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.73-06.74 CSTree.h CSTree.c 06.73-06.74.c) +# 链接公共库 +target_link_libraries(06.73-06.74 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.73-06.74/CSTree.c b/CLion/ExerciseBook/06.73-06.74/CSTree.c new file mode 100644 index 0000000..37a4c27 --- /dev/null +++ b/CLion/ExerciseBook/06.73-06.74/CSTree.c @@ -0,0 +1,67 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#include "CSTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T) { + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // 访问当前结点 + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/CLion/ExerciseBook/06.73-06.74/CSTree.h b/CLion/ExerciseBook/06.73-06.74/CSTree.h new file mode 100644 index 0000000..ac663b1 --- /dev/null +++ b/CLion/ExerciseBook/06.73-06.74/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * 树的二叉链表(孩子-兄弟)结构存储表示 + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* (孩子-兄弟)树的结点定义 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // 指向长子 + struct CSNode* nextsibling; // 指向右兄弟 +} CSNode; + +/* (孩子-兄弟)树类型定义 */ +typedef CSNode* CSTree; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CSTree* T); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CSTree T); + +// 以图形化形式输出当前结构 +void PrintGraph(CSTree T); + +// 图形化输出当前结构内部实现 +static void Print(CSTree T, int row); + +#endif diff --git a/CLion/ExerciseBook/06.73-06.74/TestData.txt b/CLion/ExerciseBook/06.73-06.74/TestData.txt new file mode 100644 index 0000000..6502a45 --- /dev/null +++ b/CLion/ExerciseBook/06.73-06.74/TestData.txt @@ -0,0 +1 @@ +A(B(E,F),C(G),D) \ No newline at end of file diff --git a/CLion/ExerciseBook/06.75-06.76/06.75-06.76.c b/CLion/ExerciseBook/06.75-06.76/06.75-06.76.c new file mode 100644 index 0000000..79b8d11 --- /dev/null +++ b/CLion/ExerciseBook/06.75-06.76/06.75-06.76.c @@ -0,0 +1,167 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "CTree.h" //**▲06 树和二叉树**// + +/* + * 创建孩子链表(已考虑双亲结点) + */ +void Algo_6_75(CTree* T, FILE* fp); + +// 创建树的内部实现,parent标记当前位置结点的双亲结点位置 +void Create(CTree* T, int parent, FILE* fp); + +/* + * 按广义表方式打印孩子链表 + */ +void Algo_6_76(CTree T, int i); + + +int main(int argc, char* argv[]) { + FILE* fp; + CTree T; + + printf("题 6.75 验证...\n"); + printf("创建孩子链表形式的树:\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_75(&T, fp); + fclose(fp); + PrintGraph(T); + printf("\n"); + + printf("题 6.76 验证...\n"); + printf("按广义表方式打印孩子链表...\n"); + Algo_6_76(T, T.r); + printf("\n"); + + return 0; +} + + +/* + * 创建孩子链表(已考虑双亲结点) + */ +void Algo_6_75(CTree* T, FILE* fp) { + CTree CT; + ChildPtr r; + int mark[MAX_TREE_SIZE]; + int i, j, p; + + CT.r = 0; // 将根结点默认设置到0号单元处 + CT.n = 0; // 从0号单元开始存储 + Create(&CT, -1, fp); // 此处创建出的树,其结点排列是先序的 + + T->n = CT.n; + T->r = 0; + j = T->r; + + // 调整结点顺序为层序 + for(p = -1; p < CT.n; p++) { + // 选出父结点为p的元素 + for(i = 0; i < CT.n; i++) { + if(CT.nodes[i].parent == p) { + T->nodes[j] = CT.nodes[i]; + mark[i] = j; // 下标为i的元素移动到了新数组的下标j处 + j++; + } + } + } + + // 下标更正 + for(i = 0; i < T->n; i++) { + p = T->nodes[i].parent; + if(p != -1) { + // 修改parent域的下标 + T->nodes[i].parent = mark[p]; + } + + // 修改孩子链表中的元素下标 + for(r = T->nodes[i].firstchild; r != NULL; r = r->next) { + r->child = mark[r->child]; + } + } +} + +// 创建树的内部实现,parent标记当前位置结点的双亲结点位置 +void Create(CTree* T, int parent, FILE* fp) { + char c; + ChildPtr p, q; + + while(TRUE) { + if(feof(fp) != 0) { + break; + } + + ReadData(fp, "%c", &c); + + if(c >= 'A' && c <= 'Z') { + T->nodes[T->n].data = c; // T.n用来追踪结点个数 + T->nodes[T->n].parent = parent; + T->nodes[T->n].firstchild = NULL; + + // 非根结点 + if(parent != -1) { + // 创建孩子结点 + p = (ChildPtr) malloc(sizeof(CTNode)); + p->child = T->n; + p->next = NULL; + + // 获取当前孩子结点的父结点的孩子链表 + q = T->nodes[parent].firstchild; + + // 父结点的孩子链表为空 + if(q == NULL) { + T->nodes[parent].firstchild = p; + } else { + // 查找父结点孩子链表的尾部 + while(q->next != NULL) { + q = q->next; + } + + // 向父结点的孩子链表插入该孩子结点 + q->next = p; + } + } + + T->n++; + } else if(c == '(') { + Create(T, T->n - 1, fp); // T.n-1结点的第一个孩子 + + } else if(c == ',') { + Create(T, parent, fp); // 创建兄弟结点 + break; + } else { + break; + } + } +} + +/* + * 按广义表方式打印孩子链表 + */ +void Algo_6_76(CTree T, int i) { + ChildPtr p; + + if(!T.n) { + return; + } + + // 打印双亲结点 + printf("%c", T.nodes[i].data); + + if(T.nodes[i].firstchild) { + printf("("); + + // 遍历孩子结点 + for(p = T.nodes[i].firstchild; p; p = p->next) { + Algo_6_76(T, p->child); + + // 存在下一个孩子 + if(p->next != NULL) { + printf(","); + } + } + + printf(")"); + } +} diff --git a/CLion/ExerciseBook/06.75-06.76/CMakeLists.txt b/CLion/ExerciseBook/06.75-06.76/CMakeLists.txt new file mode 100644 index 0000000..88c289c --- /dev/null +++ b/CLion/ExerciseBook/06.75-06.76/CMakeLists.txt @@ -0,0 +1,12 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(06.75-06.76 LinkQueue.h LinkQueue.c CTree.h CTree.c 06.75-06.76.c) +# 链接公共库 +target_link_libraries(06.75-06.76 Scanf_lib) + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/06.75-06.76/CTree.c b/CLion/ExerciseBook/06.75-06.76/CTree.c new file mode 100644 index 0000000..b97fa74 --- /dev/null +++ b/CLion/ExerciseBook/06.75-06.76/CTree.c @@ -0,0 +1,223 @@ +/*============================= + * 树的孩子链表(带双亲)的存储表示 + =============================*/ + +#include "CTree.h" + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // 所有数据清零 + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CTree T) { + int k, level; + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + return 0; + } + + /* + * 将k初始化为最后一个结点的位置 + * 由于树的结点按层序存储,故最后存储的结点必定位于最大层 + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // 根结点的位置入队 + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // 父结点所在的层 + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // 如果行数发生了改变 + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // 结点e的孩子计数归0 + + // 每个结点出队时,先设置其最后一个孩子信息为无效,因为不是每个结点都有孩子结点 + pt[e].lastChild = -1; + + // 指向该结点的孩子链表 + cp = T.nodes[e].firstchild; + + // 释放该结点处的孩子链表所占内存 + while(cp != NULL) { + // 当前结点位置入队 + EnQueue(&Q, cp->child); + + // 记录行数 + pt[cp->child].row = pt[e].row + 1; + + // 记录列数 + pt[cp->child].col = ++count; + + // 记录当前结点是第几个孩子 + pt[cp->child].childIndex = ++n; + + // 为父结点跟新最后一个孩子的信息 + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // 遇到空树则无需继续计算 + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // 计算T中结点的位置信息 + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("存储结构:\n"); + PrintFramework(T); +} + +// 图形化输出当前结构内部实现 +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // 初始化为无效的索引 + int rightBrother; + int k; + + // 访问当前结点 + printf("%c ", T.nodes[i].data); + + // 相比双亲表存储结构,求长子更容易了 + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // 遍历长子(需要先确定长子的身份) + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // 遍历右兄弟(需要先确定右兄弟的身份) + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // 访问当前结点的右兄弟前,如果当前结点不是最后一个孩子,则进行一次换行 + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/CLion/ExerciseBook/06.75-06.76/CTree.h b/CLion/ExerciseBook/06.75-06.76/CTree.h new file mode 100644 index 0000000..b72ab56 --- /dev/null +++ b/CLion/ExerciseBook/06.75-06.76/CTree.h @@ -0,0 +1,108 @@ +/*============================= + * 树的孩子链表(带双亲)的存储表示 + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // 提供 malloc、free 原型 +#include // 提供 memset、strcmp 原型 +#include "Status.h" //**▲01 绪论**// +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* 树的最大结点数 */ +#define MAX_TREE_SIZE 1024 + +/* 单个结点最大的孩子数量 */ +#define MAX_CHILD_COUNT 8 + +/* 树的元素类型定义,这里假设其元素类型为char */ +typedef char TElemType; + +/* 孩子结点定义 */ +typedef struct CTNode { + int child; // 该孩子在树中的索引 + struct CTNode* next; // 指向下一个孩子 +} CTNode; + +/* 指向孩子结点的指针 */ +typedef CTNode* ChildPtr; + +/* (双亲)树的结点定义 */ +typedef struct { + int parent; // 双亲位置域 + TElemType data; // 当前结点 + ChildPtr firstchild; // 孩子链表头指针 +} CTBox; + +/* + * (双亲)树类型定义 + * + *【注】 + * 1.树中结点在nodes中"紧邻"存储,没有空隙 + * 2.树根r可能出现在nodes的任意位置 + * 3.除根结点外,其他结点依次按层序顺着根结点往下排列(这一点与教材图示可能会有区别) + * 4.nodes数组是循环使用的(这一点教材未提到) + * 5.这里假设nodes空间是足够大的,可以视需求将其改为动态分配存储 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 存储树中结点 + int r; // 树根位置(索引) + int n; // 树的结点数 +} CTree; + + +/* + * 树中某个结点的信息 + * + * 注:相比双亲表存储结构,不需要再寄来当前结点的第一个孩子在树中的索引 + * */ +typedef struct{ + int row; // 当前结点所处的行 + int col; // 当前结点所处的列 + int childIndex; // 当前结点是第几个孩子 + int lastChild; // 当前结点的最后一个孩子在树中的索引 +} Pos; + + +/* + * 初始化 + * + * 构造空树。 + */ +Status InitTree(CTree* T); + +/* + * 判空 + * + * 判断树是否为空树。 + */ +Status TreeEmpty(CTree T); + +/* + * 树深 + * + * 返回树的深度(层数)。 + */ +int TreeDepth(CTree T); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 仅限内部使用的函数 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 获取树T的结点信息,具体包含哪些信息,请参照Pos类型的定义 +static void getPos(CTree T, Pos pt[]); + + +/*━━━━━━━━━━━━━━━━━━━━━━ 图形化输出 ━━━━━━━━━━━━━━━━━━━━━━*/ + +// 以图形化形式输出当前结构 +void PrintGraph(CTree T); + +// 图形化输出当前结构内部实现 +static void Print(CTree T, Pos pt[], int i); + +// 图形化输出树的排列结构,仅限内部测试使用 +static void PrintFramework(CTree T); + +#endif diff --git a/CLion/ExerciseBook/06.75-06.76/LinkQueue.c b/CLion/ExerciseBook/06.75-06.76/LinkQueue.c new file mode 100644 index 0000000..d4e8d40 --- /dev/null +++ b/CLion/ExerciseBook/06.75-06.76/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/CLion/ExerciseBook/06.75-06.76/LinkQueue.h b/CLion/ExerciseBook/06.75-06.76/LinkQueue.h new file mode 100644 index 0000000..ec9c0e1 --- /dev/null +++ b/CLion/ExerciseBook/06.75-06.76/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * 队列的链式存储结构(链队) + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// + +/* 链队元素类型定义 */ +typedef int QElemType; + +// 队列元素结构 +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// 队列结构 +typedef struct { + QueuePtr front; // 队头指针 + QueuePtr rear; // 队尾指针 +} LinkQueue; // 队列的链式存储表示 + + +/* + * 初始化 + * + * 构造一个空的链队。 + * 初始化成功则返回OK,否则返回ERROR。 + * + *【注】 + * 这里的队列带有头结点 + */ +Status InitQueue(LinkQueue* Q); + +/* + * 判空 + * + * 判断链队中是否包含有效数据。 + * + * 返回值: + * TRUE : 链队为空 + * FALSE: 链队不为空 + */ +Status QueueEmpty(LinkQueue Q); + +/* + * 入队 + * + * 将元素e添加到队列尾部。 + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * 出队 + * + * 移除队列头部的元素,将其存储到e中。 + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/CLion/ExerciseBook/06.75-06.76/TestData.txt b/CLion/ExerciseBook/06.75-06.76/TestData.txt new file mode 100644 index 0000000..6502a45 --- /dev/null +++ b/CLion/ExerciseBook/06.75-06.76/TestData.txt @@ -0,0 +1 @@ +A(B(E,F),C(G),D) \ No newline at end of file diff --git a/CLion/ExerciseBook/CMakeLists.txt b/CLion/ExerciseBook/CMakeLists.txt index ffd1980..83092aa 100644 --- a/CLion/ExerciseBook/CMakeLists.txt +++ b/CLion/ExerciseBook/CMakeLists.txt @@ -94,3 +94,31 @@ add_subdirectory(05.37.1) add_subdirectory(05.37.2) add_subdirectory(05.38.1) add_subdirectory(05.38.2) + +add_subdirectory(06.33-06.34) +add_subdirectory(06.35) +add_subdirectory(06.36) +add_subdirectory(06.37-06.38) +add_subdirectory(06.39) +add_subdirectory(06.40) +add_subdirectory(06.41-06.49) +add_subdirectory(06.50) +add_subdirectory(06.51) +add_subdirectory(06.52) +add_subdirectory(06.53) +add_subdirectory(06.54) +add_subdirectory(06.55) +add_subdirectory(06.56-06.58) +add_subdirectory(06.59-06.62) +add_subdirectory(06.63) +add_subdirectory(06.64) +add_subdirectory(06.65) +add_subdirectory(06.66) +add_subdirectory(06.67) +add_subdirectory(06.68) +add_subdirectory(06.69) +add_subdirectory(06.70) +add_subdirectory(06.71) +add_subdirectory(06.72) +add_subdirectory(06.73-06.74) +add_subdirectory(06.75-06.76) diff --git a/Dev-C++/ExerciseBook/06.33-06.34/06.33-06.34.cpp b/Dev-C++/ExerciseBook/06.33-06.34/06.33-06.34.cpp new file mode 100644 index 0000000..f4937a2 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.33-06.34/06.33-06.34.cpp @@ -0,0 +1,102 @@ +#include +#include "Status.h" //**01 **// + +/* Ԫ */ +#define MAX 100 + +/* + * /ҺбжuǷΪv + */ +Status Algo_6_33(int L[MAX + 1], int R[MAX + 1], int u, int v); + +/* + * ˫׽бжuǷΪv + */ +Status Algo_6_34(int T[MAX + 1], int u, int v); + + +int main(int argc, char* argv[]) { + int T[MAX + 1] = {0, 0, 1, 1, 2, 2, 3, 5, 5, 6}; // 0ŵԪ + int L[MAX + 1] = {0, 2, 4, 6, 0, 7, 0, 0, 0, 0}; + int R[MAX + 1] = {0, 3, 5, 0, 0, 8, 9, 0, 0, 0}; + int u, v; + + printf("Ϊʾµ\n"); + printf(" 1 2 3 4 5 6 7 8 9\n"); // + printf("T[n] 0 1 1 2 2 3 5 5 6\n"); // ˫׽б + printf("L[n] 2 4 6 0 7 0 0 0 0\n"); // б + printf("R[n] 3 5 0 0 8 9 0 0 0\n"); // Һб + printf("\n"); + + printf("Ҫ֤P...\n\n"); + + printf("(1~9) u = "); + scanf("%d", &u); + printf("(1~9) v = "); + scanf("%d", &v); + printf("\n"); + + printf(" 6.33 ֤...\n"); + { + if(Algo_6_33(L, R, u, v) == TRUE) { + printf("u=%d v=%d \n", u, v); + } else { + printf("u=%d v=%d \n", u, v); + } + + printf("\n"); + } + + + printf(" 6.34 ֤...\n"); + { + if(Algo_6_34(T, u, v) == TRUE) { + printf("u=%d v=%d \n", u, v); + } else { + printf("u=%d v=%d \n", u, v); + } + + printf("\n"); + } + + return 0; +} + + +/* + * /ҺбжuǷΪv + */ +Status Algo_6_33(int L[MAX + 1], int R[MAX + 1], int u, int v) { + // uvĺ + if(L[v] == u || R[v] == u) { + return TRUE; + } else { + // ӣ + if(L[v]!=0 && Algo_6_33(L, R, u, L[v])==TRUE) { + return TRUE; + } + + // Һӣ + if(R[v]!=0 && Algo_6_33(L, R, u, R[v])==TRUE) { + return TRUE; + } + } + + return FALSE; +} + +/* + * ˫׽бжuǷΪv + */ +Status Algo_6_34(int T[MAX + 1], int u, int v) { + // u˫v + if(T[u] == v) { + return TRUE; + } else { + if(T[u] != 0 && Algo_6_34(T, T[u], v) == TRUE) { + return TRUE; + } + } + + return FALSE; +} diff --git a/Dev-C++/ExerciseBook/06.33-06.34/06.33-06.34.dev b/Dev-C++/ExerciseBook/06.33-06.34/06.33-06.34.dev new file mode 100644 index 0000000..551b6aa --- /dev/null +++ b/Dev-C++/ExerciseBook/06.33-06.34/06.33-06.34.dev @@ -0,0 +1,62 @@ +[Project] +FileName=06.33-06.34.dev +Name=06.33-06.34 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=1 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=06.33-06.34.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.35/06.35.cpp b/Dev-C++/ExerciseBook/06.35/06.35.cpp new file mode 100644 index 0000000..32927aa --- /dev/null +++ b/Dev-C++/ExerciseBook/06.35/06.35.cpp @@ -0,0 +1,45 @@ +#include + +/* */ +#define N 15 + +/* + * ֵ + */ +int Algo_6_35(char* BiTree, int i); + + +int main(int argc, char* argv[]) { + // ˳洢Ķ(0ŵԪʼ洢) + char BiTree[N] = {'A', 'B', 'C', 'D', 'E', 'F', '\0', 'G', '\0', 'H', 'I', '\0', 'J', '\0', '\0'}; + int i, j; + + printf("Ϊʾ˳洢ṹ^ַ˴ûнϢABCDEF^G^HI^J^^"); + printf("\n"); + + printf("(0~%d)", N); + scanf("%d", &i); + printf("\n"); + + j = Algo_6_35(BiTree, i); + + if(j != -1) { + printf(" %d ӦʮΪ %d \n", i, j); + } else { + printf("˴㲻ڣ\n"); + } + + return 0; +} + + +/* + * ֵ + */ +int Algo_6_35(char* BiTree, int i) { + if(BiTree[i] == '\0') { + return -1; // ˴ڽ + } + + return i + 1; +} diff --git a/Dev-C++/ExerciseBook/06.35/06.35.dev b/Dev-C++/ExerciseBook/06.35/06.35.dev new file mode 100644 index 0000000..fc77a70 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.35/06.35.dev @@ -0,0 +1,62 @@ +[Project] +FileName=06.35.dev +Name=06.35 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=1 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=06.35.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.36/06.36.cpp b/Dev-C++/ExerciseBook/06.36/06.36.cpp new file mode 100644 index 0000000..f817b66 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/06.36.cpp @@ -0,0 +1,63 @@ +#include +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* + * жöǷ + */ +Status Algo_6_36(BiTree B1, BiTree B2); + + +int main(int argc, char* argv[]) { + BiTree B1, B2, B3; + + printf(" B1 ...\n"); + CreateBiTree(&B1, "TestData_B1.txt"); + PrintGraph(B1); + printf("\n"); + + printf(" B2 ...\n"); + CreateBiTree(&B2, "TestData_B2.txt"); + PrintGraph(B2); + printf("\n"); + + printf(" B3 ...\n"); + CreateBiTree(&B3, "TestData_B3.txt"); + PrintGraph(B3); + printf("\n"); + + if(Algo_6_36(B1, B2) == TRUE) { + printf("B1B2ƣ\n"); + } else { + printf("B1B2ƣ\n"); + } + + if(Algo_6_36(B2, B3) == TRUE) { + printf("B2B3ƣ\n"); + } else { + printf("B2B3ƣ\n"); + } + + return 0; +} + + +/* + * жöǷ + */ +Status Algo_6_36(BiTree B1, BiTree B2) { + // Ϊ + if(BiTreeEmpty(B1) && BiTreeEmpty(B2)) { + return TRUE; + } else { + // Ϊ + if(!BiTreeEmpty(B1) && !BiTreeEmpty(B2)) { + // ж + if(Algo_6_36(B1->lchild, B2->lchild) && Algo_6_36(B1->rchild, B2->rchild)) { + return TRUE; + } + } + } + + return FALSE; +} diff --git a/Dev-C++/ExerciseBook/06.36/06.36.dev b/Dev-C++/ExerciseBook/06.36/06.36.dev new file mode 100644 index 0000000..61edbec --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/06.36.dev @@ -0,0 +1,129 @@ +[Project] +FileName=06.36.dev +Name=06.36 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=8 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.36.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData_B1.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=TestData_B2.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=TestData_B3.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.36/BiTree.cpp b/Dev-C++/ExerciseBook/06.36/BiTree.cpp new file mode 100644 index 0000000..97a2156 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/BiTree.cpp @@ -0,0 +1,178 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.36/BiTree.h b/Dev-C++/ExerciseBook/06.36/BiTree.h new file mode 100644 index 0000000..f4d29c5 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/BiTree.h @@ -0,0 +1,76 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.36/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.36/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.36/LinkQueue.h b/Dev-C++/ExerciseBook/06.36/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.36/TestData_B1.txt b/Dev-C++/ExerciseBook/06.36/TestData_B1.txt new file mode 100644 index 0000000..3171ed9 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/TestData_B1.txt @@ -0,0 +1 @@ +СABD^^E^^C^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.36/TestData_B2.txt b/Dev-C++/ExerciseBook/06.36/TestData_B2.txt new file mode 100644 index 0000000..3c311a7 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/TestData_B2.txt @@ -0,0 +1 @@ +СFGH^^I^^J^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.36/TestData_B3.txt b/Dev-C++/ExerciseBook/06.36/TestData_B3.txt new file mode 100644 index 0000000..a89ca54 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.36/TestData_B3.txt @@ -0,0 +1 @@ +СKLM^^N^^OP^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.37-06.38/06.37-06.38.cpp b/Dev-C++/ExerciseBook/06.37-06.38/06.37-06.38.cpp new file mode 100644 index 0000000..e19a4da --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/06.37-06.38.cpp @@ -0,0 +1,133 @@ +#include +#include "Status.h" //**01 **// +#include "SqStack.h" //**03 ջͶ**// +#include "BiTree.h" //**06 Ͷ**// + +/* + * ķǵݹʽ + */ +Status Algo_6_37(BiTree T); + +/* + * ķǵݹʽ + */ +Status Algo_6_38(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf(" T ...\n"); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf(" 6.37 ֤...\n"); + { + printf("Ϊ"); + Algo_6_37(T); + printf("\n"); + } + + printf(" 6.38 ֤...\n"); + { + printf("Ϊ"); + Algo_6_38(T); + printf("\n"); + } + + return 0; +} + + +/* + * ķǵݹʽ + */ +Status Algo_6_37(BiTree T) { + SqStack S; + SElemType e; + + if(BiTreeEmpty(T)) { + printf("\n"); + return ERROR; + } + + InitStack(&S); + Push(&S, T); + + while(!StackEmpty(S)) { + GetTop(S, &e); + printf("%c ", e->data); + + if(e->lchild) { + Push(&S, e->lchild); + } else { + while(!StackEmpty(S)) { + Pop(&S, &e); + + if(e->rchild) { + Push(&S, e->rchild); + break; + } + } + } + } + + printf("\n"); + return OK; +} + +/* + * ķǵݹʽ + */ +Status Algo_6_38(BiTree T) { + SqStack S; + BiTree p; + SElemType e; + int StackMark[100] = {0}; // ջøʱǣʼΪ0 + int k; + + if(BiTreeEmpty(T)) { + printf("\n"); + return ERROR; + } + + InitStack(&S); + p = T; + k = -1; + + while(TRUE) { + while(p) { + Push(&S, p); + k++; + StackMark[k] = 1; // õһηʵı + p = p->lchild; + } + + // pΪյջΪ + while(!p && !StackEmpty(S)) { + GetTop(S, &p); + + // ѷʹһΣǰǵڶη + if(StackMark[k] == 1) { + StackMark[k] = 2; + p = p->rchild; + + // ѷʹΣǰǵη + } else { + printf("%c ", p->data); + Pop(&S, &e); + StackMark[k] = 0; + k--; + p = NULL; + } + } + + if(StackEmpty(S)) { + break; + } + } + + printf("\n"); + return OK; +} diff --git a/Dev-C++/ExerciseBook/06.37-06.38/06.37-06.38.dev b/Dev-C++/ExerciseBook/06.37-06.38/06.37-06.38.dev new file mode 100644 index 0000000..c8fd408 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/06.37-06.38.dev @@ -0,0 +1,131 @@ +[Project] +FileName=06.37-06.38.dev +Name=06.37-06.38 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=8 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit6] +FileName=SqStack.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.37-06.38.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=SqStack.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.37-06.38/BiTree.cpp b/Dev-C++/ExerciseBook/06.37-06.38/BiTree.cpp new file mode 100644 index 0000000..97a2156 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/BiTree.cpp @@ -0,0 +1,178 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.37-06.38/BiTree.h b/Dev-C++/ExerciseBook/06.37-06.38/BiTree.h new file mode 100644 index 0000000..f4d29c5 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/BiTree.h @@ -0,0 +1,76 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.37-06.38/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.37-06.38/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.37-06.38/LinkQueue.h b/Dev-C++/ExerciseBook/06.37-06.38/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.37-06.38/SqStack.cpp b/Dev-C++/ExerciseBook/06.37-06.38/SqStack.cpp new file mode 100644 index 0000000..f0b3b3d --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/SqStack.cpp @@ -0,0 +1,106 @@ +/*========================= + * ջ˳洢ṹ˳ջ + ==========================*/ + +#include "SqStack.h" //**03 ջͶ**// + +/* + * ʼ + * + * һջʼɹ򷵻OK򷵻ERROR + */ +Status InitStack(SqStack* S) { + if(S == NULL) { + return ERROR; + } + + (*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); + } + + (*S).top = (*S).base; + (*S).stacksize = STACK_INIT_SIZE; + + return OK; +} + +/* + * п + * + * ж˳ջǷЧݡ + * + * ֵ + * TRUE : ˳ջΪ + * FALSE: ˳ջΪ + */ +Status StackEmpty(SqStack S) { + if(S.top == S.base) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * ȡֵ + * + * ջԪأeա + */ +Status GetTop(SqStack S, SElemType* e) { + if(S.base == NULL || S.top == S.base) { + return 0; + } + + // ıջԪ + *e = *(S.top - 1); + + return OK; +} + +/* + * ջ + * + * Ԫeѹ뵽ջ + */ +Status Push(SqStack* S, SElemType e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + // ջʱ׷Ӵ洢ռ + if((*S).top - (*S).base >= (*S).stacksize) { + (*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); // 洢ʧ + } + + (*S).top = (*S).base + (*S).stacksize; + (*S).stacksize += STACKINCREMENT; + } + + // ջȸֵջָ + *(S->top++) = e; + + return OK; +} + +/* + * ջ + * + * ջԪصeա + */ +Status Pop(SqStack* S, SElemType* e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + if((*S).top == (*S).base) { + return ERROR; + } + + // ջջָȵݼٸֵ + *e = *(--(*S).top); + + return OK; +} diff --git a/Dev-C++/ExerciseBook/06.37-06.38/SqStack.h b/Dev-C++/ExerciseBook/06.37-06.38/SqStack.h new file mode 100644 index 0000000..86c1fcc --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/SqStack.h @@ -0,0 +1,67 @@ +/*========================= + * ջ˳洢ṹ˳ջ + ==========================*/ + +#ifndef SQSTACK_H +#define SQSTACK_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* 궨 */ +#define STACK_INIT_SIZE 100 // ˳ջ洢ռijʼ +#define STACKINCREMENT 10 // ˳ջ洢ռķ + +/* ˳ջԪͶ */ +typedef BiTree SElemType; + +// ˳ջԪؽṹ +typedef struct { + SElemType* base; // ջָ + SElemType* top; // ջָ + int stacksize; // ǰѷĴ洢ռ䣬ԪΪλ +} SqStack; + + +/* + * ʼ + * + * һջʼɹ򷵻OK򷵻ERROR + */ +Status InitStack(SqStack* S); + +/* + * п + * + * ж˳ջǷЧݡ + * + * ֵ + * TRUE : ˳ջΪ + * FALSE: ˳ջΪ + */ +Status StackEmpty(SqStack S); + +/* + * ȡֵ + * + * ջԪأeա + */ +Status GetTop(SqStack S, SElemType* e); + +/* + * ջ + * + * Ԫeѹ뵽ջ + */ +Status Push(SqStack* S, SElemType e); + +/* + * ջ + * + * ջԪصeա + */ +Status Pop(SqStack* S, SElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.37-06.38/TestData.txt b/Dev-C++/ExerciseBook/06.37-06.38/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.37-06.38/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.39/06.39.cpp b/Dev-C++/ExerciseBook/06.39/06.39.cpp new file mode 100644 index 0000000..d90804f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.39/06.39.cpp @@ -0,0 +1,153 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͣΪַ */ +typedef char TElemType; + +/* Ľ㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ + struct BiTNode* parent; + int mark; +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + +/* + * ĵʽ + */ +void Algo_6_39(BiTree T); + +// () +Status CreateBiTree(BiTree* T, char* path); + +// ڲʵ֣p׷ +void CreateTree(BiTree* T, BiTree p, FILE* fp); + +// ͼλʽǰ +void PrintGraph(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf(" T ...\n"); + CreateBiTree(&T, NULL); + PrintGraph(T); + + printf("Ϊ"); + Algo_6_39(T); + + return 0; +} + + +/* + * ĵʽ + */ +void Algo_6_39(BiTree T) { + BiTree p = T; + + while(p != NULL) { + // mark==0δʣ + if(p->mark == 0) { + p->mark = 1; + if(p->lchild != NULL) { + p = p->lchild; + } + + // mark==1ѷʣҷ + } else if(p->mark == 1) { + p->mark = 2; + if(p->rchild != NULL) { + p = p->rchild; + } + + // mark==2Ҷˣӡ + } else { + printf("%c ", p->data); + p->mark = 0; // + p = p->parent; + } + } + + printf("\n"); +} + +// () +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + + fp = fopen("TestData.txt", "r"); + CreateTree(T, NULL, fp); + fclose(fp); + + return OK; +} + +// ڲʵ֣p׷ +void CreateTree(BiTree* T, BiTree p, FILE* fp) { + char ch; + + ReadData(fp, "%c", &ch); + + if(ch == '^') { + *T = NULL; + } else { + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + (*T)->parent = p; + (*T)->mark = 0; + CreateTree(&(*T)->lchild, *T, fp); + CreateTree(&(*T)->rchild, *T, fp); + } +} + +// ͼλʽǰ +void PrintGraph(BiTree T) { + BiTree p = T; + int i = 1; + + while(p != NULL) { + // mark==0δʣ + if(p->mark == 0) { + printf("%c ", p->data); + i++; + p->mark = 1; + if(p->lchild != NULL) { + p = p->lchild; + } else { + printf("^\n"); + i--; + } + + // mark==1ѷʣҷ + } else if(p->mark == 1) { + p->mark = 2; + i++; + + if(p->rchild != NULL) { + printf("%*c", 2 * (i - 1), ' '); + p = p->rchild; + } else { + printf("%*c^\n", 2 * (i - 1), ' '); + i--; + } + + // mark==2Ҷˣӡ + } else { + p->mark = 0; // + p = p->parent; + i--; + } + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/06.39/06.39.dev b/Dev-C++/ExerciseBook/06.39/06.39.dev new file mode 100644 index 0000000..1e6e036 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.39/06.39.dev @@ -0,0 +1,71 @@ +[Project] +FileName=06.39.dev +Name=06.39 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=2 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=06.39.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.39/TestData.txt b/Dev-C++/ExerciseBook/06.39/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.39/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.40/06.40.cpp b/Dev-C++/ExerciseBook/06.40/06.40.cpp new file mode 100644 index 0000000..29642fd --- /dev/null +++ b/Dev-C++/ExerciseBook/06.40/06.40.cpp @@ -0,0 +1,169 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͣΪַ */ +typedef char TElemType; + +/* Ľ㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ + struct BiTNode* parent; +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + +/* + * ĵʽ + * + *ע + * ĹؼǷֱ浱ǰڼαʡ + */ +void Algo_6_40(BiTree T); + +// () +Status CreateBiTree(BiTree* T, char* path); + +// ڲʵ֣p׷ +void CreateTree(BiTree* T, BiTree p, FILE* fp); + +// ͼλʽǰ +void PrintGraph(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf(" T ...\n"); + CreateBiTree(&T, NULL); + PrintGraph(T); + + printf("Ϊ"); + Algo_6_40(T); + + return 0; +} + + +/* + * ĵʽ + * + *ע + * ĹؼǷֱ浱ǰڼαʡ + */ +void Algo_6_40(BiTree T) { + BiTree p = T; + + while(p != NULL) { + // һηʽ㣬 + if(p->lchild != NULL) { + p = p->lchild; + } else { + // صĽڶα,Ҫ + printf("%c ", p->data); + + // ǰҷ֧صҪ + while(p->rchild == NULL) { + // صĽαʣ + while(p->parent != NULL && p->parent->rchild == p) { + p = p->parent; + } + + if(p->parent != NULL) { + // ǰ֧صҪʸ + if(p->parent->lchild == p) { + p = p->parent; + printf("%c ", p->data); // ͬ + } + } else { + printf("\n"); + + // صʱ + return; + } + } + + p = p->rchild; + } + } +} + +// () +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + + fp = fopen("TestData.txt", "r"); + CreateTree(T, NULL, fp); + fclose(fp); + + return OK; +} + +// ڲʵ֣p׷ +void CreateTree(BiTree* T, BiTree p, FILE* fp) { + char ch; + + ReadData(fp, "%c", &ch); + + if(ch == '^') { + *T = NULL; + } else { + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + (*T)->parent = p; + CreateTree(&(*T)->lchild, *T, fp); + CreateTree(&(*T)->rchild, *T, fp); + } +} + +// ͼλʽǰ +void PrintGraph(BiTree T) { + BiTree p = T; + int i = 1; + + while(p != NULL) { + // صĽڶα,Ҫ + printf("%c ", p->data); + i++; + + // һηʽ㣬 + if(p->lchild != NULL) { + p = p->lchild; + } else { + printf("^\n"); + + // ǰҷ֧صҪ + while(p->rchild == NULL) { + printf("%*c^\n", 2 * (i - 1), ' '); + i--; + + // صĽαʣ + while(p->parent != NULL && p->parent->rchild == p) { + p = p->parent; + i--; + } + + if(p->parent != NULL) { + // ǰ֧صҪʸ + if(p->parent->lchild == p) { + p = p->parent; + } + } else { + printf("\n"); + + // صʱ + return; + } + } + + printf("%*c", 2 * (i - 1), ' '); + p = p->rchild; + } + } +} diff --git a/Dev-C++/ExerciseBook/06.40/06.40.dev b/Dev-C++/ExerciseBook/06.40/06.40.dev new file mode 100644 index 0000000..bc63b09 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.40/06.40.dev @@ -0,0 +1,71 @@ +[Project] +FileName=06.40.dev +Name=06.40 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=2 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=06.40.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.40/TestData.txt b/Dev-C++/ExerciseBook/06.40/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.40/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.41-06.49/06.41-06.49.cpp b/Dev-C++/ExerciseBook/06.41-06.49/06.41-06.49.cpp new file mode 100644 index 0000000..fdb211e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.41-06.49/06.41-06.49.cpp @@ -0,0 +1,503 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_DEPTH 20 // +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * еkֵorder + */ +Status Algo_6_41(BiTree T, int k, int* order, TElemType* e); + +/* + * ҶӽĿ + */ +int Algo_6_42(BiTree T); + +/* + * + */ +void Algo_6_43(BiTree T); + +/* + * 'x' + */ +int Algo_6_44(BiTree T, TElemType x); + +/* + * ɾTеx + */ +Status Algo_6_45(BiTree* T, TElemType x); + +/* + * ƶķǵݹ㷨 + */ +void Algo_6_46(BiTree T, BiTree* Tx); + +/* + * + */ +void Algo_6_47(BiTree T); + +/* + * Ĺͬ + */ +BiTree Algo_6_48(BiTree T, TElemType a, TElemType b); + +/* + * ж϶ǷΪȫ + */ +Status Algo_6_49(BiTree T); + +/* + * ѰҸ㵽p·path洢·ϸָ(pָ) + */ +static int FindPath(BiTree T, TElemType e, BiTree path[]); + +// ָeָ +static BiTree EPtr(BiTree T, TElemType e); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf(" T ...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf(" 6.41 ֤...\n"); + { + int k = 9; + int order = 0; // + TElemType e; + + if(Algo_6_41(T, k, &order, &e)) { + printf("е %d ԪΪ %c \n", k, e); + } else { + printf("˴Ԫزڣ\n"); + } + + printf("\n"); + } + + printf(" 6.42 ֤...\n"); + { + printf("ҶӽΪ%d\n", Algo_6_42(T)); + printf("\n"); + } + + printf(" 6.43 ֤...\n"); + { + printf("Ϊ\n"); + Algo_6_43(T); + PrintGraph(T); + printf("\n"); + } + + printf(" 6.44 ֤...\n"); + { + char x = 'E'; + + printf(" %c Ϊ %d\n", x, Algo_6_44(T, x)); + printf("\n"); + } + + printf(" 6.45 ֤...\n"); + { + char x = 'D'; + + printf("ɾ %c 󣬶Ϊ\n", x); + if(Algo_6_45(&T, x)) { + PrintGraph(T); + } + printf("\n"); + } + + printf(" 6.46 ֤...\n"); + { + BiTree Tx; + + printf(" T Tx 󣬶TxΪ\n"); + Algo_6_46(T, &Tx); + PrintGraph(Tx); + printf("\n"); + } + + printf(" 6.47 ֤...\n"); + { + printf("Ϊ"); + Algo_6_47(T); + printf("\n"); + } + + printf(" 6.48 ֤...\n"); + { + BiTree Tmp = NULL; + TElemType a = 'I'; + TElemType b = 'H'; + + if((Tmp = Algo_6_48(T, a, b)) != NULL) { + printf("'%c' '%c' ͬΪ'%c'\n", a, b, Tmp->data); + } + printf("\n"); + } + + printf(" 6.49 ֤...\n"); + { + if(Algo_6_49(T)) { + printf("˶ȫ\n"); + } else { + printf("˶ȫ!\n"); + } + } + + return 0; +} + + +/* + * еkֵorder + */ +Status Algo_6_41(BiTree T, int k, int* order, TElemType* e) { + + if(T == NULL) { + *e = '\0'; + return ERROR; + } + + (*order)++; + + if(*order == k) { + *e = T->data; + return OK; + } else { + if(Algo_6_41(T->lchild, k, order, e)) { + return OK; + } + + if(Algo_6_41(T->rchild, k, order, e)) { + return OK; + } + } + + return ERROR; +} + +/* + * ҶӽĿ + */ +int Algo_6_42(BiTree T) { + int count = 0; + + if(T != NULL) { + if(T->lchild == NULL && T->rchild == NULL) { + count++; + } else { + count += Algo_6_42(T->lchild); // Ҷӽ + count += Algo_6_42(T->rchild); // Ҷӽ + } + } + + return count; +} + +/* + * + */ +void Algo_6_43(BiTree T) { + BiTree p; + + if(T != NULL) { + p = T->lchild; + T->lchild = T->rchild; + T->rchild = p; + + // ݹ齻 + Algo_6_43(T->lchild); + Algo_6_43(T->rchild); + } +} + +/* + * T'x' + */ +int Algo_6_44(BiTree T, TElemType x) { + BiTree p; + + p = EPtr(T, x); // һݹxλãָʽ + + return BiTreeDepth(p); // ڶݹx +} + +/* + * ɾTеx + */ +Status Algo_6_45(BiTree* T, TElemType x) { + + if(*T == NULL) { + return ERROR; + } + + // ҵ˸ý㣬ݹ + if((*T)->data == x) { + ClearBiTree(T); + return OK; + // ݹѰҸý + } else { + if(Algo_6_45(&((*T)->lchild), x)) { + return OK; + } + + if(Algo_6_45(&((*T)->rchild), x)) { + return OK; + } + + return ERROR; + } +} + +/* + * ƶķǵݹ㷨 + */ +void Algo_6_46(BiTree T, BiTree* Tx) { + int front, rear; + BiTree queue[MAX_TREE_SIZE] = {NULL}; // ָ飬ģУʼԪΪNULL + BiTree tree[MAX_TREE_SIZE]; // ½Ķ + BiTree p; + int parent; + + if(T == NULL) { + *Tx = NULL; + return; + } + + front = rear = 0; + + queue[rear] = T; + + while(front <= rear) { + p = queue[front]; + + if(p == NULL) { + front++; + continue; + } + + // ½ + tree[front] = (BiTree) malloc(sizeof(BiTNode)); + tree[front]->data = p->data; + tree[front]->lchild = tree[front]->rchild = NULL; + + // Ϊýҽڸ + if(front > 0) { + parent = (front - 1) / 2; + + // ǰΪ + if(2 * parent + 1 == front) { + tree[parent]->lchild = tree[front]; + } else { + tree[parent]->rchild = tree[front]; + } + } + + if(p->lchild != NULL) { + rear = 2 * front + 1; + queue[rear] = p->lchild; + } + + if(p->rchild != NULL) { + rear = 2 * front + 2; + queue[rear] = p->rchild; + } + + front++; + } + + *Tx = tree[0]; +} + +/* + * + */ +void Algo_6_47(BiTree T) { + int front, rear; + BiTree queue[MAX_TREE_SIZE]; // ָ飬ģ + BiTree p; + + if(T == NULL) { + return; + } + + front = rear = 0; + + queue[rear++] = T; + + while(front != rear) { + p = queue[front++]; + + printf("%c ", p->data); + + if(p->lchild != NULL) { + queue[rear++] = p->lchild; + } + + if(p->rchild != NULL) { + queue[rear++] = p->rchild; + } + } + + printf("\n"); +} + +/* + * Ĺͬ + */ +BiTree Algo_6_48(BiTree T, TElemType a, TElemType b) { + BiTree pa[MAX_TREE_DEPTH] = {NULL}; + BiTree pb[MAX_TREE_DEPTH] = {NULL}; + int lenA, lenB; + int i, j; + + // ·ѰҺ + if((lenA = FindPath(T, a, pa)) != 0 && (lenB = FindPath(T, b, pb)) != 0) { + for(i = lenA - 1; pa[i] != NULL; i--) { + for(j = lenB - 1; pb[j] != NULL; j--) { + if(pa[i]->data == pb[j]->data) { + return pa[i]; + } + } + } + } + + return NULL; +} + +/* + * ж϶ǷΪȫ + * + * ȫصDzʱһ + */ +Status Algo_6_49(BiTree T) { + int front, rear; + BiTree queue[MAX_TREE_SIZE]; // ָ飬ģ + int order[MAX_TREE_SIZE]; + BiTree p; + int count; + + if(T == NULL) { + return OK; + } + + front = rear = 0; + count = 1; + + queue[rear] = T; + order[rear] = 1; + rear++; + + // ͬʱΪ + while(front < rear) { + if(order[front] != count) { + return ERROR; + } + + p = queue[front]; // ȡͷԪ + + if(p->lchild != NULL) { + queue[rear] = p->lchild; + order[rear] = 2 * order[front]; + rear++; + } + + if(p->rchild != NULL) { + queue[rear] = p->rchild; + order[rear] = 2 * order[front] + 1; + rear++; + } + + front++; + count++; // ÿһһ + } + + return OK; +} + +// ָeָ +static BiTree EPtr(BiTree T, TElemType e) { + BiTree pl, pr; + + if(T == NULL) { + return NULL; + } + + // ҵĿ㣬ֱӷָ + if(T->data == e) { + return T; + } + + // вe + pl = EPtr(T->lchild, e); + if(pl != NULL) { + return pl; + } + + // вe + pr = EPtr(T->rchild, e); + if(pr != NULL) { + return pr; + } + + return NULL; +} + +// ѰҸ㵽p·path洢·ϸָ(pָ) +static int FindPath(BiTree T, TElemType e, BiTree path[]) { + int i = -1; + int mark[MAX_TREE_DEPTH] = {0}; // ʱջ + BiTree p; + + p = T; + + while(TRUE) { + // ûĽ㣬ȳ + while(p != NULL && p->data != e) { + i++; + + // µǰָ + path[i] = p; + + // ѷʹý + mark[i] = 1; + p = p->lchild; + } + + // Ľ + if(p != NULL) { + return i + 1; + } + + // ص + p = path[i]; + + // ڣ߸ѱʹصĸ + while(p->rchild == NULL || mark[i] == 2) { + path[i] = NULL; // ÿոλ + + i--; + if(i == -1) { + return 0; + } + + // ˵ + p = path[i]; + } + + // ѷʹý + mark[i] = 2; + p = p->rchild; + } +} diff --git a/Dev-C++/ExerciseBook/06.41-06.49/06.41-06.49.dev b/Dev-C++/ExerciseBook/06.41-06.49/06.41-06.49.dev new file mode 100644 index 0000000..6511744 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.41-06.49/06.41-06.49.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.41-06.49.dev +Name=06.41-06.49 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.41-06.49.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.41-06.49/BiTree.cpp b/Dev-C++/ExerciseBook/06.41-06.49/BiTree.cpp new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.41-06.49/BiTree.cpp @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.41-06.49/BiTree.h b/Dev-C++/ExerciseBook/06.41-06.49/BiTree.h new file mode 100644 index 0000000..ba89b3e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.41-06.49/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.41-06.49/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.41-06.49/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.41-06.49/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.41-06.49/LinkQueue.h b/Dev-C++/ExerciseBook/06.41-06.49/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.41-06.49/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.41-06.49/TestData.txt b/Dev-C++/ExerciseBook/06.41-06.49/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.41-06.49/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.50/06.50.cpp b/Dev-C++/ExerciseBook/06.50/06.50.cpp new file mode 100644 index 0000000..e4d9899 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.50/06.50.cpp @@ -0,0 +1,83 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ȡԤʽĽϢ򴴽 + */ +Status Algo_6_50(BiTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + BiTree T; + FILE* fp; + + printf("У...\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_50(&T, fp); + fclose(fp); + printf("\n"); + + printf("TΪ\n"); + PrintGraph(T); + + return 0; +} + + +/* + * ȡԤʽĽϢ򴴽 + */ +Status Algo_6_50(BiTree* T, FILE* fp) { + char s[4]; + BiTree tmp[MAX_TREE_SIZE]; // 洢ÿָ + int m, n; + BiTree p; + + m = n = 0; + + *T= NULL; + + while(TRUE) { + ReadData(fp, "%s", s); + printf("%s\n", s); + + // ˳־ + if(s[1] == '^') { + return OK; + } + + p = (BiTree) malloc(sizeof(BiTNode)); + if(p==NULL) { + exit(OVERFLOW); + } + p->data = s[1]; + p->lchild = p->rchild = NULL; + + // + if(s[0] == '^') { + *T = p; + tmp[n++] = p; + } else { + // Ѱ + while(mdata != s[0]) { + m++; + } + + if(m>=n) { + return ERROR; + } + + if(s[2] == 'L') { + tmp[m]->lchild = p; + } else { + tmp[m]->rchild = p; + } + } + + tmp[n++] = p; + } +} diff --git a/Dev-C++/ExerciseBook/06.50/06.50.dev b/Dev-C++/ExerciseBook/06.50/06.50.dev new file mode 100644 index 0000000..00a5182 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.50/06.50.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.50.dev +Name=06.50 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.50.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.50/BiTree.cpp b/Dev-C++/ExerciseBook/06.50/BiTree.cpp new file mode 100644 index 0000000..76327ed --- /dev/null +++ b/Dev-C++/ExerciseBook/06.50/BiTree.cpp @@ -0,0 +1,121 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.50/BiTree.h b/Dev-C++/ExerciseBook/06.50/BiTree.h new file mode 100644 index 0000000..d53885f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.50/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.50/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.50/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.50/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.50/LinkQueue.h b/Dev-C++/ExerciseBook/06.50/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.50/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.50/TestData.txt b/Dev-C++/ExerciseBook/06.50/TestData.txt new file mode 100644 index 0000000..43ff76f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.50/TestData.txt @@ -0,0 +1,9 @@ +^AL +ABL +ACR +BDL +CEL +CFR +DGR +FHL +^^L \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.51/06.51.cpp b/Dev-C++/ExerciseBook/06.51/06.51.cpp new file mode 100644 index 0000000..8dfa052 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.51/06.51.cpp @@ -0,0 +1,90 @@ +#include +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* + * ʽɵĶ + */ +void Algo_6_51(BiTree T); + +// жַcǷΪ +Status IsOperator(char c); + +// жȼ +Status Priority(char a, char b); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("ʽ"); + Algo_6_51(T); + printf("\n"); + + return 0; +} + + +/* + * ʽɵĶ + */ +void Algo_6_51(BiTree T) { + if(T == NULL) { + return; + } + + if(T->lchild != NULL) { + // ǰDzȼڵǰ + if(IsOperator(T->lchild->data) && Priority(T->lchild->data, T->data) < 0) { + printf("("); + Algo_6_51(T->lchild); + printf(")"); + } else { + Algo_6_51(T->lchild); + } + } + + printf("%c", T->data); + + if(T->rchild != NULL) { + // ǰҺDzȼڵǰ + if(IsOperator(T->rchild->data) && Priority(T->rchild->data, T->data) < 0) { + printf("("); + Algo_6_51(T->rchild); + printf(")"); + } else { + Algo_6_51(T->rchild); + } + } +} + +// жַcǷΪ +Status IsOperator(char c) { + if(c == '+' || c == '-' || c == '*' || c == '/') { + return TRUE; + } else { + return ERROR; + } +} + +// жȼ +Status Priority(char a, char b) { + // aȼ + if((a == '+' || a == '-') && (b == '*' || b == '/')) { + return -1; + + // aȼ + } else if((a == '*' || a == '/') && (b == '+' || b == '-')) { + return 1; + + // ȼͬ + } else { + return 0; + } +} diff --git a/Dev-C++/ExerciseBook/06.51/06.51.dev b/Dev-C++/ExerciseBook/06.51/06.51.dev new file mode 100644 index 0000000..40bae3a --- /dev/null +++ b/Dev-C++/ExerciseBook/06.51/06.51.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.51.dev +Name=06.51 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.51.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.51/BiTree.cpp b/Dev-C++/ExerciseBook/06.51/BiTree.cpp new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.51/BiTree.cpp @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.51/BiTree.h b/Dev-C++/ExerciseBook/06.51/BiTree.h new file mode 100644 index 0000000..ba89b3e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.51/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.51/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.51/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.51/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.51/LinkQueue.h b/Dev-C++/ExerciseBook/06.51/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.51/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.51/TestData.txt b/Dev-C++/ExerciseBook/06.51/TestData.txt new file mode 100644 index 0000000..be56cc6 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.51/TestData.txt @@ -0,0 +1 @@ +С*/*+a^^b^^-c^^d^^e^^-g^^h^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.52/06.52.cpp b/Dev-C++/ExerciseBook/06.52/06.52.cpp new file mode 100644 index 0000000..49b08f3 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.52/06.52.cpp @@ -0,0 +1,90 @@ +#include +#include // ṩpowlogԭ +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ķïȣx߶ + * עΪֵ + */ +int Algo_6_52(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("ķïΪ %d", Algo_6_52(T)); + printf("\n"); + + return 0; +} + + +/* + * ķïȣx߶ + * עΪֵ + */ +int Algo_6_52(BiTree T) { + int lux; // ï + int col, width; // Ⱥ + int row, high; // ǰڲ߶ + BiTree queue[MAX_TREE_SIZE]; // ָ飬ģ + int level[MAX_TREE_SIZE]; // ¼ǰڵڼ + BiTree p; + int m, n; + + if(T==NULL) { + return 0; + } + + width = high = 0; + m = n = 0; + col = 1; + + queue[n] = T; + level[n] = 1; + n++; + + while(mhigh) { + high = row; + col = 1; // ʱҪ + } else { + col++; + } + + if(col>width) { + width = col; + } + + if(p->lchild!=NULL) { + queue[n] = p->lchild; + level[n] = row+1; + n++; + } + + if(p->rchild!=NULL) { + queue[n] = p->rchild; + level[n] = row+1; + n++; + } + + + } + + lux = width * high; + + return lux; +} diff --git a/Dev-C++/ExerciseBook/06.52/06.52.dev b/Dev-C++/ExerciseBook/06.52/06.52.dev new file mode 100644 index 0000000..982f1f9 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.52/06.52.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.52.dev +Name=06.52 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.52.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.52/BiTree.cpp b/Dev-C++/ExerciseBook/06.52/BiTree.cpp new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.52/BiTree.cpp @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.52/BiTree.h b/Dev-C++/ExerciseBook/06.52/BiTree.h new file mode 100644 index 0000000..ba89b3e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.52/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.52/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.52/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.52/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.52/LinkQueue.h b/Dev-C++/ExerciseBook/06.52/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.52/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.52/TestData.txt b/Dev-C++/ExerciseBook/06.52/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.52/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.53/06.53.cpp b/Dev-C++/ExerciseBook/06.53/06.53.cpp new file mode 100644 index 0000000..0e615b1 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.53/06.53.cpp @@ -0,0 +1,87 @@ +#include +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_DEPTH 20 // + +/* + * ѰҸ㵽Ҷӽ·һ + */ +int Algo_6_53(BiTree T, BiTree path[]); + + +int main(int argc, char* argv[]) { + BiTree T; + BiTree way[MAX_TREE_DEPTH] = {NULL}; + int i, n; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("㵽Ҷӽ·һ"); + n = Algo_6_53(T, way); + for(i = 0; i < n; i++) { + printf("%c ", way[i]->data); + } + printf("\n"); + + return 0; +} + + +/* + * ѰҸ㵽Ҷӽ·һ + */ +int Algo_6_53(BiTree T, BiTree path[]) { + int i = -1; + int mark[MAX_TREE_DEPTH] = {0}; // ʱջ + BiTree p; + int depth; + + // ж + depth = BiTreeDepth(T); + + p = T; + + while(TRUE) { + // ȳ + while(p != NULL) { + i++; + + // µǰָ + path[i] = p; + + // ѷʹý + mark[i] = 1; + p = p->lchild; + } + + // ͷж·Ƿ + if(i + 1 == depth) { + return depth; + } + + // ص + p = path[i]; + + // ڣ߸ѱʹصĸ + while(p->rchild == NULL || mark[i] == 2) { + path[i] = NULL; // ÿոλ + + i--; + if(i == -1) { + return 0; + } + + // ˵ + p = path[i]; + } + + // ѷʹý + mark[i] = 2; + p = p->rchild; + } +} diff --git a/Dev-C++/ExerciseBook/06.53/06.53.dev b/Dev-C++/ExerciseBook/06.53/06.53.dev new file mode 100644 index 0000000..07fcdcf --- /dev/null +++ b/Dev-C++/ExerciseBook/06.53/06.53.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.53.dev +Name=06.53 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=06.53.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.53/BiTree.cpp b/Dev-C++/ExerciseBook/06.53/BiTree.cpp new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.53/BiTree.cpp @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.53/BiTree.h b/Dev-C++/ExerciseBook/06.53/BiTree.h new file mode 100644 index 0000000..ba89b3e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.53/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.53/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.53/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.53/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.53/LinkQueue.h b/Dev-C++/ExerciseBook/06.53/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.53/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.53/TestData.txt b/Dev-C++/ExerciseBook/06.53/TestData.txt new file mode 100644 index 0000000..f00a60d --- /dev/null +++ b/Dev-C++/ExerciseBook/06.53/TestData.txt @@ -0,0 +1 @@ +СABD^^EG^^^CF^HI^^J^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.54/06.54.cpp b/Dev-C++/ExerciseBook/06.54/06.54.cpp new file mode 100644 index 0000000..41a7070 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.54/06.54.cpp @@ -0,0 +1,64 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ݶIJдʽ + */ +Status Algo_6_54(BiTree* T, TElemType sa[100]); + + +int main(int argc, char* argv[]) { + BiTree T; + TElemType sa[MAX_TREE_SIZE] = "ABCDEF^G^HI^J"; // + + printf("У...\n"); + Algo_6_54(&T, sa); + PrintGraph(T); + + return 0; +} + + +/* + * ݶIJдʽ + */ +Status Algo_6_54(BiTree* T, TElemType sa[]) { + BiTree tree[MAX_TREE_SIZE]; // ʱűиָĸƷ + int p, i; + + i = 0; + + while(sa[i] != '\0') { + if(sa[i] == '^') { + tree[i] = NULL; + } else { + tree[i] = (BiTree) malloc(sizeof(BiTNode)); + if(tree[i] == NULL) { + exit(OVERFLOW); + } + tree[i]->data = sa[i]; + tree[i]->lchild = tree[i]->rchild = NULL; + } + + if(i > 0) { + p = (i - 1) / 2; // + + // ǰ + if(2 * p + 1 == i) { + tree[p]->lchild = tree[i]; + } else { + tree[p]->rchild = tree[i]; + } + } + + i++; + } + + *T = tree[0]; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/06.54/06.54.dev b/Dev-C++/ExerciseBook/06.54/06.54.dev new file mode 100644 index 0000000..5702466 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.54/06.54.dev @@ -0,0 +1,102 @@ +[Project] +FileName=06.54.dev +Name=06.54 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.54.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.54/BiTree.cpp b/Dev-C++/ExerciseBook/06.54/BiTree.cpp new file mode 100644 index 0000000..76327ed --- /dev/null +++ b/Dev-C++/ExerciseBook/06.54/BiTree.cpp @@ -0,0 +1,121 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.54/BiTree.h b/Dev-C++/ExerciseBook/06.54/BiTree.h new file mode 100644 index 0000000..d53885f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.54/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.54/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.54/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.54/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.54/LinkQueue.h b/Dev-C++/ExerciseBook/06.54/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.54/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.55/06.55.cpp b/Dev-C++/ExerciseBook/06.55/06.55.cpp new file mode 100644 index 0000000..916f194 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.55/06.55.cpp @@ -0,0 +1,64 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* + * ÿĿ + */ +int Algo_6_55(BiTree T); + +// Ŀ +void PreOrderPrint(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("ֵӦĿ\n"); + Algo_6_55(T); + PreOrderPrint(T); + + return 0; +} + + +/* + * ÿĿ + */ +int Algo_6_55(BiTree T) { + int l, r; + + if(T == NULL) { + return 0; + } else { + T->DescNum = 0; + + if(T->lchild != NULL) { + l = Algo_6_55(T->lchild); + T->DescNum += l + 1; + } + + if(T->rchild != NULL) { + r = Algo_6_55(T->rchild); + T->DescNum += r + 1; + } + } + + return T->DescNum; +} + +// Ŀ +void PreOrderPrint(BiTree T) { + if(T != NULL) { + printf(" %c Ŀ %d\n", T->data, T->DescNum); + PreOrderPrint(T->lchild); + PreOrderPrint(T->rchild); + } +} diff --git a/Dev-C++/ExerciseBook/06.55/06.55.dev b/Dev-C++/ExerciseBook/06.55/06.55.dev new file mode 100644 index 0000000..281991f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.55/06.55.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.55.dev +Name=06.55 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.55.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.55/BiTree.cpp b/Dev-C++/ExerciseBook/06.55/BiTree.cpp new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.55/BiTree.cpp @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.55/BiTree.h b/Dev-C++/ExerciseBook/06.55/BiTree.h new file mode 100644 index 0000000..425dfa1 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.55/BiTree.h @@ -0,0 +1,92 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ + + int DescNum; // ý +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.55/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.55/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.55/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.55/LinkQueue.h b/Dev-C++/ExerciseBook/06.55/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.55/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.55/TestData.txt b/Dev-C++/ExerciseBook/06.55/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.55/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.56-06.58/06.56-06.58.cpp b/Dev-C++/ExerciseBook/06.56-06.58/06.56-06.58.cpp new file mode 100644 index 0000000..4cb0485 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.56-06.58/06.56-06.58.cpp @@ -0,0 +1,502 @@ +#include +#include "Status.h" //**01 **// +#include "BiThrTree.h" //**06 Ͷ**// + +/* + * Ѱҽpĺ + */ +BiThrTree Algo_6_56(BiThrTree p); + +// ԷAlgo_6_56 +void PreTraverse(BiThrTree Thrt); + + +/* + * ںѰҽpĺ + */ +BiThrTree Algo_6_57(BiThrTree p); + +// ԷAlgo_6_57ĺ +void PosTraverse(BiThrTree Thrt); + + +/* + * ΪxҽxֻȫΪp + * УpڵҲȫThrxָxͷ㡣 + * עpѾժ£޽Ϊx + */ +Status Algo_6_58(BiThrTree p, BiThrTree x, BiThrTree Thrx); + + +// T +Status PreOrderThreading(BiThrTree* Thrt, BiThrTree T); + +// ڲʵ +void PreTheading(BiThrTree p); + +// ǵݹ㷨 +Status PreOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)); + + +// T˳ʼparent +Status PosOrderThreading(BiThrTree* Thrt, BiThrTree T); + +// ڲʵ֣ıʽ +void PosTheading(BiThrTree p); + +// Ժкǵݹ㷨 +Status PosOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)); + + +// ԺӡԪ +Status PrintElem(TElemType c); + + + +int main(int argc, char* argv[]) { + + printf(" 6.56 ֤...\n"); + { + BiThrTree T; // + BiThrTree Thr; // + + printf(" (ABDG^^^EH^^I^^CF^J^^^)...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf(" Զ...\n"); + PreOrderThreading(&Thr, T); + + printf(" "); + PreOrderTraverse_Thr(Thr, PrintElem); + + printf(" ԷAlgo_6_56У"); + PreTraverse(Thr); + } + PressEnterToContinue(); + + + printf(" 6.57 ֤...\n"); + { + BiThrTree T; // + BiThrTree Thr; // + + printf(" (ABDG^^^EH^^I^^CF^J^^^)...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf(" Զк...\n"); + PosOrderThreading(&Thr, T); + + printf(" "); + PosOrderTraverse_Thr(Thr, PrintElem); + + printf(" ԷAlgo_6_57ĺУ"); + PosTraverse(Thr); + } + PressEnterToContinue(); + + + printf(" 6.58 ֤...\n"); + { + BiThrTree T; // + BiThrTree Thr; // ȫ + + BiThrTree Tx; // Ķ + BiThrTree Thrx; // ȫ + + BiThrTree p; + + printf(" (ABDG^^^EH^^I^^CF^J^^^)...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf(" Զȫ...\n"); + InOrderThreading(&Thr, T); + + printf(" ȫ"); + InOrderTraverse_Thr(Thr, PrintElem); + + printf(" ===============================================\n"); + + printf(" (012^47^^^35^^68^^9^^^)...\n"); + CreateBiTree(&Tx, "TestData_x.txt"); + + printf(" Զȫ...\n"); + InOrderThreading(&Thrx, Tx); + + printf(" ȫ"); + InOrderTraverse_Thr(Thrx, PrintElem); + + printf(" ===============================================\n"); + + p = T->lchild->rchild; + printf(" ⣬ x 뵽 T %c ...\n", p->data); + Algo_6_58(p, Tx, Thrx); + + printf(" ɺȫΪ"); + InOrderTraverse_Thr(Thr, PrintElem); + } + PressEnterToContinue(); + +} + + + +/* + * Ѱҽpĺ + */ +BiThrTree Algo_6_56(BiThrTree p) { + if(p == NULL) { + return NULL; + } + + // ںֱӻȡϢ + if(p->RTag == Thread) { + p = p->rchild; + } else { + if(p->lchild != NULL) { + p = p->lchild; + } else { + p = p->rchild; + } + } + + return p; +} + +// ԷAlgo_6_56 +void PreTraverse(BiThrTree Thrt) { + BiThrTree p = Thrt->rchild; + + while(p != Thrt) { + printf("%c", p->data); + p = Algo_6_56(p); + } + + printf("\n"); +} + + +/* + * ںѰҽpĺ + */ +BiThrTree Algo_6_57(BiThrTree p) { + if(p == NULL) { + return NULL; + } + + // ںֱӻȡϢ + if(p->RTag == Thread) { + p = p->rchild; + } else { + // ǰ + if(p == p->parent->rchild) { + p = p->parent; + } else { + // ûҺ + if(p->parent->rchild == NULL || p->parent->RTag == Thread) { + p = p->parent; + } else { + p = p->parent->rchild; + + /* ֵܽҶ */ + + while(p->lchild != NULL) { + p = p->lchild; + } + + while(p->rchild != NULL && p->RTag == Link) { + p = p->rchild; + } + } + } + } + + return p; +} + +// ԷAlgo_6_57ĺ +void PosTraverse(BiThrTree Thrt) { + BiThrTree p = Thrt->rchild; + + while(p != Thrt) { + printf("%c", p->data); + p = Algo_6_57(p); + } + + printf("\n"); +} + + +/* + * ΪxҽxֻȫΪp + * УpڵҲȫThrxָxͷ㡣 + * עpѾժ£޽Ϊx + */ +Status Algo_6_58(BiThrTree p, BiThrTree x, BiThrTree Thrx) { + BiThrTree pPre; // pǰ + + BiThrTree xFirst; // xеĵһ + BiThrTree xLast; // xеһ + + BiThrTree lt; // p + BiThrTree ltFirst; // ltеĵһ + + if(p==NULL || x==NULL) { + return ERROR; + } + + // x㲻Һ + if(x->RTag==Link) { + return ERROR; + } + + // ȡxеĵһһ + xFirst = Thrx->lchild; + // һֱ + while(xFirst->LTag==Link){ + xFirst = xFirst->lchild; + } + xLast = Thrx->rchild; + + // p + if(p->LTag==Thread) { + pPre = p->lchild; // ֱӻȡpǰ + + p->LTag = Link; // ޸pΪ + p->lchild = x; // x + + xFirst->lchild = pPre; // xFirst + xLast->rchild = p; // xLast + + // p + } else { + // ָp + lt = p->lchild; + + // ltеĵһ + ltFirst = lt; + // ӣһֱ + while(ltFirst->LTag==Link){ + ltFirst = ltFirst->lchild; + } + + x->RTag = Link; // ltΪx + x->rchild = lt; + + xFirst->lchild = ltFirst->lchild; // ӹlt + ltFirst->lchild = x; // ltָx + + p->lchild = x; // p + } + + // xThrxƳ + Thrx->lchild = Thrx->rchild = Thrx; + + return OK; +} + + +// T +Status PreOrderThreading(BiThrTree* Thrt, BiThrTree T) { + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(*Thrt == NULL) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + (*Thrt)->LTag = Link; + (*Thrt)->RTag = Thread; + (*Thrt)->rchild = NULL; + + // ֻͷ + if(!T) { + (*Thrt)->lchild = (*Thrt)->rchild = *Thrt; + } else { + (*Thrt)->lchild = T; + pre = *Thrt; // ָͷ + + PreTheading(T); // ʼ + + pre->RTag = Thread; // һ + pre->rchild = *Thrt; // һָͷ + + (*Thrt)->rchild = T; // ͷָһ㣬ѭϵ + } + + return OK; +} + +// ڲʵ +void PreTheading(BiThrTree p) { + if(p == NULL) { + return; + } + + // Ϊһ + if(pre->rchild == NULL) { + pre->RTag = Thread; + pre->rchild = p; + } else { + // ΪգLink + pre->RTag = Link; + } + + // preǰŲһ + pre = p; + + // + PreTheading(p->lchild); + + // + if(p->rchild != NULL && p->RTag == Link) { + PreTheading(p->rchild); + } +} + +// ǵݹ㷨 +Status PreOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)) { + BiThrTree p = Thrt; // pָ + + while(p->rchild != Thrt) { + // ʣֱͷ + while(p->lchild != NULL) { + p = p->lchild; + if(Visit(p->data) == ERROR) { + return ERROR; + } + } + + // ʵͷҷʣͨ + if(p->rchild != Thrt) { + p = p->rchild; + if(Visit(p->data) == ERROR) { + return ERROR; + } + } + } + + printf("\n"); + + return OK; +} + + +// T˳ʼparent +Status PosOrderThreading(BiThrTree* Thrt, BiThrTree T) { + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(*Thrt == NULL) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + (*Thrt)->LTag = Link; + (*Thrt)->RTag = Thread; + (*Thrt)->rchild = *Thrt; + + if(T == NULL) { + (*Thrt)->lchild = (*Thrt)->rchild = *Thrt; + } else { + (*Thrt)->lchild = T; + pre = *Thrt; // ָͷ + + T->parent = *Thrt; + + PosTheading(T); // ʼ + + (*Thrt)->rchild = pre; // ͷָһ㣬ѭϵ + } + + return OK; +} + +// ڲʵ֣ıʽ +void PosTheading(BiThrTree p) { + if(p == NULL) { + return; + } + + // Ϊǰ + if(p->rchild == NULL) { + p->RTag = Thread; + p->rchild = pre; + } else { + // ΪգLink + p->RTag = Link; + } + + // pre˳Ϊһ + pre = p; + + // + if(p->RTag != Thread) { + if(p->rchild != NULL) { + p->rchild->parent = p; + } + + PosTheading(p->rchild); + } + + if(p->lchild != NULL) { + p->lchild->parent = p; + } + + // + PosTheading(p->lchild); +} + +// Ժкǵݹ㷨 +Status PosOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)) { + BiThrTree r = Thrt->rchild; // pָһ + BiThrTree p; + + // Ϊ + while(r != Thrt) { + if(Visit(r->data) == ERROR) { + return ERROR; + } + + // ں + if(r->RTag == Thread) { + r = r->rchild; + } else { + p = r->parent; + if(p == Thrt) { + break; // Ѿ + } + + // ǰҺ + if(r == p->rchild) { + r = p; + + // ǰ + } else { + // ҺΪNULL + if(p->rchild == NULL || p->RTag == Thread) { + r = p; + } else { + r = p->rchild; + + /* rҶ */ + + while(r->lchild != NULL) { + r = r->lchild; + } + + while(r->rchild != NULL && r->RTag == Link) { + r = r->rchild; + } + } + } + } + } + + printf("\n"); + + return OK; +} + + +// ԺӡԪ +Status PrintElem(TElemType c) { + printf("%c", c); + return OK; +} diff --git a/Dev-C++/ExerciseBook/06.56-06.58/06.56-06.58.dev b/Dev-C++/ExerciseBook/06.56-06.58/06.56-06.58.dev new file mode 100644 index 0000000..0fc63c5 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.56-06.58/06.56-06.58.dev @@ -0,0 +1,100 @@ +[Project] +FileName=06.56-06.58.dev +Name=06.56-06.58 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=BiThrTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.56-06.58.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiThrTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData_T.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=TestData_x.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.56-06.58/BiThrTree.cpp b/Dev-C++/ExerciseBook/06.56-06.58/BiThrTree.cpp new file mode 100644 index 0000000..0275869 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.56-06.58/BiThrTree.cpp @@ -0,0 +1,182 @@ +/*======================= + * + * + * 㷨: 6.56.66.7 + ========================*/ + +#include "BiThrTree.h" + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiThrTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 㷨6.6 + * + * TȫΪThrt + * עǰ + */ +Status InOrderThreading(BiThrTree* Thrt, BiThrTree T) { + // ͷ + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(!*Thrt) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + + (*Thrt)->LTag = Link; // ӣҪָĸ + (*Thrt)->RTag = Thread; // ָ룬ҪָһԪأԱ + + (*Thrt)->rchild = *Thrt; + + // Ϊգָָ + if(!T) { + (*Thrt)->lchild = *Thrt; + } else { + (*Thrt)->lchild = T; // ָͷ + pre = *Thrt; // ¼ǰϢʼΪͷ + + InTheading(T); // Խ + + pre->rchild = *Thrt; // һָͷ + pre->RTag = Thread; // һ + (*Thrt)->rchild = pre; // ͷָһ㣬˫ϵ + } + + return OK; + +} + +/* + * 㷨6.5 + * + * ȫǵݹ㷨 + */ +Status InOrderTraverse_Thr(BiThrTree T, Status(Visit)(TElemType)) { + BiThrTree p = T->lchild; // pָ㣨ͬͷ㣩 + + // ʱp==T + while(p != T) { + // ӣ + while(p->LTag == Link) { + p = p->lchild; + } + + // ΪյĽ㣨ߣ + if(!Visit(p->data)) { + return ERROR; + } + + // ںû + while(p->RTag == Thread && p->rchild != T) { + p = p->rchild; // pָ + Visit(p->data); // ʺ̽ + } + + // + p = p->rchild; + } + + printf("\n"); + + return OK; +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiThrTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiThrTree) malloc(sizeof(BiThrNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + +/* + * 㷨6.7 + * + * ȫڲʵ + */ +static void InTheading(BiThrTree p) { + if(p) { + InTheading(p->lchild); // + + // ǰΪգҪǰ + if(!p->lchild) { + p->LTag = Thread; + p->lchild = pre; + + // Ϊգӱǣ̲ȱһ裩 + } else { + p->LTag = Link; + } + + // ǰΪգΪǰ㽨 + if(!pre->rchild) { + pre->RTag = Thread; + pre->rchild = p; + + // ΪգҺӱǣ̲ȱһ裩 + } else { + p->RTag = Link; + } + + pre = p; // preǰŲһ + + InTheading(p->rchild); // + } +} diff --git a/Dev-C++/ExerciseBook/06.56-06.58/BiThrTree.h b/Dev-C++/ExerciseBook/06.56-06.58/BiThrTree.h new file mode 100644 index 0000000..386ee99 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.56-06.58/BiThrTree.h @@ -0,0 +1,89 @@ +/*======================= + * + * + * 㷨: 6.56.66.7 + ========================*/ + +#ifndef BITHRTREE_H +#define BITHRTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ͱ */ +typedef enum { + Link, Thread // Link==0ָ()Thread==1 +} PointerTag; + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiThrNode { + TElemType data; // Ԫ + struct BiThrNode* lchild; // ָ + struct BiThrNode* rchild; // Һָ + PointerTag LTag; // ָ + PointerTag RTag; // ָ + + struct BiThrNode* parent; // ˫׽ָ룬ڷǵݹʱʹ +} BiThrNode; + +/* ָָ */ +typedef BiThrNode* BiThrTree; + + +/* ȫֱ */ +static BiThrTree pre; // ָǰʽһ㣨ǰ + + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiThrTree* T, char* path); + +/* + * 㷨6.6 + * + * TȫΪThrt + * עǰ + */ +Status InOrderThreading(BiThrTree* Thrt, BiThrTree T); + +/* + * 㷨6.5 + * + * ȫTǵݹ㷨 + */ +Status InOrderTraverse_Thr(BiThrTree T, Status(Visit)(TElemType)); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiThrTree* T, FILE* fp); + +/* + * 㷨6.7 + * + * ȫڲʵ + */ +static void InTheading(BiThrTree p); + +#endif diff --git a/Dev-C++/ExerciseBook/06.56-06.58/TestData_T.txt b/Dev-C++/ExerciseBook/06.56-06.58/TestData_T.txt new file mode 100644 index 0000000..ca28844 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.56-06.58/TestData_T.txt @@ -0,0 +1 @@ +УϵǴս㣩ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.56-06.58/TestData_x.txt b/Dev-C++/ExerciseBook/06.56-06.58/TestData_x.txt new file mode 100644 index 0000000..ea3fd92 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.56-06.58/TestData_x.txt @@ -0,0 +1 @@ +УϵǴս㣩012^47^^^35^^68^^9^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.59-06.62/06.59-06.62.cpp b/Dev-C++/ExerciseBook/06.59-06.62/06.59-06.62.cpp new file mode 100644 index 0000000..994ec7f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.59-06.62/06.59-06.62.cpp @@ -0,0 +1,173 @@ +#include +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ĸ + */ +void Algo_6_59(CSTree T); + +/* + * Ҷӽ + */ +int Algo_6_60(CSTree T); + +/* + * Ķȣиȵֵ + */ +int Algo_6_61(CSTree T); + +/* + * + */ +int Algo_6_62(CSTree T); + + +int main(int argc, char* argv[]) { + CSTree T; + + printf("УT...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf(" 6.59 ֤...\n"); + { + printf("б...\n"); + Algo_6_59(T); + printf("\n\n"); + } + + printf(" 6.60 ֤...\n"); + { + int count; + + count = Algo_6_60(T); + printf("ҶӽΪcount = %d\n", count); + printf("\n"); + } + + printf(" 6.61 ֤...\n"); + { + int degree; + + degree = Algo_6_61(T); + printf("ĶΪdegree = %d\n", degree); + printf("\n"); + } + + printf(" 6.62 ֤...\n"); + { + int depth; + + depth = Algo_6_62(T); + printf("Ϊdepth = %d\n", depth); + printf("\n"); + } + + return 0; +} + + +/* + * ĸ + */ +void Algo_6_59(CSTree T) { + CSTree p, q; + + if(T == NULL) { + return; + } + + p = T; + q = T->firstchild; + + while(q != NULL) { + printf("(%c, %c) ", p->data, q->data); + q = q->nextsibling; + } + + Algo_6_59(T->firstchild); + Algo_6_59(T->nextsibling); +} + +/* + * Ҷӽ + */ +int Algo_6_60(CSTree T) { + if(T == NULL) { + return 0; + } + + // Ҷӽ + if(T->firstchild == NULL) { + return 1 + Algo_6_60(T->nextsibling); + } else { + return Algo_6_60(T->firstchild) + Algo_6_60(T->nextsibling); + } +} + +/* + * Ķȣиȵֵ + */ +int Algo_6_61(CSTree T) { + CSTree queue[MAX_TREE_SIZE]; // 洢ʹĽ + int parent[MAX_TREE_SIZE]; // 洢ÿĸ + int order[MAX_TREE_SIZE]; // 洢ÿı + CSTree p, r; + int col, max; + int m, n; + int curParent; // ¼ʽĸ + + if(T == NULL || T->firstchild == NULL) { + return 0; + } + + curParent = -2; + max = 0; + + m = n = 0; + + queue[n] = T; + parent[n] = -1; + order[n] = 0; + n++; + + while(m < n) { + p = queue[m]; + + // µĸ + if(parent[m] != curParent) { + curParent = parent[m]; + col = 1; // + } else { + col++; + } + + if(col > max) { + max = col; + } + + // 洢ӽ + for(r = p->firstchild; r != NULL; r = r->nextsibling) { + queue[n] = r; + parent[n] = order[m]; // Ϊӽ洢 + order[n] = n; // ¼ǰı + n++; + } + + m++; + } + + return max; +} + +/* + * + */ +int Algo_6_62(CSTree T) { + return TreeDepth(T); // Ѷ +} diff --git a/Dev-C++/ExerciseBook/06.59-06.62/06.59-06.62.dev b/Dev-C++/ExerciseBook/06.59-06.62/06.59-06.62.dev new file mode 100644 index 0000000..641664b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.59-06.62/06.59-06.62.dev @@ -0,0 +1,91 @@ +[Project] +FileName=06.59-06.62.dev +Name=06.59-06.62 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=4 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=CSTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.59-06.62.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CSTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.59-06.62/CSTree.cpp b/Dev-C++/ExerciseBook/06.59-06.62/CSTree.cpp new file mode 100644 index 0000000..64d258f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.59-06.62/CSTree.cpp @@ -0,0 +1,166 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CSTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûкӽûֵܽڵ㣬ʹ^棺"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CSTree T) { + int max = 0; + + Depth(T, 0, &max); + + return max; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CSTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (CSTree) malloc(sizeof(CSNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + Create(&((*T)->firstchild), fp); // + Create(&((*T)->nextsibling), fp); // ֵ + } +} + +// ȵڲʵ +static void Depth(CSTree T, int d, int* max) { + if(T == NULL) { + return; + } + + d++; // ָʾǰڵIJ + + if(d > *max) { + *max = d; + } + + Depth(T->firstchild, d, max); // ± + Depth(T->nextsibling, --d, max); // ұ +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/Dev-C++/ExerciseBook/06.59-06.62/CSTree.h b/Dev-C++/ExerciseBook/06.59-06.62/CSTree.h new file mode 100644 index 0000000..3d95beb --- /dev/null +++ b/Dev-C++/ExerciseBook/06.59-06.62/CSTree.h @@ -0,0 +1,87 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CSTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CSTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CSTree* T, FILE* fp); + +// ȵڲʵ +static void Depth(CSTree T, int d, int *max); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/Dev-C++/ExerciseBook/06.59-06.62/TestData.txt b/Dev-C++/ExerciseBook/06.59-06.62/TestData.txt new file mode 100644 index 0000000..0b1431c --- /dev/null +++ b/Dev-C++/ExerciseBook/06.59-06.62/TestData.txt @@ -0,0 +1 @@ +RAD^E^^B^CFG^H^K^^^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.63/06.63.cpp b/Dev-C++/ExerciseBook/06.63/06.63.cpp new file mode 100644 index 0000000..dc1592e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.63/06.63.cpp @@ -0,0 +1,32 @@ +#include +#include "Status.h" //**01 **// +#include "CTree.h" //**06 Ͷ**// + +/* + * 㺢ʾ + */ +int Algo_6_63(CTree T); + + +int main(int argc, char* argv[]) { + CTree T; + + printf("T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("Ϊ %d\n", Algo_6_63(T)); + printf("\n"); + + return 0; +} + + +/* + * 㺢ʾ + */ +int Algo_6_63(CTree T) { + return TreeDepth(T); // Ѷ +} diff --git a/Dev-C++/ExerciseBook/06.63/06.63.dev b/Dev-C++/ExerciseBook/06.63/06.63.dev new file mode 100644 index 0000000..29fb4f3 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.63/06.63.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.63.dev +Name=06.63 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=CTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.63.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.63/CTree.cpp b/Dev-C++/ExerciseBook/06.63/CTree.cpp new file mode 100644 index 0000000..d2c194a --- /dev/null +++ b/Dev-C++/ExerciseBook/06.63/CTree.cpp @@ -0,0 +1,405 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#include "CTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("ԪϢڿս㣬ʹ^...\n"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T) { + int k, level; + + // + if(TreeEmpty(T)) { + return 0; + } + + /* + * kʼΪһλ + * Ľ㰴洢洢Ľضλ + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CTree* T, FILE* fp) { + int r; // ĸλã + int n; // ¼Ԫ + int cur; // α + TElemType ch; + LinkQueue Q; + QElemType e; // Ԫָʾλ + char s[MAX_CHILD_COUNT + 1]; + int i; + ChildPtr p, pc; + + InitQueue(&Q); + + n = 0; + + // ȡλ + if(fp == NULL) { + printf("λ(0~%d)", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("ֵ"); + scanf("%s", s); + ch = s[0]; + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // λó + + printf(" %c ĺӽ㣬ںʱһ^", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // ij + p = T->nodes[e].firstchild; + + // װǰ + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // ǰӵĺ + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // ҵβ + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // ¼λ + ReadData(fp, "%d", &r); + cur = r; + + // ¼ֵ + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ֵ%c\n", ch); + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ %c ĺӣ", ch); + + // ¼뺢ӽ + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // λó + + // + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // װǰ + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // ij + p = T->nodes[e].firstchild; + + // ǰӵĺ + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // ҵβ + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // λ + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // ڵIJ + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // ˸ı + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // eĺӼ0 + + // ÿʱһϢΪЧΪÿ㶼кӽ + pt[e].lastChild = -1; + + // ָýĺ + cp = T.nodes[e].firstchild; + + // ͷŸý㴦ĺռڴ + while(cp != NULL) { + // ǰλ + EnQueue(&Q, cp->child); + + // ¼ + pt[cp->child].row = pt[e].row + 1; + + // ¼ + pt[cp->child].col = ++count; + + // ¼ǰǵڼ + pt[cp->child].childIndex = ++n; + + // ΪһӵϢ + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework(T); +} + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // ʼΪЧ + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + // ˫ױ洢ṹӸ + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/Dev-C++/ExerciseBook/06.63/CTree.h b/Dev-C++/ExerciseBook/06.63/CTree.h new file mode 100644 index 0000000..873504b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.63/CTree.h @@ -0,0 +1,129 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* ӽ㶨 */ +typedef struct CTNode { + int child; // úе + struct CTNode* next; // ָһ +} CTNode; + +/* ָӽָ */ +typedef CTNode* ChildPtr; + +/* (˫)Ľ㶨 */ +typedef struct { + int parent; // ˫λ + TElemType data; // ǰ + ChildPtr firstchild; // ͷָ +} CTBox; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} CTree; + + +/* + * ijϢ + * + * ע˫ױ洢ṹҪټǰĵһе + * */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CTree* T, FILE* fp); + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T); + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework(CTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.63/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.63/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.63/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.63/LinkQueue.h b/Dev-C++/ExerciseBook/06.63/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.63/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.63/TestData.txt b/Dev-C++/ExerciseBook/06.63/TestData.txt new file mode 100644 index 0000000..5786a62 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.63/TestData.txt @@ -0,0 +1,12 @@ +λã5 +ֵR +Rĺӽ㣺ABC +Aĺӽ㣺DE +Bĺӽ㣺^ +Cĺӽ㣺F +Dĺӽ㣺^ +Eĺӽ㣺^ +Fĺӽ㣺GHK +Gĺӽ㣺^ +Hĺӽ㣺^ +Kĺӽ㣺^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.64/06.64.cpp b/Dev-C++/ExerciseBook/06.64/06.64.cpp new file mode 100644 index 0000000..2af54e0 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/06.64.cpp @@ -0,0 +1,32 @@ +#include +#include "Status.h" //**01 **// +#include "PTree.h" //**06 Ͷ**// + +/* + * ˫ױʾ + */ +int Algo_6_64(PTree T); + + +int main(int argc, char* argv[]) { + PTree T; + + printf("T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("Ϊ %d\n", Algo_6_64(T)); + printf("\n"); + + return 0; +} + + +/* + * ˫ױʾ + */ +int Algo_6_64(PTree T) { + return TreeDepth(T); // Ѷ +} diff --git a/Dev-C++/ExerciseBook/06.64/06.64.dev b/Dev-C++/ExerciseBook/06.64/06.64.dev new file mode 100644 index 0000000..b288872 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/06.64.dev @@ -0,0 +1,131 @@ +[Project] +FileName=06.64.dev +Name=06.64 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=8 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit6] +FileName=PTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=LinkList.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.64.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=LinkList.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=PTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.64/LinkList.cpp b/Dev-C++/ExerciseBook/06.64/LinkList.cpp new file mode 100644 index 0000000..4774f33 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/LinkList.cpp @@ -0,0 +1,163 @@ +/*=============================== + * Աʽ洢ṹ + * + * 㷨: 2.82.92.102.11 + ================================*/ + +#include "LinkList.h" //**02 Ա**// + +/* + * ʼ + * + * ֻdzʼһͷ㡣 + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(LinkList* L) { + (*L) = (LinkList) malloc(sizeof(LNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + (*L)->next = NULL; + + return OK; +} + +/* + * (ṹ) + * + * ͷռڴ棬ͷҲᱻ + */ +Status DestroyList(LinkList* L) { + LinkList p; + + // ȷṹ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + + while(p != NULL) { + p = (*L)->next; + free(*L); + (*L) = p; + } + + *L = NULL; + + return OK; +} + +/* + * ÿ() + * + * Ҫͷзͷ㴦Ŀռ䡣 + */ +Status ClearList(LinkList L) { + LinkList pre, p; + + // ȷ + if(L == NULL) { + return ERROR; + } + + p = L->next; + + // ͷнռڴ + while(p != NULL) { + pre = p; + p = p->next; + free(pre); + } + + L->next = NULL; + + return OK; +} + +/* + * + * + * ׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + LinkList p; + + // ȷҲΪձ + if(L == NULL || L->next == NULL) { + return 0; + } + + i = 1; // iijֵΪ1Ԫصλ + p = L->next; // pijֵΪ1Ԫصָ + + while(p != NULL && !Compare(p->data, e)) { + i++; + p = p->next; + } + + if(p != NULL) { + return i; + } else { + return 0; + } +} + +/* + * 㷨2.9 + * + * + * + * iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(LinkList L, int i, ElemType e) { + LinkList p, s; + int j; + + // ȷ + if(L == NULL) { + return ERROR; + } + + p = L; + j = 0; + + // Ѱҵi-1㣬ұ֤ý㱾ΪNULL + while(p != NULL && j < i - 1) { + p = p->next; + ++j; + } + + // ͷˣiֵϹ(i<=0)˵ûҵϺĿĽ + if(p == NULL || j > i - 1) { + return ERROR; + } + + // ½ + s = (LinkList) malloc(sizeof(LNode)); + if(s == NULL) { + exit(OVERFLOW); + } + s->data = e; + s->next = p->next; + p->next = s; + + return OK; +} + + +/* */ + +// жԱԪǷ +Status Equal(ElemType e1, ElemType e2) { + return e1 == e2 ? TRUE : FALSE; +} diff --git a/Dev-C++/ExerciseBook/06.64/LinkList.h b/Dev-C++/ExerciseBook/06.64/LinkList.h new file mode 100644 index 0000000..b2fb1fc --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/LinkList.h @@ -0,0 +1,82 @@ +/*=============================== + * Աʽ洢ṹ + * + * 㷨: 2.82.92.102.11 + ================================*/ + +#ifndef LINKLIST_H +#define LINKLIST_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int ElemType; + +/* + * ṹ + * + * עĵͷ + */ +typedef struct LNode { + ElemType data; // ݽ + struct LNode* next; // ָһָ +} LNode; + +// ָָ +typedef LNode* LinkList; + + +/* + * ʼ + * + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(LinkList* L); + +/* + * (ṹ) + * + * ͷռڴ档 + */ +Status DestroyList(LinkList* L); + +/* + * ÿ() + * + * Ҫͷзͷ㴦Ŀռ䡣 + */ +Status ClearList(LinkList L); + +/* + * + * + * ׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * 㷨2.9 + * + * + * + * iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(LinkList L, int i, ElemType e); + + +/* */ + +// жԱԪǷ +Status Equal(ElemType e1, ElemType e2); + +#endif diff --git a/Dev-C++/ExerciseBook/06.64/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.64/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.64/LinkQueue.h b/Dev-C++/ExerciseBook/06.64/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.64/PTree.cpp b/Dev-C++/ExerciseBook/06.64/PTree.cpp new file mode 100644 index 0000000..69fd054 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/PTree.cpp @@ -0,0 +1,348 @@ +/*================== + * ˫ױ洢ʾ + ===================*/ + +#include "PTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(PTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(PTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("ԪϢڿս㣬ʹ^...\n"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(PTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(PTree T) { + int k, level; + + // + if(TreeEmpty(T)) { + return 0; + } + + /* + * kʼΪһλ + * Ľ㰴洢洢Ľضλ + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(PTree* T, FILE* fp) { + int r; // ĸλã + int n; // ¼Ԫ + int cur; // α + TElemType ch; + LinkQueue Q; + QElemType e; // Ԫָʾλ + char s[MAX_CHILD_COUNT + 1]; + int i; + + InitQueue(&Q); + + n = 0; + + // ȡλ + if(fp == NULL) { + printf("λ(0~%d)", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("ֵ"); + scanf("%s", s); + ch = s[0]; + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // λó + + printf(" %c ĺӽ㣬ںʱһ^", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // ¼λ + ReadData(fp, "%d", &r); + cur = r; + + // ¼ֵ + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ֵ%c\n", ch); + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ %c ĺӣ", ch); + + // ¼뺢ӽ + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // λó + + // + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(PTree T, Pos pt[]) { + LinkList Lt, Lt_parent, Lt_child; + int m, n, p, k, s; + int level; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty(T)) { + return; + } + + InitList(&Lt_parent); + InitList(&Lt_child); + + // parentΪ-1 + ListInsert(Lt_parent, 1, -1); + + level = 1; + k = T.r; + m = n = 0; + s = -1; // ʼͷĸΪ-1 + + while(k != (T.r + T.n) % MAX_TREE_SIZE) { + // kһеʼΪ-1 + pt[k].firstChild = -1; + + // kһеʼΪ-1 + pt[k].lastChild = -1; + + // ǰkĸ + p = T.nodes[k].parent; + if(p != s) { + s = p; // ׷ٸı仯 + n = 0; // ıʱҪ¼ + } + + // жϵǰǷΪlevel-1ĺ + if(LocateElem(Lt_parent, p, Equal)) { + ListInsert(Lt_child, ++m, k); + + pt[k].row = level; + pt[k].col = m; + pt[k].childIndex = ++n; + + // ȷǰ㸸 + if(p != -1) { + // һе + if(pt[p].firstChild==-1) { + pt[p].firstChild = k; + } + + // һе + pt[p].lastChild = k; + } + + k = (k + 1) % MAX_TREE_SIZE; + } else { + Lt = Lt_parent; + Lt_parent = Lt_child; + Lt_child = Lt; + ClearList(Lt_child); + + level++; + m = 0; + } + } + + DestroyList(&Lt_parent); + DestroyList(&Lt_child); +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(PTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework(T); +} + +// ͼλǰṹڲʵ +static void Print(PTree T, Pos pt[], int i) { + int firstChild; + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + firstChild = pt[i].firstChild; + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework(PTree T) { + int k; + + if(T.n == 0) { + printf("\n"); + return; + } + + printf("+---------+\n"); + printf("| i e p |\n"); + printf("+---------+\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + printf("| %2d %c %2d |\n", k, T.nodes[k].data, T.nodes[k].parent); + } + + printf("+---------+\n"); +} diff --git a/Dev-C++/ExerciseBook/06.64/PTree.h b/Dev-C++/ExerciseBook/06.64/PTree.h new file mode 100644 index 0000000..c47c6ed --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/PTree.h @@ -0,0 +1,117 @@ +/*================== + * ˫ױ洢ʾ + ===================*/ + +#ifndef PTREE_H +#define PTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkList.h" //**02 Ա**// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (˫)Ľ㶨 */ +typedef struct PTNode { + TElemType data; + int parent; // ˫λ +} PTNode; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + PTNode nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} PTree; + + +/* ijϢ */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int firstChild; // ǰĵһе + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree(PTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(PTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(PTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(PTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(PTree* T, FILE* fp); + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(PTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(PTree T); + +// ͼλǰṹڲʵ +static void Print(PTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework(PTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.64/TestData.txt b/Dev-C++/ExerciseBook/06.64/TestData.txt new file mode 100644 index 0000000..5786a62 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.64/TestData.txt @@ -0,0 +1,12 @@ +λã5 +ֵR +Rĺӽ㣺ABC +Aĺӽ㣺DE +Bĺӽ㣺^ +Cĺӽ㣺F +Dĺӽ㣺^ +Eĺӽ㣺^ +Fĺӽ㣺GHK +Gĺӽ㣺^ +Hĺӽ㣺^ +Kĺӽ㣺^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.65/06.65.cpp b/Dev-C++/ExerciseBook/06.65/06.65.cpp new file mode 100644 index 0000000..58c798b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.65/06.65.cpp @@ -0,0 +1,85 @@ +#include +#include // ṩstrlenԭ +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ȫֱ */ +char Pre[] = "ABDGEHICFJ"; // ǰ +char In[] = "GDBHEIAFJC"; // + +/* + * ǰкй + */ +Status Algo_6_65(BiTree* T); + +// ڲʵ +BiTree BuildTree(int pre_start, int pre_end, int in_start, int in_end); //ݹ鴴 + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("Ϊ%s\n", Pre); + printf("Ϊ%s\n", In); + printf("\n"); + + printf("ɴ˹ĶΪ T = \n"); + Algo_6_65(&T); + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * ǰкй + */ +Status Algo_6_65(BiTree* T) { + int len_pre, len_in; + + len_pre = strlen(Pre); + len_in = strlen(In); + + if(len_pre == 0 || len_in == 0 || len_pre != len_in) { + return ERROR; + } + + *T = BuildTree(0, len_pre - 1, 0, len_in - 1); + + return OK; +} + +// ڲʵ +BiTree BuildTree(int pre_start, int pre_end, int in_start, int in_end) { + BiTree T; + int i, LTreeLen, RTreeLen; + + T = (BiTree) malloc(sizeof(BiTNode)); // + if(T == NULL) { + exit(OVERFLOW); + } + T->data = Pre[pre_start]; // ǰ洢Ľ + T->lchild = T->rchild = NULL; // ʼʱÿҺָ + + i = in_start; + while(In[i] != T->data) { // ѰҸλ + i++; + } + + LTreeLen = i - in_start; // + RTreeLen = in_end - i; // + + // + if(LTreeLen) { + T->lchild = BuildTree(pre_start + 1, pre_start + LTreeLen, in_start, i - 1); + } + + // + if(RTreeLen) { + T->rchild = BuildTree(pre_start + LTreeLen + 1, pre_end, i + 1, in_end); + } + + return T; +} diff --git a/Dev-C++/ExerciseBook/06.65/06.65.dev b/Dev-C++/ExerciseBook/06.65/06.65.dev new file mode 100644 index 0000000..387e821 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.65/06.65.dev @@ -0,0 +1,102 @@ +[Project] +FileName=06.65.dev +Name=06.65 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=06.65.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.65/BiTree.cpp b/Dev-C++/ExerciseBook/06.65/BiTree.cpp new file mode 100644 index 0000000..76327ed --- /dev/null +++ b/Dev-C++/ExerciseBook/06.65/BiTree.cpp @@ -0,0 +1,121 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.65/BiTree.h b/Dev-C++/ExerciseBook/06.65/BiTree.h new file mode 100644 index 0000000..d53885f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.65/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.65/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.65/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.65/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.65/LinkQueue.h b/Dev-C++/ExerciseBook/06.65/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.65/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.66/06.66.cpp b/Dev-C++/ExerciseBook/06.66/06.66.cpp new file mode 100644 index 0000000..df12be3 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/06.66.cpp @@ -0,0 +1,74 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "PTree.h" //**06 Ͷ**// +#include "CSTree.h" //**06 Ͷ**// + +/* + * ˫ױʾתΪĺ-ֵܱʾ + */ +CSTree Algo_6_66(PTree T); + + +int main(int argc, char* argv[]) { + PTree PT; + CSTree CST; + + printf("T...\n"); + InitTree_P(&PT); + CreateTree_P(&PT, "TestData.txt"); + PrintGraph_P(PT); + printf("\n"); + + printf("˫ױʾתΪĺ-ֵܱʾ\n"); + CST = Algo_6_66(PT); + PrintGraph_CS(CST); + printf("\n"); + + return 0; +} + + +/* + * ˫ױʾתΪĺ-ֵܱʾ + */ +CSTree Algo_6_66(PTree T) { + CSTree p, q; + CSTree tree[MAX_TREE_SIZE] = {NULL}; + int i, j, k; + + // ˫ױ洢 + for(i = T.r, j = T.r; i != (T.r + T.n) % MAX_TREE_SIZE; i = (i + 1) % MAX_TREE_SIZE) { + // ȡýĸ + k = T.nodes[i].parent; + + // ƽϢ + p = (CSTree) malloc(sizeof(CSNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->data = T.nodes[i].data; + p->firstchild = p->nextsibling = NULL; + + // ǰڸ + if(k != -1) { + // ǰΪ˵һ + if(tree[k]->firstchild == NULL) { + tree[k]->firstchild = p; + + // ǰ㲻ǵһӣȲ丸ĺβ + } else { + for(q = tree[k]->firstchild; q->nextsibling != NULL; q = q->nextsibling) { + // ѰҺĩ + } + + q->nextsibling = p; + } + } + + tree[j] = p; + j = (j + 1) % MAX_TREE_SIZE; + } + + return tree[T.r]; +} diff --git a/Dev-C++/ExerciseBook/06.66/06.66.dev b/Dev-C++/ExerciseBook/06.66/06.66.dev new file mode 100644 index 0000000..9cdff2f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/06.66.dev @@ -0,0 +1,151 @@ +[Project] +FileName=06.66.dev +Name=06.66 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=10 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit8] +FileName=PTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=LinkList.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=CSTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.66.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CSTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkList.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=PTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.66/CSTree.cpp b/Dev-C++/ExerciseBook/06.66/CSTree.cpp new file mode 100644 index 0000000..a121656 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/CSTree.cpp @@ -0,0 +1,67 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree_CS(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty_CS(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// ͼλʽǰṹ +void PrintGraph_CS(CSTree T) { + + // + if(TreeEmpty_CS(T)) { + printf("\n"); + return; + } + + Print_CS(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print_CS(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print_CS(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print_CS(T->nextsibling, row); + } +} diff --git a/Dev-C++/ExerciseBook/06.66/CSTree.h b/Dev-C++/ExerciseBook/06.66/CSTree.h new file mode 100644 index 0000000..2899652 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree_CS(CSTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty_CS(CSTree T); + +// ͼλʽǰṹ +void PrintGraph_CS(CSTree T); + +// ͼλǰṹڲʵ +static void Print_CS(CSTree T, int row); + +#endif diff --git a/Dev-C++/ExerciseBook/06.66/LinkList.cpp b/Dev-C++/ExerciseBook/06.66/LinkList.cpp new file mode 100644 index 0000000..4774f33 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/LinkList.cpp @@ -0,0 +1,163 @@ +/*=============================== + * Աʽ洢ṹ + * + * 㷨: 2.82.92.102.11 + ================================*/ + +#include "LinkList.h" //**02 Ա**// + +/* + * ʼ + * + * ֻdzʼһͷ㡣 + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(LinkList* L) { + (*L) = (LinkList) malloc(sizeof(LNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + (*L)->next = NULL; + + return OK; +} + +/* + * (ṹ) + * + * ͷռڴ棬ͷҲᱻ + */ +Status DestroyList(LinkList* L) { + LinkList p; + + // ȷṹ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + + while(p != NULL) { + p = (*L)->next; + free(*L); + (*L) = p; + } + + *L = NULL; + + return OK; +} + +/* + * ÿ() + * + * Ҫͷзͷ㴦Ŀռ䡣 + */ +Status ClearList(LinkList L) { + LinkList pre, p; + + // ȷ + if(L == NULL) { + return ERROR; + } + + p = L->next; + + // ͷнռڴ + while(p != NULL) { + pre = p; + p = p->next; + free(pre); + } + + L->next = NULL; + + return OK; +} + +/* + * + * + * ׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + LinkList p; + + // ȷҲΪձ + if(L == NULL || L->next == NULL) { + return 0; + } + + i = 1; // iijֵΪ1Ԫصλ + p = L->next; // pijֵΪ1Ԫصָ + + while(p != NULL && !Compare(p->data, e)) { + i++; + p = p->next; + } + + if(p != NULL) { + return i; + } else { + return 0; + } +} + +/* + * 㷨2.9 + * + * + * + * iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(LinkList L, int i, ElemType e) { + LinkList p, s; + int j; + + // ȷ + if(L == NULL) { + return ERROR; + } + + p = L; + j = 0; + + // Ѱҵi-1㣬ұ֤ý㱾ΪNULL + while(p != NULL && j < i - 1) { + p = p->next; + ++j; + } + + // ͷˣiֵϹ(i<=0)˵ûҵϺĿĽ + if(p == NULL || j > i - 1) { + return ERROR; + } + + // ½ + s = (LinkList) malloc(sizeof(LNode)); + if(s == NULL) { + exit(OVERFLOW); + } + s->data = e; + s->next = p->next; + p->next = s; + + return OK; +} + + +/* */ + +// жԱԪǷ +Status Equal(ElemType e1, ElemType e2) { + return e1 == e2 ? TRUE : FALSE; +} diff --git a/Dev-C++/ExerciseBook/06.66/LinkList.h b/Dev-C++/ExerciseBook/06.66/LinkList.h new file mode 100644 index 0000000..b2fb1fc --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/LinkList.h @@ -0,0 +1,82 @@ +/*=============================== + * Աʽ洢ṹ + * + * 㷨: 2.82.92.102.11 + ================================*/ + +#ifndef LINKLIST_H +#define LINKLIST_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int ElemType; + +/* + * ṹ + * + * עĵͷ + */ +typedef struct LNode { + ElemType data; // ݽ + struct LNode* next; // ָһָ +} LNode; + +// ָָ +typedef LNode* LinkList; + + +/* + * ʼ + * + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(LinkList* L); + +/* + * (ṹ) + * + * ͷռڴ档 + */ +Status DestroyList(LinkList* L); + +/* + * ÿ() + * + * Ҫͷзͷ㴦Ŀռ䡣 + */ +Status ClearList(LinkList L); + +/* + * + * + * ׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * 㷨2.9 + * + * + * + * iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(LinkList L, int i, ElemType e); + + +/* */ + +// жԱԪǷ +Status Equal(ElemType e1, ElemType e2); + +#endif diff --git a/Dev-C++/ExerciseBook/06.66/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.66/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.66/LinkQueue.h b/Dev-C++/ExerciseBook/06.66/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.66/PTree.cpp b/Dev-C++/ExerciseBook/06.66/PTree.cpp new file mode 100644 index 0000000..9ea6921 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/PTree.cpp @@ -0,0 +1,320 @@ +/*================== + * ˫ױ洢ʾ + ===================*/ + +#include "PTree.h" + +/* + * ʼ + * + * + */ +Status InitTree_P(PTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree_P(PTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("ԪϢڿս㣬ʹ^...\n"); + Create_P(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create_P(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty_P(PTree T) { + return T.n == 0 ? TRUE : FALSE; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create_P(PTree* T, FILE* fp) { + int r; // ĸλã + int n; // ¼Ԫ + int cur; // α + TElemType ch; + LinkQueue Q; + QElemType e; // Ԫָʾλ + char s[MAX_CHILD_COUNT + 1]; + int i; + + InitQueue(&Q); + + n = 0; + + // ȡλ + if(fp == NULL) { + printf("λ(0~%d)", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("ֵ"); + scanf("%s", s); + ch = s[0]; + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // λó + + printf(" %c ĺӽ㣬ںʱһ^", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // ¼λ + ReadData(fp, "%d", &r); + cur = r; + + // ¼ֵ + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ֵ%c\n", ch); + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ %c ĺӣ", ch); + + // ¼뺢ӽ + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // λó + + // + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// ȡTĽϢЩϢPos͵Ķ +static void getPos_P(PTree T, Pos pt[]) { + LinkList Lt, Lt_parent, Lt_child; + int m, n, p, k, s; + int level; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty_P(T)) { + return; + } + + InitList(&Lt_parent); + InitList(&Lt_child); + + // parentΪ-1 + ListInsert(Lt_parent, 1, -1); + + level = 1; + k = T.r; + m = n = 0; + s = -1; // ʼͷĸΪ-1 + + while(k != (T.r + T.n) % MAX_TREE_SIZE) { + // kһеʼΪ-1 + pt[k].firstChild = -1; + + // kһеʼΪ-1 + pt[k].lastChild = -1; + + // ǰkĸ + p = T.nodes[k].parent; + if(p != s) { + s = p; // ׷ٸı仯 + n = 0; // ıʱҪ¼ + } + + // жϵǰǷΪlevel-1ĺ + if(LocateElem(Lt_parent, p, Equal)) { + ListInsert(Lt_child, ++m, k); + + pt[k].row = level; + pt[k].col = m; + pt[k].childIndex = ++n; + + // ȷǰ㸸 + if(p != -1) { + // һе + if(pt[p].firstChild==-1) { + pt[p].firstChild = k; + } + + // һе + pt[p].lastChild = k; + } + + k = (k + 1) % MAX_TREE_SIZE; + } else { + Lt = Lt_parent; + Lt_parent = Lt_child; + Lt_child = Lt; + ClearList(Lt_child); + + level++; + m = 0; + } + } + + DestroyList(&Lt_parent); + DestroyList(&Lt_child); +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph_P(PTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty_P(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos_P(T, pt); + + Print_P(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework_P(T); +} + +// ͼλǰṹڲʵ +static void Print_P(PTree T, Pos pt[], int i) { + int firstChild; + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + firstChild = pt[i].firstChild; + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print_P(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print_P(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework_P(PTree T) { + int k; + + if(T.n == 0) { + printf("\n"); + return; + } + + printf("+---------+\n"); + printf("| i e p |\n"); + printf("+---------+\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + printf("| %2d %c %2d |\n", k, T.nodes[k].data, T.nodes[k].parent); + } + + printf("+---------+\n"); +} diff --git a/Dev-C++/ExerciseBook/06.66/PTree.h b/Dev-C++/ExerciseBook/06.66/PTree.h new file mode 100644 index 0000000..9bf3676 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/PTree.h @@ -0,0 +1,110 @@ +/*================== + * ˫ױ洢ʾ + ===================*/ + +#ifndef PTREE_H +#define PTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkList.h" //**02 Ա**// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (˫)Ľ㶨 */ +typedef struct PTNode { + TElemType data; + int parent; // ˫λ +} PTNode; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + PTNode nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} PTree; + + +/* ijϢ */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int firstChild; // ǰĵһе + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree_P(PTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree_P(PTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty_P(PTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create_P(PTree* T, FILE* fp); + +// ȡTĽϢЩϢPos͵Ķ +static void getPos_P(PTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph_P(PTree T); + +// ͼλǰṹڲʵ +static void Print_P(PTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework_P(PTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.66/TestData.txt b/Dev-C++/ExerciseBook/06.66/TestData.txt new file mode 100644 index 0000000..5786a62 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.66/TestData.txt @@ -0,0 +1,12 @@ +λã5 +ֵR +Rĺӽ㣺ABC +Aĺӽ㣺DE +Bĺӽ㣺^ +Cĺӽ㣺F +Dĺӽ㣺^ +Eĺӽ㣺^ +Fĺӽ㣺GHK +Gĺӽ㣺^ +Hĺӽ㣺^ +Kĺӽ㣺^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.67/06.67.cpp b/Dev-C++/ExerciseBook/06.67/06.67.cpp new file mode 100644 index 0000000..e971e1c --- /dev/null +++ b/Dev-C++/ExerciseBook/06.67/06.67.cpp @@ -0,0 +1,84 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ĺ-ֵܽṹ + */ +Status Algo_6_67(CSTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf("-ֵܶ\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_67(&T, fp); + fclose(fp); + printf("\n"); + + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * ĺ-ֵܽṹ + */ +Status Algo_6_67(CSTree* T, FILE* fp) { + char input[3]; + CSTree tree[MAX_TREE_SIZE]; // ˳洢ÿ + CSTree p, q; + int m, n, count; + + m = n = 0; + count = 0; + + while(TRUE) { + printf("¼ %2d Ԫ飺", ++count); + ReadData(fp, "%s", input); + printf("%s\n", input); + + // ˳־ + if(input[1] == '^') { + return OK; + } + + p = (CSTree) malloc(sizeof(CSNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->data = input[1]; // ǰϢ + p->firstchild = p->nextsibling = NULL; + + // + if(input[0] == '^') { + *T = p; + } else { + // Ҹtreeеλ + while(tree[m]->data != input[0]) { + m++; + } + + // ǰΪһ + if(tree[m]->firstchild == NULL) { + tree[m]->firstchild = p; + } else { + for(q = tree[m]->firstchild; q->nextsibling != NULL; q = q->nextsibling) { + // ѰҺĩ + } + + // 뵱ǰ + q->nextsibling = p; + } + } + + tree[n++] = p; + } +} diff --git a/Dev-C++/ExerciseBook/06.67/06.67.dev b/Dev-C++/ExerciseBook/06.67/06.67.dev new file mode 100644 index 0000000..42e0908 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.67/06.67.dev @@ -0,0 +1,91 @@ +[Project] +FileName=06.67.dev +Name=06.67 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=4 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=CSTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.67.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CSTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.67/CSTree.cpp b/Dev-C++/ExerciseBook/06.67/CSTree.cpp new file mode 100644 index 0000000..323fd9b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.67/CSTree.cpp @@ -0,0 +1,67 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/Dev-C++/ExerciseBook/06.67/CSTree.h b/Dev-C++/ExerciseBook/06.67/CSTree.h new file mode 100644 index 0000000..8c3b490 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.67/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/Dev-C++/ExerciseBook/06.67/TestData.txt b/Dev-C++/ExerciseBook/06.67/TestData.txt new file mode 100644 index 0000000..3804274 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.67/TestData.txt @@ -0,0 +1,7 @@ +^A +AB +AC +AD +CE +CF +^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.68/06.68.cpp b/Dev-C++/ExerciseBook/06.68/06.68.cpp new file mode 100644 index 0000000..116a90b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.68/06.68.cpp @@ -0,0 +1,97 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ĺ-ֵܽṹ + */ +Status Algo_6_68(CSTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf("-ֵܶ\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_68(&T, fp); + fclose(fp); + printf("\n"); + + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * ĺ-ֵܽṹ + */ +Status Algo_6_68(CSTree* T, FILE* fp) { + CSTree queue[MAX_TREE_SIZE] = {NULL}; // 洢Ľ + int d[MAX_TREE_SIZE]; // 洢ýĶ + int parent[MAX_TREE_SIZE]; // 洢ýĸϢ + CSTree p; + int x; + char ch; + int m, n; + int i; + + d[0] = 1; + + for(m = 0, n = 1; m < n; m++) { + p = NULL; + i = 0; + + while(i < d[m]) { + // б + ch = getc(fp); + if(ch == '\n' || ch == '\r') { + continue; + } else { + ungetc(ch, fp); + } + + // ȡϢ + ReadData(fp, "%c%d", &ch, &x); + printf("%c %d\n", ch, x); + if(x < 0) { + return ERROR; + } + + d[n] = x; + parent[n] = m; + + // ½ + queue[n] = (CSTree) malloc(sizeof(CSNode)); + if(queue[n] == NULL) { + exit(OVERFLOW); + } + queue[n]->data = ch; + queue[n]->firstchild = queue[n]->nextsibling = NULL; + + // ׷ٸò׸ + if(p == NULL) { + p = queue[n]; + } else { + // ӽ㴮һ + queue[n - 1]->nextsibling = queue[n]; + } + + n++; + i++; + } + + if(m > 0 && queue[m]->firstchild == NULL) { + queue[m]->firstchild = p; + } + } + + *T = queue[1]; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/06.68/06.68.dev b/Dev-C++/ExerciseBook/06.68/06.68.dev new file mode 100644 index 0000000..cfd8599 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.68/06.68.dev @@ -0,0 +1,91 @@ +[Project] +FileName=06.68.dev +Name=06.68 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=4 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=CSTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.68.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CSTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.68/CSTree.cpp b/Dev-C++/ExerciseBook/06.68/CSTree.cpp new file mode 100644 index 0000000..323fd9b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.68/CSTree.cpp @@ -0,0 +1,67 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/Dev-C++/ExerciseBook/06.68/CSTree.h b/Dev-C++/ExerciseBook/06.68/CSTree.h new file mode 100644 index 0000000..8c3b490 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.68/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/Dev-C++/ExerciseBook/06.68/TestData.txt b/Dev-C++/ExerciseBook/06.68/TestData.txt new file mode 100644 index 0000000..15fc534 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.68/TestData.txt @@ -0,0 +1,10 @@ +R 3 +A 2 +B 0 +C 1 +D 0 +E 0 +F 3 +G 0 +H 0 +K 0 \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.69/06.69.cpp b/Dev-C++/ExerciseBook/06.69/06.69.cpp new file mode 100644 index 0000000..856bd29 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.69/06.69.cpp @@ -0,0 +1,45 @@ +#include +#include "BiTree.h" //**06 Ͷ**// + +/* + * Ұӡ + * iԸ˼˲Ϣ + */ +void Algo_6_69(BiTree T, int i); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("Ұӡ\n"); + Algo_6_69(T, 0); + printf("\n"); + + return 0; +} + + +/* + * Ұӡ + * iԸ˼˲Ϣ + */ +void Algo_6_69(BiTree T, int i) { + int j; + + if(T) { + Algo_6_69(T->rchild, i + 1); // ȷ + + for(j = 1; j <= 2 * i; j++) { // i2ΪЧۣʵʿո + printf(" "); + } + printf("%c\n", T->data); + + Algo_6_69(T->lchild, i + 1); // + } +} diff --git a/Dev-C++/ExerciseBook/06.69/06.69.dev b/Dev-C++/ExerciseBook/06.69/06.69.dev new file mode 100644 index 0000000..3479139 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.69/06.69.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.69.dev +Name=06.69 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.69.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.69/BiTree.cpp b/Dev-C++/ExerciseBook/06.69/BiTree.cpp new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.69/BiTree.cpp @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.69/BiTree.h b/Dev-C++/ExerciseBook/06.69/BiTree.h new file mode 100644 index 0000000..425dfa1 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.69/BiTree.h @@ -0,0 +1,92 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ + + int DescNum; // ý +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.69/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.69/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.69/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.69/LinkQueue.h b/Dev-C++/ExerciseBook/06.69/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.69/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.69/TestData.txt b/Dev-C++/ExerciseBook/06.69/TestData.txt new file mode 100644 index 0000000..de785cc --- /dev/null +++ b/Dev-C++/ExerciseBook/06.69/TestData.txt @@ -0,0 +1 @@ +СAB^D^^CE^F^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.70/06.70.cpp b/Dev-C++/ExerciseBook/06.70/06.70.cpp new file mode 100644 index 0000000..8eb0c29 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.70/06.70.cpp @@ -0,0 +1,58 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* + * Ķṹ + */ +Status Algo_6_70(BiTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + BiTree T; + FILE* fp; + + printf("T...\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_70(&T, fp); + fclose(fp); + PrintGraph(T); + + return 0; +} + + +/* + * Ķṹ + */ +Status Algo_6_70(BiTree* T, FILE* fp) { + char c; + + while(TRUE) { + // ַȡ + if(feof(fp)!=0) { + return OK; + } + + ReadData(fp, "%c", &c); + + if(c == '#') { + *T = NULL; + } else if(c >= 'A' && c <= 'Z') { + *T = (BiTree) malloc(sizeof(BiTNode)); // + if(*T==NULL) { + exit(OVERFLOW); + } + (*T)->data = c; + (*T)->lchild = (*T)->rchild = NULL; + } else if(c == '(') { + Algo_6_70(&(*T)->lchild, fp); + Algo_6_70(&(*T)->rchild, fp); + } else { + break; + } + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/06.70/06.70.dev b/Dev-C++/ExerciseBook/06.70/06.70.dev new file mode 100644 index 0000000..d7228ad --- /dev/null +++ b/Dev-C++/ExerciseBook/06.70/06.70.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.70.dev +Name=06.70 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=BiTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.70.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=BiTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.70/BiTree.cpp b/Dev-C++/ExerciseBook/06.70/BiTree.cpp new file mode 100644 index 0000000..76327ed --- /dev/null +++ b/Dev-C++/ExerciseBook/06.70/BiTree.cpp @@ -0,0 +1,121 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/06.70/BiTree.h b/Dev-C++/ExerciseBook/06.70/BiTree.h new file mode 100644 index 0000000..d53885f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.70/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.70/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.70/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.70/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.70/LinkQueue.h b/Dev-C++/ExerciseBook/06.70/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.70/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.70/TestData.txt b/Dev-C++/ExerciseBook/06.70/TestData.txt new file mode 100644 index 0000000..1c5af96 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.70/TestData.txt @@ -0,0 +1 @@ +A(B(#,D),C(E(#,F),#)) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.71/06.71.cpp b/Dev-C++/ExerciseBook/06.71/06.71.cpp new file mode 100644 index 0000000..4ca6545 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.71/06.71.cpp @@ -0,0 +1,80 @@ +#include +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +/* + * ӡ + * 1ֱʹõݹ飬iʼΪ0 + */ +void Algo_6_71_1(CSTree T, int i); + +/* + * ӡ + * 2ѭʹõݹ飬iʼΪ0 + */ +void Algo_6_71_2(CSTree T, int i); + + +int main(int argc, char* argv[]) { + CSTree T; + + printf("УT...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf(" 1ӡ\n"); + Algo_6_71_1(T, 0); + printf("\n"); + + printf(" 2ӡ\n"); + Algo_6_71_2(T, 0); + printf("\n"); + + return 0; +} + + +/* + * ӡ + * 1ֱʹõݹ飬iʼΪ0 + */ +void Algo_6_71_1(CSTree T, int i) { + int j; + + if(!T) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T->data); + + Algo_6_71_1(T->firstchild, i + 1); + Algo_6_71_1(T->nextsibling, i); // ˴Ϊi +} + +/* + * ӡ + * 2ѭʹõݹ飬iʼΪ0 + */ +void Algo_6_71_2(CSTree T, int i) { + int j; + CSTree p; + + if(!T) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T->data); + + // ӽ + for(p = T->firstchild; p; p = p->nextsibling) { + Algo_6_71_2(p, i + 1); + } +} diff --git a/Dev-C++/ExerciseBook/06.71/06.71.dev b/Dev-C++/ExerciseBook/06.71/06.71.dev new file mode 100644 index 0000000..9f94f03 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.71/06.71.dev @@ -0,0 +1,91 @@ +[Project] +FileName=06.71.dev +Name=06.71 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=4 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=CSTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.71.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CSTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.71/CSTree.cpp b/Dev-C++/ExerciseBook/06.71/CSTree.cpp new file mode 100644 index 0000000..64d258f --- /dev/null +++ b/Dev-C++/ExerciseBook/06.71/CSTree.cpp @@ -0,0 +1,166 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CSTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûкӽûֵܽڵ㣬ʹ^棺"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CSTree T) { + int max = 0; + + Depth(T, 0, &max); + + return max; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CSTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (CSTree) malloc(sizeof(CSNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + Create(&((*T)->firstchild), fp); // + Create(&((*T)->nextsibling), fp); // ֵ + } +} + +// ȵڲʵ +static void Depth(CSTree T, int d, int* max) { + if(T == NULL) { + return; + } + + d++; // ָʾǰڵIJ + + if(d > *max) { + *max = d; + } + + Depth(T->firstchild, d, max); // ± + Depth(T->nextsibling, --d, max); // ұ +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/Dev-C++/ExerciseBook/06.71/CSTree.h b/Dev-C++/ExerciseBook/06.71/CSTree.h new file mode 100644 index 0000000..3d95beb --- /dev/null +++ b/Dev-C++/ExerciseBook/06.71/CSTree.h @@ -0,0 +1,87 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CSTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CSTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CSTree* T, FILE* fp); + +// ȵڲʵ +static void Depth(CSTree T, int d, int *max); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/Dev-C++/ExerciseBook/06.71/TestData.txt b/Dev-C++/ExerciseBook/06.71/TestData.txt new file mode 100644 index 0000000..24661d5 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.71/TestData.txt @@ -0,0 +1 @@ +ABE^F^^CG^^D^^^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.72/06.72.cpp b/Dev-C++/ExerciseBook/06.72/06.72.cpp new file mode 100644 index 0000000..6933c36 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.72/06.72.cpp @@ -0,0 +1,91 @@ +#include +#include "Status.h" //**01 **// +#include "CTree.h" //**06 Ͷ**// + +/* + * ӡ + * 1ֱʹõݹ飬iʼΪ0 + */ +void Algo_6_72_1(CTree T, int order, int i); + +/* + * ӡ + * 2ѭʹõݹ飬iʼΪ0 + */ +void Algo_6_72_2(CTree T, int order, int i); + + +int main(int argc, char* argv[]) { + CTree T; + + printf("T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("ӡ\n"); + Algo_6_72_1(T, T.r, 0); + printf("\n"); + + printf("ӡ\n"); + Algo_6_72_2(T, T.r, 0); + printf("\n"); + + return 0; +} + + +/* + * ӡ + * 1ֱʹõݹ飬iʼΪ0 + */ +void Algo_6_72_1(CTree T, int order, int i) { + int j, k; + + if(!T.n) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T.nodes[order].data); + + // ʺӽ + if(T.nodes[order].firstchild) { + Algo_6_72_1(T, T.nodes[order].firstchild->child, i + 1); + } + + // ȡorderҽλ + k = (order + 1) % MAX_TREE_SIZE; + + // ֵ + if(T.nodes[order].parent == T.nodes[k].parent) { + // ֵܽ + Algo_6_72_1(T, k, i); + } +} + +/* + * ӡ + * 2ѭʹõݹ飬iʼΪ0 + */ +void Algo_6_72_2(CTree T, int order, int i) { + int j; + ChildPtr p; + + if(!T.n) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T.nodes[order].data); + + // ӽ + for(p = T.nodes[order].firstchild; p; p = p->next) { + Algo_6_72_2(T, p->child, i + 1); + } +} diff --git a/Dev-C++/ExerciseBook/06.72/06.72.dev b/Dev-C++/ExerciseBook/06.72/06.72.dev new file mode 100644 index 0000000..e5bc7c6 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.72/06.72.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.72.dev +Name=06.72 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=CTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.72.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.72/CTree.cpp b/Dev-C++/ExerciseBook/06.72/CTree.cpp new file mode 100644 index 0000000..d2c194a --- /dev/null +++ b/Dev-C++/ExerciseBook/06.72/CTree.cpp @@ -0,0 +1,405 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#include "CTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("ԪϢڿս㣬ʹ^...\n"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T) { + int k, level; + + // + if(TreeEmpty(T)) { + return 0; + } + + /* + * kʼΪһλ + * Ľ㰴洢洢Ľضλ + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CTree* T, FILE* fp) { + int r; // ĸλã + int n; // ¼Ԫ + int cur; // α + TElemType ch; + LinkQueue Q; + QElemType e; // Ԫָʾλ + char s[MAX_CHILD_COUNT + 1]; + int i; + ChildPtr p, pc; + + InitQueue(&Q); + + n = 0; + + // ȡλ + if(fp == NULL) { + printf("λ(0~%d)", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("ֵ"); + scanf("%s", s); + ch = s[0]; + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // λó + + printf(" %c ĺӽ㣬ںʱһ^", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // ij + p = T->nodes[e].firstchild; + + // װǰ + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // ǰӵĺ + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // ҵβ + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // ¼λ + ReadData(fp, "%d", &r); + cur = r; + + // ¼ֵ + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ֵ%c\n", ch); + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ %c ĺӣ", ch); + + // ¼뺢ӽ + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // λó + + // + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // װǰ + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // ij + p = T->nodes[e].firstchild; + + // ǰӵĺ + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // ҵβ + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // λ + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // ڵIJ + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // ˸ı + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // eĺӼ0 + + // ÿʱһϢΪЧΪÿ㶼кӽ + pt[e].lastChild = -1; + + // ָýĺ + cp = T.nodes[e].firstchild; + + // ͷŸý㴦ĺռڴ + while(cp != NULL) { + // ǰλ + EnQueue(&Q, cp->child); + + // ¼ + pt[cp->child].row = pt[e].row + 1; + + // ¼ + pt[cp->child].col = ++count; + + // ¼ǰǵڼ + pt[cp->child].childIndex = ++n; + + // ΪһӵϢ + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework(T); +} + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // ʼΪЧ + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + // ˫ױ洢ṹӸ + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/Dev-C++/ExerciseBook/06.72/CTree.h b/Dev-C++/ExerciseBook/06.72/CTree.h new file mode 100644 index 0000000..873504b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.72/CTree.h @@ -0,0 +1,129 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* ӽ㶨 */ +typedef struct CTNode { + int child; // úе + struct CTNode* next; // ָһ +} CTNode; + +/* ָӽָ */ +typedef CTNode* ChildPtr; + +/* (˫)Ľ㶨 */ +typedef struct { + int parent; // ˫λ + TElemType data; // ǰ + ChildPtr firstchild; // ͷָ +} CTBox; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} CTree; + + +/* + * ijϢ + * + * ע˫ױ洢ṹҪټǰĵһе + * */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CTree* T, FILE* fp); + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T); + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework(CTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.72/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.72/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.72/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.72/LinkQueue.h b/Dev-C++/ExerciseBook/06.72/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.72/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.72/TestData.txt b/Dev-C++/ExerciseBook/06.72/TestData.txt new file mode 100644 index 0000000..054a1ad --- /dev/null +++ b/Dev-C++/ExerciseBook/06.72/TestData.txt @@ -0,0 +1,9 @@ +λã5 +ֵA +Aĺӽ㣺BCD +Bĺӽ㣺EF +Cĺӽ㣺G +Dĺӽ㣺^ +Eĺӽ㣺^ +Fĺӽ㣺^ +Gĺӽ㣺^ \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.73-06.74/06.73-06.74.cpp b/Dev-C++/ExerciseBook/06.73-06.74/06.73-06.74.cpp new file mode 100644 index 0000000..49f6c9d --- /dev/null +++ b/Dev-C++/ExerciseBook/06.73-06.74/06.73-06.74.cpp @@ -0,0 +1,97 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +/* + * -ֵ + */ +Status Algo_6_73(CSTree* T, FILE* fp); + +/* + * ʽӡ-ֵ + */ +void Algo_6_74(CSTree T); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf(" 6.73 ֤... \n"); + printf("-ֵܶ\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_73(&T, fp); + fclose(fp); + PrintGraph(T); + printf("\n"); + + printf(" 6.74 ֤... \n"); + printf("ӡ-ֵ...\n"); + Algo_6_74(T); + printf("\n"); + + return 0; +} + + +/* + * -ֵ + */ +Status Algo_6_73(CSTree* T, FILE* fp) { + char c; + + while(TRUE) { + if(feof(fp) != 0) { + break; + } + + ReadData(fp, "%c", &c); + + if(c >= 'A' && c <= 'Z') { + *T = (CSTree) malloc(sizeof(CSNode)); // + if(*T == NULL) { + exit(OVERFLOW); + } + (*T)->data = c; + (*T)->firstchild = (*T)->nextsibling = NULL; + } else if(c == '(') { + Algo_6_73(&(*T)->firstchild, fp); + } else if(c == ',') { + Algo_6_73(&(*T)->nextsibling, fp); + break; // ע˴Ӧ÷ + } else { + break; + } + } + + return OK; +} + +/* + * ʽӡ-ֵ + */ +void Algo_6_74(CSTree T) { + CSTree p; + + if(!T) { + return; + } + + printf("%c", T->data); + + if(T->firstchild) { + printf("("); + + for(p = T->firstchild; p; p = p->nextsibling) { + Algo_6_74(p); + + // һֵܣ"," + if(p->nextsibling) { + printf(","); + } + } + + printf(")"); + } +} diff --git a/Dev-C++/ExerciseBook/06.73-06.74/06.73-06.74.dev b/Dev-C++/ExerciseBook/06.73-06.74/06.73-06.74.dev new file mode 100644 index 0000000..245d7d4 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.73-06.74/06.73-06.74.dev @@ -0,0 +1,91 @@ +[Project] +FileName=06.73-06.74.dev +Name=06.73-06.74 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=4 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=CSTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.73-06.74.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CSTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.73-06.74/CSTree.cpp b/Dev-C++/ExerciseBook/06.73-06.74/CSTree.cpp new file mode 100644 index 0000000..323fd9b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.73-06.74/CSTree.cpp @@ -0,0 +1,67 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/Dev-C++/ExerciseBook/06.73-06.74/CSTree.h b/Dev-C++/ExerciseBook/06.73-06.74/CSTree.h new file mode 100644 index 0000000..8c3b490 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.73-06.74/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/Dev-C++/ExerciseBook/06.73-06.74/TestData.txt b/Dev-C++/ExerciseBook/06.73-06.74/TestData.txt new file mode 100644 index 0000000..6502a45 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.73-06.74/TestData.txt @@ -0,0 +1 @@ +A(B(E,F),C(G),D) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/06.75-06.76/06.75-06.76.cpp b/Dev-C++/ExerciseBook/06.75-06.76/06.75-06.76.cpp new file mode 100644 index 0000000..a67f7f2 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.75-06.76/06.75-06.76.cpp @@ -0,0 +1,167 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "CTree.h" //**06 Ͷ**// + +/* + * (ѿ˫׽) + */ +void Algo_6_75(CTree* T, FILE* fp); + +// ڲʵ֣parentǵǰλý˫׽λ +void Create(CTree* T, int parent, FILE* fp); + +/* + * ʽӡ + */ +void Algo_6_76(CTree T, int i); + + +int main(int argc, char* argv[]) { + FILE* fp; + CTree T; + + printf(" 6.75 ֤...\n"); + printf("ʽ\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_75(&T, fp); + fclose(fp); + PrintGraph(T); + printf("\n"); + + printf(" 6.76 ֤...\n"); + printf("ʽӡ...\n"); + Algo_6_76(T, T.r); + printf("\n"); + + return 0; +} + + +/* + * (ѿ˫׽) + */ +void Algo_6_75(CTree* T, FILE* fp) { + CTree CT; + ChildPtr r; + int mark[MAX_TREE_SIZE]; + int i, j, p; + + CT.r = 0; // Ĭõ0ŵԪ + CT.n = 0; // 0ŵԪʼ洢 + Create(&CT, -1, fp); // ˴ + + T->n = CT.n; + T->r = 0; + j = T->r; + + // ˳Ϊ + for(p = -1; p < CT.n; p++) { + // ѡΪpԪ + for(i = 0; i < CT.n; i++) { + if(CT.nodes[i].parent == p) { + T->nodes[j] = CT.nodes[i]; + mark[i] = j; // ±ΪiԪƶ±j + j++; + } + } + } + + // ± + for(i = 0; i < T->n; i++) { + p = T->nodes[i].parent; + if(p != -1) { + // ޸parent± + T->nodes[i].parent = mark[p]; + } + + // ޸ĺеԪ± + for(r = T->nodes[i].firstchild; r != NULL; r = r->next) { + r->child = mark[r->child]; + } + } +} + +// ڲʵ֣parentǵǰλý˫׽λ +void Create(CTree* T, int parent, FILE* fp) { + char c; + ChildPtr p, q; + + while(TRUE) { + if(feof(fp) != 0) { + break; + } + + ReadData(fp, "%c", &c); + + if(c >= 'A' && c <= 'Z') { + T->nodes[T->n].data = c; // T.n׷ٽ + T->nodes[T->n].parent = parent; + T->nodes[T->n].firstchild = NULL; + + // Ǹ + if(parent != -1) { + // ӽ + p = (ChildPtr) malloc(sizeof(CTNode)); + p->child = T->n; + p->next = NULL; + + // ȡǰӽĸĺ + q = T->nodes[parent].firstchild; + + // ĺΪ + if(q == NULL) { + T->nodes[parent].firstchild = p; + } else { + // Ҹ㺢β + while(q->next != NULL) { + q = q->next; + } + + // 򸸽ĺúӽ + q->next = p; + } + } + + T->n++; + } else if(c == '(') { + Create(T, T->n - 1, fp); // T.n-1ĵһ + + } else if(c == ',') { + Create(T, parent, fp); // ֵܽ + break; + } else { + break; + } + } +} + +/* + * ʽӡ + */ +void Algo_6_76(CTree T, int i) { + ChildPtr p; + + if(!T.n) { + return; + } + + // ӡ˫׽ + printf("%c", T.nodes[i].data); + + if(T.nodes[i].firstchild) { + printf("("); + + // ӽ + for(p = T.nodes[i].firstchild; p; p = p->next) { + Algo_6_76(T, p->child); + + // һ + if(p->next != NULL) { + printf(","); + } + } + + printf(")"); + } +} diff --git a/Dev-C++/ExerciseBook/06.75-06.76/06.75-06.76.dev b/Dev-C++/ExerciseBook/06.75-06.76/06.75-06.76.dev new file mode 100644 index 0000000..1276cc4 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.75-06.76/06.75-06.76.dev @@ -0,0 +1,111 @@ +[Project] +FileName=06.75-06.76.dev +Name=06.75-06.76 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=6 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=LinkQueue.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=CTree.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=06.75-06.76.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CTree.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=LinkQueue.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=TestData.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/06.75-06.76/CTree.cpp b/Dev-C++/ExerciseBook/06.75-06.76/CTree.cpp new file mode 100644 index 0000000..ba0d57d --- /dev/null +++ b/Dev-C++/ExerciseBook/06.75-06.76/CTree.cpp @@ -0,0 +1,223 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#include "CTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T) { + int k, level; + + // + if(TreeEmpty(T)) { + return 0; + } + + /* + * kʼΪһλ + * Ľ㰴洢洢Ľضλ + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/* ڲʹõĺ */ + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // λ + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // ڵIJ + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // ˸ı + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // eĺӼ0 + + // ÿʱһϢΪЧΪÿ㶼кӽ + pt[e].lastChild = -1; + + // ָýĺ + cp = T.nodes[e].firstchild; + + // ͷŸý㴦ĺռڴ + while(cp != NULL) { + // ǰλ + EnQueue(&Q, cp->child); + + // ¼ + pt[cp->child].row = pt[e].row + 1; + + // ¼ + pt[cp->child].col = ++count; + + // ¼ǰǵڼ + pt[cp->child].childIndex = ++n; + + // ΪһӵϢ + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework(T); +} + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // ʼΪЧ + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + // ˫ױ洢ṹӸ + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/Dev-C++/ExerciseBook/06.75-06.76/CTree.h b/Dev-C++/ExerciseBook/06.75-06.76/CTree.h new file mode 100644 index 0000000..2647e1b --- /dev/null +++ b/Dev-C++/ExerciseBook/06.75-06.76/CTree.h @@ -0,0 +1,108 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* ӽ㶨 */ +typedef struct CTNode { + int child; // úе + struct CTNode* next; // ָһ +} CTNode; + +/* ָӽָ */ +typedef CTNode* ChildPtr; + +/* (˫)Ľ㶨 */ +typedef struct { + int parent; // ˫λ + TElemType data; // ǰ + ChildPtr firstchild; // ͷָ +} CTBox; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} CTree; + + +/* + * ijϢ + * + * ע˫ױ洢ṹҪټǰĵһе + * */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T); + + +/* ڲʹõĺ */ + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T); + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework(CTree T); + +#endif diff --git a/Dev-C++/ExerciseBook/06.75-06.76/LinkQueue.cpp b/Dev-C++/ExerciseBook/06.75-06.76/LinkQueue.cpp new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/Dev-C++/ExerciseBook/06.75-06.76/LinkQueue.cpp @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/Dev-C++/ExerciseBook/06.75-06.76/LinkQueue.h b/Dev-C++/ExerciseBook/06.75-06.76/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.75-06.76/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/06.75-06.76/TestData.txt b/Dev-C++/ExerciseBook/06.75-06.76/TestData.txt new file mode 100644 index 0000000..6502a45 --- /dev/null +++ b/Dev-C++/ExerciseBook/06.75-06.76/TestData.txt @@ -0,0 +1 @@ +A(B(E,F),C(G),D) \ No newline at end of file diff --git a/VisualC++/CourseBook/CourseBook.sdf b/VisualC++/CourseBook/CourseBook.sdf index a94bb6e..43990bf 100644 Binary files a/VisualC++/CourseBook/CourseBook.sdf and b/VisualC++/CourseBook/CourseBook.sdf differ diff --git a/VisualC++/CourseBook/CourseBook.suo b/VisualC++/CourseBook/CourseBook.suo index f3316e0..adac658 100644 Binary files a/VisualC++/CourseBook/CourseBook.suo and b/VisualC++/CourseBook/CourseBook.suo differ diff --git a/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.c b/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.c new file mode 100644 index 0000000..f4937a2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.c @@ -0,0 +1,102 @@ +#include +#include "Status.h" //**01 **// + +/* Ԫ */ +#define MAX 100 + +/* + * /ҺбжuǷΪv + */ +Status Algo_6_33(int L[MAX + 1], int R[MAX + 1], int u, int v); + +/* + * ˫׽бжuǷΪv + */ +Status Algo_6_34(int T[MAX + 1], int u, int v); + + +int main(int argc, char* argv[]) { + int T[MAX + 1] = {0, 0, 1, 1, 2, 2, 3, 5, 5, 6}; // 0ŵԪ + int L[MAX + 1] = {0, 2, 4, 6, 0, 7, 0, 0, 0, 0}; + int R[MAX + 1] = {0, 3, 5, 0, 0, 8, 9, 0, 0, 0}; + int u, v; + + printf("Ϊʾµ\n"); + printf(" 1 2 3 4 5 6 7 8 9\n"); // + printf("T[n] 0 1 1 2 2 3 5 5 6\n"); // ˫׽б + printf("L[n] 2 4 6 0 7 0 0 0 0\n"); // б + printf("R[n] 3 5 0 0 8 9 0 0 0\n"); // Һб + printf("\n"); + + printf("Ҫ֤P...\n\n"); + + printf("(1~9) u = "); + scanf("%d", &u); + printf("(1~9) v = "); + scanf("%d", &v); + printf("\n"); + + printf(" 6.33 ֤...\n"); + { + if(Algo_6_33(L, R, u, v) == TRUE) { + printf("u=%d v=%d \n", u, v); + } else { + printf("u=%d v=%d \n", u, v); + } + + printf("\n"); + } + + + printf(" 6.34 ֤...\n"); + { + if(Algo_6_34(T, u, v) == TRUE) { + printf("u=%d v=%d \n", u, v); + } else { + printf("u=%d v=%d \n", u, v); + } + + printf("\n"); + } + + return 0; +} + + +/* + * /ҺбжuǷΪv + */ +Status Algo_6_33(int L[MAX + 1], int R[MAX + 1], int u, int v) { + // uvĺ + if(L[v] == u || R[v] == u) { + return TRUE; + } else { + // ӣ + if(L[v]!=0 && Algo_6_33(L, R, u, L[v])==TRUE) { + return TRUE; + } + + // Һӣ + if(R[v]!=0 && Algo_6_33(L, R, u, R[v])==TRUE) { + return TRUE; + } + } + + return FALSE; +} + +/* + * ˫׽бжuǷΪv + */ +Status Algo_6_34(int T[MAX + 1], int u, int v) { + // u˫v + if(T[u] == v) { + return TRUE; + } else { + if(T[u] != 0 && Algo_6_34(T, T[u], v) == TRUE) { + return TRUE; + } + } + + return FALSE; +} diff --git a/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj b/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj new file mode 100644 index 0000000..b50b1f8 --- /dev/null +++ b/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj @@ -0,0 +1,72 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {E2A9BA52-345F-4538-9291-68F3FC7617F5} + My06330634 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj.filters b/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj.filters new file mode 100644 index 0000000..e779762 --- /dev/null +++ b/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj.user b/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.33-06.34/06.33-06.34.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.35/06.35.c b/VisualC++/ExerciseBook/06.35/06.35.c new file mode 100644 index 0000000..32927aa --- /dev/null +++ b/VisualC++/ExerciseBook/06.35/06.35.c @@ -0,0 +1,45 @@ +#include + +/* */ +#define N 15 + +/* + * ֵ + */ +int Algo_6_35(char* BiTree, int i); + + +int main(int argc, char* argv[]) { + // ˳洢Ķ(0ŵԪʼ洢) + char BiTree[N] = {'A', 'B', 'C', 'D', 'E', 'F', '\0', 'G', '\0', 'H', 'I', '\0', 'J', '\0', '\0'}; + int i, j; + + printf("Ϊʾ˳洢ṹ^ַ˴ûнϢABCDEF^G^HI^J^^"); + printf("\n"); + + printf("(0~%d)", N); + scanf("%d", &i); + printf("\n"); + + j = Algo_6_35(BiTree, i); + + if(j != -1) { + printf(" %d ӦʮΪ %d \n", i, j); + } else { + printf("˴㲻ڣ\n"); + } + + return 0; +} + + +/* + * ֵ + */ +int Algo_6_35(char* BiTree, int i) { + if(BiTree[i] == '\0') { + return -1; // ˴ڽ + } + + return i + 1; +} diff --git a/VisualC++/ExerciseBook/06.35/06.35.vcxproj b/VisualC++/ExerciseBook/06.35/06.35.vcxproj new file mode 100644 index 0000000..75b7136 --- /dev/null +++ b/VisualC++/ExerciseBook/06.35/06.35.vcxproj @@ -0,0 +1,72 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {643D5705-B868-4A77-8E6A-17BEFD90F6C8} + My0635 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.35/06.35.vcxproj.filters b/VisualC++/ExerciseBook/06.35/06.35.vcxproj.filters new file mode 100644 index 0000000..e7c31c7 --- /dev/null +++ b/VisualC++/ExerciseBook/06.35/06.35.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.35/06.35.vcxproj.user b/VisualC++/ExerciseBook/06.35/06.35.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.35/06.35.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.36/06.36.c b/VisualC++/ExerciseBook/06.36/06.36.c new file mode 100644 index 0000000..f817b66 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/06.36.c @@ -0,0 +1,63 @@ +#include +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* + * жöǷ + */ +Status Algo_6_36(BiTree B1, BiTree B2); + + +int main(int argc, char* argv[]) { + BiTree B1, B2, B3; + + printf(" B1 ...\n"); + CreateBiTree(&B1, "TestData_B1.txt"); + PrintGraph(B1); + printf("\n"); + + printf(" B2 ...\n"); + CreateBiTree(&B2, "TestData_B2.txt"); + PrintGraph(B2); + printf("\n"); + + printf(" B3 ...\n"); + CreateBiTree(&B3, "TestData_B3.txt"); + PrintGraph(B3); + printf("\n"); + + if(Algo_6_36(B1, B2) == TRUE) { + printf("B1B2ƣ\n"); + } else { + printf("B1B2ƣ\n"); + } + + if(Algo_6_36(B2, B3) == TRUE) { + printf("B2B3ƣ\n"); + } else { + printf("B2B3ƣ\n"); + } + + return 0; +} + + +/* + * жöǷ + */ +Status Algo_6_36(BiTree B1, BiTree B2) { + // Ϊ + if(BiTreeEmpty(B1) && BiTreeEmpty(B2)) { + return TRUE; + } else { + // Ϊ + if(!BiTreeEmpty(B1) && !BiTreeEmpty(B2)) { + // ж + if(Algo_6_36(B1->lchild, B2->lchild) && Algo_6_36(B1->rchild, B2->rchild)) { + return TRUE; + } + } + } + + return FALSE; +} diff --git a/VisualC++/ExerciseBook/06.36/06.36.vcxproj b/VisualC++/ExerciseBook/06.36/06.36.vcxproj new file mode 100644 index 0000000..a6268e0 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/06.36.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {07804D85-D6E3-4A9C-B600-48DD65807835} + My0636 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.36/06.36.vcxproj.filters b/VisualC++/ExerciseBook/06.36/06.36.vcxproj.filters new file mode 100644 index 0000000..c2ca5f5 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/06.36.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.36/06.36.vcxproj.user b/VisualC++/ExerciseBook/06.36/06.36.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/06.36.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.36/BiTree.c b/VisualC++/ExerciseBook/06.36/BiTree.c new file mode 100644 index 0000000..97a2156 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/BiTree.c @@ -0,0 +1,178 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.36/BiTree.h b/VisualC++/ExerciseBook/06.36/BiTree.h new file mode 100644 index 0000000..f4d29c5 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/BiTree.h @@ -0,0 +1,76 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.36/LinkQueue.c b/VisualC++/ExerciseBook/06.36/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.36/LinkQueue.h b/VisualC++/ExerciseBook/06.36/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.36/TestData_B1.txt b/VisualC++/ExerciseBook/06.36/TestData_B1.txt new file mode 100644 index 0000000..3171ed9 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/TestData_B1.txt @@ -0,0 +1 @@ +СABD^^E^^C^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.36/TestData_B2.txt b/VisualC++/ExerciseBook/06.36/TestData_B2.txt new file mode 100644 index 0000000..3c311a7 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/TestData_B2.txt @@ -0,0 +1 @@ +СFGH^^I^^J^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.36/TestData_B3.txt b/VisualC++/ExerciseBook/06.36/TestData_B3.txt new file mode 100644 index 0000000..a89ca54 --- /dev/null +++ b/VisualC++/ExerciseBook/06.36/TestData_B3.txt @@ -0,0 +1 @@ +СKLM^^N^^OP^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.c b/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.c new file mode 100644 index 0000000..e19a4da --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.c @@ -0,0 +1,133 @@ +#include +#include "Status.h" //**01 **// +#include "SqStack.h" //**03 ջͶ**// +#include "BiTree.h" //**06 Ͷ**// + +/* + * ķǵݹʽ + */ +Status Algo_6_37(BiTree T); + +/* + * ķǵݹʽ + */ +Status Algo_6_38(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf(" T ...\n"); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf(" 6.37 ֤...\n"); + { + printf("Ϊ"); + Algo_6_37(T); + printf("\n"); + } + + printf(" 6.38 ֤...\n"); + { + printf("Ϊ"); + Algo_6_38(T); + printf("\n"); + } + + return 0; +} + + +/* + * ķǵݹʽ + */ +Status Algo_6_37(BiTree T) { + SqStack S; + SElemType e; + + if(BiTreeEmpty(T)) { + printf("\n"); + return ERROR; + } + + InitStack(&S); + Push(&S, T); + + while(!StackEmpty(S)) { + GetTop(S, &e); + printf("%c ", e->data); + + if(e->lchild) { + Push(&S, e->lchild); + } else { + while(!StackEmpty(S)) { + Pop(&S, &e); + + if(e->rchild) { + Push(&S, e->rchild); + break; + } + } + } + } + + printf("\n"); + return OK; +} + +/* + * ķǵݹʽ + */ +Status Algo_6_38(BiTree T) { + SqStack S; + BiTree p; + SElemType e; + int StackMark[100] = {0}; // ջøʱǣʼΪ0 + int k; + + if(BiTreeEmpty(T)) { + printf("\n"); + return ERROR; + } + + InitStack(&S); + p = T; + k = -1; + + while(TRUE) { + while(p) { + Push(&S, p); + k++; + StackMark[k] = 1; // õһηʵı + p = p->lchild; + } + + // pΪյջΪ + while(!p && !StackEmpty(S)) { + GetTop(S, &p); + + // ѷʹһΣǰǵڶη + if(StackMark[k] == 1) { + StackMark[k] = 2; + p = p->rchild; + + // ѷʹΣǰǵη + } else { + printf("%c ", p->data); + Pop(&S, &e); + StackMark[k] = 0; + k--; + p = NULL; + } + } + + if(StackEmpty(S)) { + break; + } + } + + printf("\n"); + return OK; +} diff --git a/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj b/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj new file mode 100644 index 0000000..ed9c50b --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D9DAFB4C-B792-40D8-913E-A5FB1304A383} + My06370638 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj.filters b/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj.filters new file mode 100644 index 0000000..c31edb7 --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj.user b/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/06.37-06.38.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.37-06.38/BiTree.c b/VisualC++/ExerciseBook/06.37-06.38/BiTree.c new file mode 100644 index 0000000..97a2156 --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/BiTree.c @@ -0,0 +1,178 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.37-06.38/BiTree.h b/VisualC++/ExerciseBook/06.37-06.38/BiTree.h new file mode 100644 index 0000000..f4d29c5 --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/BiTree.h @@ -0,0 +1,76 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.37-06.38/LinkQueue.c b/VisualC++/ExerciseBook/06.37-06.38/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.37-06.38/LinkQueue.h b/VisualC++/ExerciseBook/06.37-06.38/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.37-06.38/SqStack.c b/VisualC++/ExerciseBook/06.37-06.38/SqStack.c new file mode 100644 index 0000000..f0b3b3d --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/SqStack.c @@ -0,0 +1,106 @@ +/*========================= + * ջ˳洢ṹ˳ջ + ==========================*/ + +#include "SqStack.h" //**03 ջͶ**// + +/* + * ʼ + * + * һջʼɹ򷵻OK򷵻ERROR + */ +Status InitStack(SqStack* S) { + if(S == NULL) { + return ERROR; + } + + (*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); + } + + (*S).top = (*S).base; + (*S).stacksize = STACK_INIT_SIZE; + + return OK; +} + +/* + * п + * + * ж˳ջǷЧݡ + * + * ֵ + * TRUE : ˳ջΪ + * FALSE: ˳ջΪ + */ +Status StackEmpty(SqStack S) { + if(S.top == S.base) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * ȡֵ + * + * ջԪأeա + */ +Status GetTop(SqStack S, SElemType* e) { + if(S.base == NULL || S.top == S.base) { + return 0; + } + + // ıջԪ + *e = *(S.top - 1); + + return OK; +} + +/* + * ջ + * + * Ԫeѹ뵽ջ + */ +Status Push(SqStack* S, SElemType e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + // ջʱ׷Ӵ洢ռ + if((*S).top - (*S).base >= (*S).stacksize) { + (*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); // 洢ʧ + } + + (*S).top = (*S).base + (*S).stacksize; + (*S).stacksize += STACKINCREMENT; + } + + // ջȸֵջָ + *(S->top++) = e; + + return OK; +} + +/* + * ջ + * + * ջԪصeա + */ +Status Pop(SqStack* S, SElemType* e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + if((*S).top == (*S).base) { + return ERROR; + } + + // ջջָȵݼٸֵ + *e = *(--(*S).top); + + return OK; +} diff --git a/VisualC++/ExerciseBook/06.37-06.38/SqStack.h b/VisualC++/ExerciseBook/06.37-06.38/SqStack.h new file mode 100644 index 0000000..86c1fcc --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/SqStack.h @@ -0,0 +1,67 @@ +/*========================= + * ջ˳洢ṹ˳ջ + ==========================*/ + +#ifndef SQSTACK_H +#define SQSTACK_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* 궨 */ +#define STACK_INIT_SIZE 100 // ˳ջ洢ռijʼ +#define STACKINCREMENT 10 // ˳ջ洢ռķ + +/* ˳ջԪͶ */ +typedef BiTree SElemType; + +// ˳ջԪؽṹ +typedef struct { + SElemType* base; // ջָ + SElemType* top; // ջָ + int stacksize; // ǰѷĴ洢ռ䣬ԪΪλ +} SqStack; + + +/* + * ʼ + * + * һջʼɹ򷵻OK򷵻ERROR + */ +Status InitStack(SqStack* S); + +/* + * п + * + * ж˳ջǷЧݡ + * + * ֵ + * TRUE : ˳ջΪ + * FALSE: ˳ջΪ + */ +Status StackEmpty(SqStack S); + +/* + * ȡֵ + * + * ջԪأeա + */ +Status GetTop(SqStack S, SElemType* e); + +/* + * ջ + * + * Ԫeѹ뵽ջ + */ +Status Push(SqStack* S, SElemType e); + +/* + * ջ + * + * ջԪصeա + */ +Status Pop(SqStack* S, SElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.37-06.38/TestData.txt b/VisualC++/ExerciseBook/06.37-06.38/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/VisualC++/ExerciseBook/06.37-06.38/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.39/06.39.c b/VisualC++/ExerciseBook/06.39/06.39.c new file mode 100644 index 0000000..d90804f --- /dev/null +++ b/VisualC++/ExerciseBook/06.39/06.39.c @@ -0,0 +1,153 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͣΪַ */ +typedef char TElemType; + +/* Ľ㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ + struct BiTNode* parent; + int mark; +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + +/* + * ĵʽ + */ +void Algo_6_39(BiTree T); + +// () +Status CreateBiTree(BiTree* T, char* path); + +// ڲʵ֣p׷ +void CreateTree(BiTree* T, BiTree p, FILE* fp); + +// ͼλʽǰ +void PrintGraph(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf(" T ...\n"); + CreateBiTree(&T, NULL); + PrintGraph(T); + + printf("Ϊ"); + Algo_6_39(T); + + return 0; +} + + +/* + * ĵʽ + */ +void Algo_6_39(BiTree T) { + BiTree p = T; + + while(p != NULL) { + // mark==0δʣ + if(p->mark == 0) { + p->mark = 1; + if(p->lchild != NULL) { + p = p->lchild; + } + + // mark==1ѷʣҷ + } else if(p->mark == 1) { + p->mark = 2; + if(p->rchild != NULL) { + p = p->rchild; + } + + // mark==2Ҷˣӡ + } else { + printf("%c ", p->data); + p->mark = 0; // + p = p->parent; + } + } + + printf("\n"); +} + +// () +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + + fp = fopen("TestData.txt", "r"); + CreateTree(T, NULL, fp); + fclose(fp); + + return OK; +} + +// ڲʵ֣p׷ +void CreateTree(BiTree* T, BiTree p, FILE* fp) { + char ch; + + ReadData(fp, "%c", &ch); + + if(ch == '^') { + *T = NULL; + } else { + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + (*T)->parent = p; + (*T)->mark = 0; + CreateTree(&(*T)->lchild, *T, fp); + CreateTree(&(*T)->rchild, *T, fp); + } +} + +// ͼλʽǰ +void PrintGraph(BiTree T) { + BiTree p = T; + int i = 1; + + while(p != NULL) { + // mark==0δʣ + if(p->mark == 0) { + printf("%c ", p->data); + i++; + p->mark = 1; + if(p->lchild != NULL) { + p = p->lchild; + } else { + printf("^\n"); + i--; + } + + // mark==1ѷʣҷ + } else if(p->mark == 1) { + p->mark = 2; + i++; + + if(p->rchild != NULL) { + printf("%*c", 2 * (i - 1), ' '); + p = p->rchild; + } else { + printf("%*c^\n", 2 * (i - 1), ' '); + i--; + } + + // mark==2Ҷˣӡ + } else { + p->mark = 0; // + p = p->parent; + i--; + } + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/06.39/06.39.vcxproj b/VisualC++/ExerciseBook/06.39/06.39.vcxproj new file mode 100644 index 0000000..58ea8c0 --- /dev/null +++ b/VisualC++/ExerciseBook/06.39/06.39.vcxproj @@ -0,0 +1,75 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {73823E0A-5C7D-4785-B42D-7F10221D5698} + My0639 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.39/06.39.vcxproj.filters b/VisualC++/ExerciseBook/06.39/06.39.vcxproj.filters new file mode 100644 index 0000000..d3e16ae --- /dev/null +++ b/VisualC++/ExerciseBook/06.39/06.39.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.39/06.39.vcxproj.user b/VisualC++/ExerciseBook/06.39/06.39.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.39/06.39.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.39/TestData.txt b/VisualC++/ExerciseBook/06.39/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/VisualC++/ExerciseBook/06.39/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.40/06.40.c b/VisualC++/ExerciseBook/06.40/06.40.c new file mode 100644 index 0000000..29642fd --- /dev/null +++ b/VisualC++/ExerciseBook/06.40/06.40.c @@ -0,0 +1,169 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͣΪַ */ +typedef char TElemType; + +/* Ľ㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ + struct BiTNode* parent; +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + +/* + * ĵʽ + * + *ע + * ĹؼǷֱ浱ǰڼαʡ + */ +void Algo_6_40(BiTree T); + +// () +Status CreateBiTree(BiTree* T, char* path); + +// ڲʵ֣p׷ +void CreateTree(BiTree* T, BiTree p, FILE* fp); + +// ͼλʽǰ +void PrintGraph(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf(" T ...\n"); + CreateBiTree(&T, NULL); + PrintGraph(T); + + printf("Ϊ"); + Algo_6_40(T); + + return 0; +} + + +/* + * ĵʽ + * + *ע + * ĹؼǷֱ浱ǰڼαʡ + */ +void Algo_6_40(BiTree T) { + BiTree p = T; + + while(p != NULL) { + // һηʽ㣬 + if(p->lchild != NULL) { + p = p->lchild; + } else { + // صĽڶα,Ҫ + printf("%c ", p->data); + + // ǰҷ֧صҪ + while(p->rchild == NULL) { + // صĽαʣ + while(p->parent != NULL && p->parent->rchild == p) { + p = p->parent; + } + + if(p->parent != NULL) { + // ǰ֧صҪʸ + if(p->parent->lchild == p) { + p = p->parent; + printf("%c ", p->data); // ͬ + } + } else { + printf("\n"); + + // صʱ + return; + } + } + + p = p->rchild; + } + } +} + +// () +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + + fp = fopen("TestData.txt", "r"); + CreateTree(T, NULL, fp); + fclose(fp); + + return OK; +} + +// ڲʵ֣p׷ +void CreateTree(BiTree* T, BiTree p, FILE* fp) { + char ch; + + ReadData(fp, "%c", &ch); + + if(ch == '^') { + *T = NULL; + } else { + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + (*T)->parent = p; + CreateTree(&(*T)->lchild, *T, fp); + CreateTree(&(*T)->rchild, *T, fp); + } +} + +// ͼλʽǰ +void PrintGraph(BiTree T) { + BiTree p = T; + int i = 1; + + while(p != NULL) { + // صĽڶα,Ҫ + printf("%c ", p->data); + i++; + + // һηʽ㣬 + if(p->lchild != NULL) { + p = p->lchild; + } else { + printf("^\n"); + + // ǰҷ֧صҪ + while(p->rchild == NULL) { + printf("%*c^\n", 2 * (i - 1), ' '); + i--; + + // صĽαʣ + while(p->parent != NULL && p->parent->rchild == p) { + p = p->parent; + i--; + } + + if(p->parent != NULL) { + // ǰ֧صҪʸ + if(p->parent->lchild == p) { + p = p->parent; + } + } else { + printf("\n"); + + // صʱ + return; + } + } + + printf("%*c", 2 * (i - 1), ' '); + p = p->rchild; + } + } +} diff --git a/VisualC++/ExerciseBook/06.40/06.40.vcxproj b/VisualC++/ExerciseBook/06.40/06.40.vcxproj new file mode 100644 index 0000000..c25394c --- /dev/null +++ b/VisualC++/ExerciseBook/06.40/06.40.vcxproj @@ -0,0 +1,75 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {DB178717-F4B4-40C7-AD1A-CEDFB66D6313} + My0640 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.40/06.40.vcxproj.filters b/VisualC++/ExerciseBook/06.40/06.40.vcxproj.filters new file mode 100644 index 0000000..02ef209 --- /dev/null +++ b/VisualC++/ExerciseBook/06.40/06.40.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.40/06.40.vcxproj.user b/VisualC++/ExerciseBook/06.40/06.40.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.40/06.40.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.40/TestData.txt b/VisualC++/ExerciseBook/06.40/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/VisualC++/ExerciseBook/06.40/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.c b/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.c new file mode 100644 index 0000000..fdb211e --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.c @@ -0,0 +1,503 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_DEPTH 20 // +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * еkֵorder + */ +Status Algo_6_41(BiTree T, int k, int* order, TElemType* e); + +/* + * ҶӽĿ + */ +int Algo_6_42(BiTree T); + +/* + * + */ +void Algo_6_43(BiTree T); + +/* + * 'x' + */ +int Algo_6_44(BiTree T, TElemType x); + +/* + * ɾTеx + */ +Status Algo_6_45(BiTree* T, TElemType x); + +/* + * ƶķǵݹ㷨 + */ +void Algo_6_46(BiTree T, BiTree* Tx); + +/* + * + */ +void Algo_6_47(BiTree T); + +/* + * Ĺͬ + */ +BiTree Algo_6_48(BiTree T, TElemType a, TElemType b); + +/* + * ж϶ǷΪȫ + */ +Status Algo_6_49(BiTree T); + +/* + * ѰҸ㵽p·path洢·ϸָ(pָ) + */ +static int FindPath(BiTree T, TElemType e, BiTree path[]); + +// ָeָ +static BiTree EPtr(BiTree T, TElemType e); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf(" T ...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf(" 6.41 ֤...\n"); + { + int k = 9; + int order = 0; // + TElemType e; + + if(Algo_6_41(T, k, &order, &e)) { + printf("е %d ԪΪ %c \n", k, e); + } else { + printf("˴Ԫزڣ\n"); + } + + printf("\n"); + } + + printf(" 6.42 ֤...\n"); + { + printf("ҶӽΪ%d\n", Algo_6_42(T)); + printf("\n"); + } + + printf(" 6.43 ֤...\n"); + { + printf("Ϊ\n"); + Algo_6_43(T); + PrintGraph(T); + printf("\n"); + } + + printf(" 6.44 ֤...\n"); + { + char x = 'E'; + + printf(" %c Ϊ %d\n", x, Algo_6_44(T, x)); + printf("\n"); + } + + printf(" 6.45 ֤...\n"); + { + char x = 'D'; + + printf("ɾ %c 󣬶Ϊ\n", x); + if(Algo_6_45(&T, x)) { + PrintGraph(T); + } + printf("\n"); + } + + printf(" 6.46 ֤...\n"); + { + BiTree Tx; + + printf(" T Tx 󣬶TxΪ\n"); + Algo_6_46(T, &Tx); + PrintGraph(Tx); + printf("\n"); + } + + printf(" 6.47 ֤...\n"); + { + printf("Ϊ"); + Algo_6_47(T); + printf("\n"); + } + + printf(" 6.48 ֤...\n"); + { + BiTree Tmp = NULL; + TElemType a = 'I'; + TElemType b = 'H'; + + if((Tmp = Algo_6_48(T, a, b)) != NULL) { + printf("'%c' '%c' ͬΪ'%c'\n", a, b, Tmp->data); + } + printf("\n"); + } + + printf(" 6.49 ֤...\n"); + { + if(Algo_6_49(T)) { + printf("˶ȫ\n"); + } else { + printf("˶ȫ!\n"); + } + } + + return 0; +} + + +/* + * еkֵorder + */ +Status Algo_6_41(BiTree T, int k, int* order, TElemType* e) { + + if(T == NULL) { + *e = '\0'; + return ERROR; + } + + (*order)++; + + if(*order == k) { + *e = T->data; + return OK; + } else { + if(Algo_6_41(T->lchild, k, order, e)) { + return OK; + } + + if(Algo_6_41(T->rchild, k, order, e)) { + return OK; + } + } + + return ERROR; +} + +/* + * ҶӽĿ + */ +int Algo_6_42(BiTree T) { + int count = 0; + + if(T != NULL) { + if(T->lchild == NULL && T->rchild == NULL) { + count++; + } else { + count += Algo_6_42(T->lchild); // Ҷӽ + count += Algo_6_42(T->rchild); // Ҷӽ + } + } + + return count; +} + +/* + * + */ +void Algo_6_43(BiTree T) { + BiTree p; + + if(T != NULL) { + p = T->lchild; + T->lchild = T->rchild; + T->rchild = p; + + // ݹ齻 + Algo_6_43(T->lchild); + Algo_6_43(T->rchild); + } +} + +/* + * T'x' + */ +int Algo_6_44(BiTree T, TElemType x) { + BiTree p; + + p = EPtr(T, x); // һݹxλãָʽ + + return BiTreeDepth(p); // ڶݹx +} + +/* + * ɾTеx + */ +Status Algo_6_45(BiTree* T, TElemType x) { + + if(*T == NULL) { + return ERROR; + } + + // ҵ˸ý㣬ݹ + if((*T)->data == x) { + ClearBiTree(T); + return OK; + // ݹѰҸý + } else { + if(Algo_6_45(&((*T)->lchild), x)) { + return OK; + } + + if(Algo_6_45(&((*T)->rchild), x)) { + return OK; + } + + return ERROR; + } +} + +/* + * ƶķǵݹ㷨 + */ +void Algo_6_46(BiTree T, BiTree* Tx) { + int front, rear; + BiTree queue[MAX_TREE_SIZE] = {NULL}; // ָ飬ģУʼԪΪNULL + BiTree tree[MAX_TREE_SIZE]; // ½Ķ + BiTree p; + int parent; + + if(T == NULL) { + *Tx = NULL; + return; + } + + front = rear = 0; + + queue[rear] = T; + + while(front <= rear) { + p = queue[front]; + + if(p == NULL) { + front++; + continue; + } + + // ½ + tree[front] = (BiTree) malloc(sizeof(BiTNode)); + tree[front]->data = p->data; + tree[front]->lchild = tree[front]->rchild = NULL; + + // Ϊýҽڸ + if(front > 0) { + parent = (front - 1) / 2; + + // ǰΪ + if(2 * parent + 1 == front) { + tree[parent]->lchild = tree[front]; + } else { + tree[parent]->rchild = tree[front]; + } + } + + if(p->lchild != NULL) { + rear = 2 * front + 1; + queue[rear] = p->lchild; + } + + if(p->rchild != NULL) { + rear = 2 * front + 2; + queue[rear] = p->rchild; + } + + front++; + } + + *Tx = tree[0]; +} + +/* + * + */ +void Algo_6_47(BiTree T) { + int front, rear; + BiTree queue[MAX_TREE_SIZE]; // ָ飬ģ + BiTree p; + + if(T == NULL) { + return; + } + + front = rear = 0; + + queue[rear++] = T; + + while(front != rear) { + p = queue[front++]; + + printf("%c ", p->data); + + if(p->lchild != NULL) { + queue[rear++] = p->lchild; + } + + if(p->rchild != NULL) { + queue[rear++] = p->rchild; + } + } + + printf("\n"); +} + +/* + * Ĺͬ + */ +BiTree Algo_6_48(BiTree T, TElemType a, TElemType b) { + BiTree pa[MAX_TREE_DEPTH] = {NULL}; + BiTree pb[MAX_TREE_DEPTH] = {NULL}; + int lenA, lenB; + int i, j; + + // ·ѰҺ + if((lenA = FindPath(T, a, pa)) != 0 && (lenB = FindPath(T, b, pb)) != 0) { + for(i = lenA - 1; pa[i] != NULL; i--) { + for(j = lenB - 1; pb[j] != NULL; j--) { + if(pa[i]->data == pb[j]->data) { + return pa[i]; + } + } + } + } + + return NULL; +} + +/* + * ж϶ǷΪȫ + * + * ȫصDzʱһ + */ +Status Algo_6_49(BiTree T) { + int front, rear; + BiTree queue[MAX_TREE_SIZE]; // ָ飬ģ + int order[MAX_TREE_SIZE]; + BiTree p; + int count; + + if(T == NULL) { + return OK; + } + + front = rear = 0; + count = 1; + + queue[rear] = T; + order[rear] = 1; + rear++; + + // ͬʱΪ + while(front < rear) { + if(order[front] != count) { + return ERROR; + } + + p = queue[front]; // ȡͷԪ + + if(p->lchild != NULL) { + queue[rear] = p->lchild; + order[rear] = 2 * order[front]; + rear++; + } + + if(p->rchild != NULL) { + queue[rear] = p->rchild; + order[rear] = 2 * order[front] + 1; + rear++; + } + + front++; + count++; // ÿһһ + } + + return OK; +} + +// ָeָ +static BiTree EPtr(BiTree T, TElemType e) { + BiTree pl, pr; + + if(T == NULL) { + return NULL; + } + + // ҵĿ㣬ֱӷָ + if(T->data == e) { + return T; + } + + // вe + pl = EPtr(T->lchild, e); + if(pl != NULL) { + return pl; + } + + // вe + pr = EPtr(T->rchild, e); + if(pr != NULL) { + return pr; + } + + return NULL; +} + +// ѰҸ㵽p·path洢·ϸָ(pָ) +static int FindPath(BiTree T, TElemType e, BiTree path[]) { + int i = -1; + int mark[MAX_TREE_DEPTH] = {0}; // ʱջ + BiTree p; + + p = T; + + while(TRUE) { + // ûĽ㣬ȳ + while(p != NULL && p->data != e) { + i++; + + // µǰָ + path[i] = p; + + // ѷʹý + mark[i] = 1; + p = p->lchild; + } + + // Ľ + if(p != NULL) { + return i + 1; + } + + // ص + p = path[i]; + + // ڣ߸ѱʹصĸ + while(p->rchild == NULL || mark[i] == 2) { + path[i] = NULL; // ÿոλ + + i--; + if(i == -1) { + return 0; + } + + // ˵ + p = path[i]; + } + + // ѷʹý + mark[i] = 2; + p = p->rchild; + } +} diff --git a/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj b/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj new file mode 100644 index 0000000..7be60d8 --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {8D15F734-D022-4049-B6B2-B8CDE3845D00} + My06410649 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj.filters b/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj.filters new file mode 100644 index 0000000..fd5a825 --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj.user b/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/06.41-06.49.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.41-06.49/BiTree.c b/VisualC++/ExerciseBook/06.41-06.49/BiTree.c new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.41-06.49/BiTree.h b/VisualC++/ExerciseBook/06.41-06.49/BiTree.h new file mode 100644 index 0000000..ba89b3e --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.41-06.49/LinkQueue.c b/VisualC++/ExerciseBook/06.41-06.49/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.41-06.49/LinkQueue.h b/VisualC++/ExerciseBook/06.41-06.49/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.41-06.49/TestData.txt b/VisualC++/ExerciseBook/06.41-06.49/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/VisualC++/ExerciseBook/06.41-06.49/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.50/06.50.c b/VisualC++/ExerciseBook/06.50/06.50.c new file mode 100644 index 0000000..e4d9899 --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/06.50.c @@ -0,0 +1,83 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ȡԤʽĽϢ򴴽 + */ +Status Algo_6_50(BiTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + BiTree T; + FILE* fp; + + printf("У...\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_50(&T, fp); + fclose(fp); + printf("\n"); + + printf("TΪ\n"); + PrintGraph(T); + + return 0; +} + + +/* + * ȡԤʽĽϢ򴴽 + */ +Status Algo_6_50(BiTree* T, FILE* fp) { + char s[4]; + BiTree tmp[MAX_TREE_SIZE]; // 洢ÿָ + int m, n; + BiTree p; + + m = n = 0; + + *T= NULL; + + while(TRUE) { + ReadData(fp, "%s", s); + printf("%s\n", s); + + // ˳־ + if(s[1] == '^') { + return OK; + } + + p = (BiTree) malloc(sizeof(BiTNode)); + if(p==NULL) { + exit(OVERFLOW); + } + p->data = s[1]; + p->lchild = p->rchild = NULL; + + // + if(s[0] == '^') { + *T = p; + tmp[n++] = p; + } else { + // Ѱ + while(mdata != s[0]) { + m++; + } + + if(m>=n) { + return ERROR; + } + + if(s[2] == 'L') { + tmp[m]->lchild = p; + } else { + tmp[m]->rchild = p; + } + } + + tmp[n++] = p; + } +} diff --git a/VisualC++/ExerciseBook/06.50/06.50.vcxproj b/VisualC++/ExerciseBook/06.50/06.50.vcxproj new file mode 100644 index 0000000..5d8cf94 --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/06.50.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {CEBDCC1E-C3FE-4E9A-B830-D3B43268C645} + My0650 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.50/06.50.vcxproj.filters b/VisualC++/ExerciseBook/06.50/06.50.vcxproj.filters new file mode 100644 index 0000000..5b4cf6b --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/06.50.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.50/06.50.vcxproj.user b/VisualC++/ExerciseBook/06.50/06.50.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/06.50.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.50/BiTree.c b/VisualC++/ExerciseBook/06.50/BiTree.c new file mode 100644 index 0000000..76327ed --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/BiTree.c @@ -0,0 +1,121 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.50/BiTree.h b/VisualC++/ExerciseBook/06.50/BiTree.h new file mode 100644 index 0000000..d53885f --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.50/LinkQueue.c b/VisualC++/ExerciseBook/06.50/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.50/LinkQueue.h b/VisualC++/ExerciseBook/06.50/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.50/TestData.txt b/VisualC++/ExerciseBook/06.50/TestData.txt new file mode 100644 index 0000000..43ff76f --- /dev/null +++ b/VisualC++/ExerciseBook/06.50/TestData.txt @@ -0,0 +1,9 @@ +^AL +ABL +ACR +BDL +CEL +CFR +DGR +FHL +^^L \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.51/06.51.c b/VisualC++/ExerciseBook/06.51/06.51.c new file mode 100644 index 0000000..8dfa052 --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/06.51.c @@ -0,0 +1,90 @@ +#include +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* + * ʽɵĶ + */ +void Algo_6_51(BiTree T); + +// жַcǷΪ +Status IsOperator(char c); + +// жȼ +Status Priority(char a, char b); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("ʽ"); + Algo_6_51(T); + printf("\n"); + + return 0; +} + + +/* + * ʽɵĶ + */ +void Algo_6_51(BiTree T) { + if(T == NULL) { + return; + } + + if(T->lchild != NULL) { + // ǰDzȼڵǰ + if(IsOperator(T->lchild->data) && Priority(T->lchild->data, T->data) < 0) { + printf("("); + Algo_6_51(T->lchild); + printf(")"); + } else { + Algo_6_51(T->lchild); + } + } + + printf("%c", T->data); + + if(T->rchild != NULL) { + // ǰҺDzȼڵǰ + if(IsOperator(T->rchild->data) && Priority(T->rchild->data, T->data) < 0) { + printf("("); + Algo_6_51(T->rchild); + printf(")"); + } else { + Algo_6_51(T->rchild); + } + } +} + +// жַcǷΪ +Status IsOperator(char c) { + if(c == '+' || c == '-' || c == '*' || c == '/') { + return TRUE; + } else { + return ERROR; + } +} + +// жȼ +Status Priority(char a, char b) { + // aȼ + if((a == '+' || a == '-') && (b == '*' || b == '/')) { + return -1; + + // aȼ + } else if((a == '*' || a == '/') && (b == '+' || b == '-')) { + return 1; + + // ȼͬ + } else { + return 0; + } +} diff --git a/VisualC++/ExerciseBook/06.51/06.51.vcxproj b/VisualC++/ExerciseBook/06.51/06.51.vcxproj new file mode 100644 index 0000000..f6d7661 --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/06.51.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {28F75E62-9AE5-49E2-BA2E-A5CD592505AF} + My0651 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.51/06.51.vcxproj.filters b/VisualC++/ExerciseBook/06.51/06.51.vcxproj.filters new file mode 100644 index 0000000..8d1a729 --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/06.51.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.51/06.51.vcxproj.user b/VisualC++/ExerciseBook/06.51/06.51.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/06.51.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.51/BiTree.c b/VisualC++/ExerciseBook/06.51/BiTree.c new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.51/BiTree.h b/VisualC++/ExerciseBook/06.51/BiTree.h new file mode 100644 index 0000000..ba89b3e --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.51/LinkQueue.c b/VisualC++/ExerciseBook/06.51/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.51/LinkQueue.h b/VisualC++/ExerciseBook/06.51/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.51/TestData.txt b/VisualC++/ExerciseBook/06.51/TestData.txt new file mode 100644 index 0000000..be56cc6 --- /dev/null +++ b/VisualC++/ExerciseBook/06.51/TestData.txt @@ -0,0 +1 @@ +С*/*+a^^b^^-c^^d^^e^^-g^^h^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.52/06.52.c b/VisualC++/ExerciseBook/06.52/06.52.c new file mode 100644 index 0000000..49b08f3 --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/06.52.c @@ -0,0 +1,90 @@ +#include +#include // ṩpowlogԭ +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ķïȣx߶ + * עΪֵ + */ +int Algo_6_52(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("ķïΪ %d", Algo_6_52(T)); + printf("\n"); + + return 0; +} + + +/* + * ķïȣx߶ + * עΪֵ + */ +int Algo_6_52(BiTree T) { + int lux; // ï + int col, width; // Ⱥ + int row, high; // ǰڲ߶ + BiTree queue[MAX_TREE_SIZE]; // ָ飬ģ + int level[MAX_TREE_SIZE]; // ¼ǰڵڼ + BiTree p; + int m, n; + + if(T==NULL) { + return 0; + } + + width = high = 0; + m = n = 0; + col = 1; + + queue[n] = T; + level[n] = 1; + n++; + + while(mhigh) { + high = row; + col = 1; // ʱҪ + } else { + col++; + } + + if(col>width) { + width = col; + } + + if(p->lchild!=NULL) { + queue[n] = p->lchild; + level[n] = row+1; + n++; + } + + if(p->rchild!=NULL) { + queue[n] = p->rchild; + level[n] = row+1; + n++; + } + + + } + + lux = width * high; + + return lux; +} diff --git a/VisualC++/ExerciseBook/06.52/06.52.vcxproj b/VisualC++/ExerciseBook/06.52/06.52.vcxproj new file mode 100644 index 0000000..da234f6 --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/06.52.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C01BDD71-C820-4EF9-A153-C92CF6A252C3} + My0652 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.52/06.52.vcxproj.filters b/VisualC++/ExerciseBook/06.52/06.52.vcxproj.filters new file mode 100644 index 0000000..988f0b7 --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/06.52.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.52/06.52.vcxproj.user b/VisualC++/ExerciseBook/06.52/06.52.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/06.52.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.52/BiTree.c b/VisualC++/ExerciseBook/06.52/BiTree.c new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.52/BiTree.h b/VisualC++/ExerciseBook/06.52/BiTree.h new file mode 100644 index 0000000..ba89b3e --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.52/LinkQueue.c b/VisualC++/ExerciseBook/06.52/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.52/LinkQueue.h b/VisualC++/ExerciseBook/06.52/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.52/TestData.txt b/VisualC++/ExerciseBook/06.52/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/VisualC++/ExerciseBook/06.52/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.53/06.53.c b/VisualC++/ExerciseBook/06.53/06.53.c new file mode 100644 index 0000000..0e615b1 --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/06.53.c @@ -0,0 +1,87 @@ +#include +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_DEPTH 20 // + +/* + * ѰҸ㵽Ҷӽ·һ + */ +int Algo_6_53(BiTree T, BiTree path[]); + + +int main(int argc, char* argv[]) { + BiTree T; + BiTree way[MAX_TREE_DEPTH] = {NULL}; + int i, n; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("㵽Ҷӽ·һ"); + n = Algo_6_53(T, way); + for(i = 0; i < n; i++) { + printf("%c ", way[i]->data); + } + printf("\n"); + + return 0; +} + + +/* + * ѰҸ㵽Ҷӽ·һ + */ +int Algo_6_53(BiTree T, BiTree path[]) { + int i = -1; + int mark[MAX_TREE_DEPTH] = {0}; // ʱջ + BiTree p; + int depth; + + // ж + depth = BiTreeDepth(T); + + p = T; + + while(TRUE) { + // ȳ + while(p != NULL) { + i++; + + // µǰָ + path[i] = p; + + // ѷʹý + mark[i] = 1; + p = p->lchild; + } + + // ͷж·Ƿ + if(i + 1 == depth) { + return depth; + } + + // ص + p = path[i]; + + // ڣ߸ѱʹصĸ + while(p->rchild == NULL || mark[i] == 2) { + path[i] = NULL; // ÿոλ + + i--; + if(i == -1) { + return 0; + } + + // ˵ + p = path[i]; + } + + // ѷʹý + mark[i] = 2; + p = p->rchild; + } +} diff --git a/VisualC++/ExerciseBook/06.53/06.53.vcxproj b/VisualC++/ExerciseBook/06.53/06.53.vcxproj new file mode 100644 index 0000000..81256f6 --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/06.53.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {FA895CBA-DCA0-4539-B4CE-4E9D79195282} + My0653 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.53/06.53.vcxproj.filters b/VisualC++/ExerciseBook/06.53/06.53.vcxproj.filters new file mode 100644 index 0000000..3d0e72c --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/06.53.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.53/06.53.vcxproj.user b/VisualC++/ExerciseBook/06.53/06.53.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/06.53.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.53/BiTree.c b/VisualC++/ExerciseBook/06.53/BiTree.c new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.53/BiTree.h b/VisualC++/ExerciseBook/06.53/BiTree.h new file mode 100644 index 0000000..ba89b3e --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/BiTree.h @@ -0,0 +1,90 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.53/LinkQueue.c b/VisualC++/ExerciseBook/06.53/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.53/LinkQueue.h b/VisualC++/ExerciseBook/06.53/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.53/TestData.txt b/VisualC++/ExerciseBook/06.53/TestData.txt new file mode 100644 index 0000000..f00a60d --- /dev/null +++ b/VisualC++/ExerciseBook/06.53/TestData.txt @@ -0,0 +1 @@ +СABD^^EG^^^CF^HI^^J^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.54/06.54.c b/VisualC++/ExerciseBook/06.54/06.54.c new file mode 100644 index 0000000..41a7070 --- /dev/null +++ b/VisualC++/ExerciseBook/06.54/06.54.c @@ -0,0 +1,64 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ݶIJдʽ + */ +Status Algo_6_54(BiTree* T, TElemType sa[100]); + + +int main(int argc, char* argv[]) { + BiTree T; + TElemType sa[MAX_TREE_SIZE] = "ABCDEF^G^HI^J"; // + + printf("У...\n"); + Algo_6_54(&T, sa); + PrintGraph(T); + + return 0; +} + + +/* + * ݶIJдʽ + */ +Status Algo_6_54(BiTree* T, TElemType sa[]) { + BiTree tree[MAX_TREE_SIZE]; // ʱűиָĸƷ + int p, i; + + i = 0; + + while(sa[i] != '\0') { + if(sa[i] == '^') { + tree[i] = NULL; + } else { + tree[i] = (BiTree) malloc(sizeof(BiTNode)); + if(tree[i] == NULL) { + exit(OVERFLOW); + } + tree[i]->data = sa[i]; + tree[i]->lchild = tree[i]->rchild = NULL; + } + + if(i > 0) { + p = (i - 1) / 2; // + + // ǰ + if(2 * p + 1 == i) { + tree[p]->lchild = tree[i]; + } else { + tree[p]->rchild = tree[i]; + } + } + + i++; + } + + *T = tree[0]; + + return OK; +} diff --git a/VisualC++/ExerciseBook/06.54/06.54.vcxproj b/VisualC++/ExerciseBook/06.54/06.54.vcxproj new file mode 100644 index 0000000..cd2f771 --- /dev/null +++ b/VisualC++/ExerciseBook/06.54/06.54.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {4A4F7F91-A802-4881-9459-94AAEB825CAF} + My0654 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.54/06.54.vcxproj.filters b/VisualC++/ExerciseBook/06.54/06.54.vcxproj.filters new file mode 100644 index 0000000..81d25d9 --- /dev/null +++ b/VisualC++/ExerciseBook/06.54/06.54.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.54/06.54.vcxproj.user b/VisualC++/ExerciseBook/06.54/06.54.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.54/06.54.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.54/BiTree.c b/VisualC++/ExerciseBook/06.54/BiTree.c new file mode 100644 index 0000000..76327ed --- /dev/null +++ b/VisualC++/ExerciseBook/06.54/BiTree.c @@ -0,0 +1,121 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.54/BiTree.h b/VisualC++/ExerciseBook/06.54/BiTree.h new file mode 100644 index 0000000..d53885f --- /dev/null +++ b/VisualC++/ExerciseBook/06.54/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.54/LinkQueue.c b/VisualC++/ExerciseBook/06.54/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.54/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.54/LinkQueue.h b/VisualC++/ExerciseBook/06.54/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.54/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.55/06.55.c b/VisualC++/ExerciseBook/06.55/06.55.c new file mode 100644 index 0000000..916f194 --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/06.55.c @@ -0,0 +1,64 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* + * ÿĿ + */ +int Algo_6_55(BiTree T); + +// Ŀ +void PreOrderPrint(BiTree T); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("ֵӦĿ\n"); + Algo_6_55(T); + PreOrderPrint(T); + + return 0; +} + + +/* + * ÿĿ + */ +int Algo_6_55(BiTree T) { + int l, r; + + if(T == NULL) { + return 0; + } else { + T->DescNum = 0; + + if(T->lchild != NULL) { + l = Algo_6_55(T->lchild); + T->DescNum += l + 1; + } + + if(T->rchild != NULL) { + r = Algo_6_55(T->rchild); + T->DescNum += r + 1; + } + } + + return T->DescNum; +} + +// Ŀ +void PreOrderPrint(BiTree T) { + if(T != NULL) { + printf(" %c Ŀ %d\n", T->data, T->DescNum); + PreOrderPrint(T->lchild); + PreOrderPrint(T->rchild); + } +} diff --git a/VisualC++/ExerciseBook/06.55/06.55.vcxproj b/VisualC++/ExerciseBook/06.55/06.55.vcxproj new file mode 100644 index 0000000..ccf9289 --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/06.55.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {677775A1-798C-4F33-A703-546AFC56875C} + My0655 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.55/06.55.vcxproj.filters b/VisualC++/ExerciseBook/06.55/06.55.vcxproj.filters new file mode 100644 index 0000000..bd4c62e --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/06.55.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.55/06.55.vcxproj.user b/VisualC++/ExerciseBook/06.55/06.55.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/06.55.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.55/BiTree.c b/VisualC++/ExerciseBook/06.55/BiTree.c new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.55/BiTree.h b/VisualC++/ExerciseBook/06.55/BiTree.h new file mode 100644 index 0000000..425dfa1 --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/BiTree.h @@ -0,0 +1,92 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ + + int DescNum; // ý +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.55/LinkQueue.c b/VisualC++/ExerciseBook/06.55/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.55/LinkQueue.h b/VisualC++/ExerciseBook/06.55/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.55/TestData.txt b/VisualC++/ExerciseBook/06.55/TestData.txt new file mode 100644 index 0000000..ce10094 --- /dev/null +++ b/VisualC++/ExerciseBook/06.55/TestData.txt @@ -0,0 +1 @@ +СABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.c b/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.c new file mode 100644 index 0000000..4cb0485 --- /dev/null +++ b/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.c @@ -0,0 +1,502 @@ +#include +#include "Status.h" //**01 **// +#include "BiThrTree.h" //**06 Ͷ**// + +/* + * Ѱҽpĺ + */ +BiThrTree Algo_6_56(BiThrTree p); + +// ԷAlgo_6_56 +void PreTraverse(BiThrTree Thrt); + + +/* + * ںѰҽpĺ + */ +BiThrTree Algo_6_57(BiThrTree p); + +// ԷAlgo_6_57ĺ +void PosTraverse(BiThrTree Thrt); + + +/* + * ΪxҽxֻȫΪp + * УpڵҲȫThrxָxͷ㡣 + * עpѾժ£޽Ϊx + */ +Status Algo_6_58(BiThrTree p, BiThrTree x, BiThrTree Thrx); + + +// T +Status PreOrderThreading(BiThrTree* Thrt, BiThrTree T); + +// ڲʵ +void PreTheading(BiThrTree p); + +// ǵݹ㷨 +Status PreOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)); + + +// T˳ʼparent +Status PosOrderThreading(BiThrTree* Thrt, BiThrTree T); + +// ڲʵ֣ıʽ +void PosTheading(BiThrTree p); + +// Ժкǵݹ㷨 +Status PosOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)); + + +// ԺӡԪ +Status PrintElem(TElemType c); + + + +int main(int argc, char* argv[]) { + + printf(" 6.56 ֤...\n"); + { + BiThrTree T; // + BiThrTree Thr; // + + printf(" (ABDG^^^EH^^I^^CF^J^^^)...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf(" Զ...\n"); + PreOrderThreading(&Thr, T); + + printf(" "); + PreOrderTraverse_Thr(Thr, PrintElem); + + printf(" ԷAlgo_6_56У"); + PreTraverse(Thr); + } + PressEnterToContinue(); + + + printf(" 6.57 ֤...\n"); + { + BiThrTree T; // + BiThrTree Thr; // + + printf(" (ABDG^^^EH^^I^^CF^J^^^)...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf(" Զк...\n"); + PosOrderThreading(&Thr, T); + + printf(" "); + PosOrderTraverse_Thr(Thr, PrintElem); + + printf(" ԷAlgo_6_57ĺУ"); + PosTraverse(Thr); + } + PressEnterToContinue(); + + + printf(" 6.58 ֤...\n"); + { + BiThrTree T; // + BiThrTree Thr; // ȫ + + BiThrTree Tx; // Ķ + BiThrTree Thrx; // ȫ + + BiThrTree p; + + printf(" (ABDG^^^EH^^I^^CF^J^^^)...\n"); + CreateBiTree(&T, "TestData_T.txt"); + + printf(" Զȫ...\n"); + InOrderThreading(&Thr, T); + + printf(" ȫ"); + InOrderTraverse_Thr(Thr, PrintElem); + + printf(" ===============================================\n"); + + printf(" (012^47^^^35^^68^^9^^^)...\n"); + CreateBiTree(&Tx, "TestData_x.txt"); + + printf(" Զȫ...\n"); + InOrderThreading(&Thrx, Tx); + + printf(" ȫ"); + InOrderTraverse_Thr(Thrx, PrintElem); + + printf(" ===============================================\n"); + + p = T->lchild->rchild; + printf(" ⣬ x 뵽 T %c ...\n", p->data); + Algo_6_58(p, Tx, Thrx); + + printf(" ɺȫΪ"); + InOrderTraverse_Thr(Thr, PrintElem); + } + PressEnterToContinue(); + +} + + + +/* + * Ѱҽpĺ + */ +BiThrTree Algo_6_56(BiThrTree p) { + if(p == NULL) { + return NULL; + } + + // ںֱӻȡϢ + if(p->RTag == Thread) { + p = p->rchild; + } else { + if(p->lchild != NULL) { + p = p->lchild; + } else { + p = p->rchild; + } + } + + return p; +} + +// ԷAlgo_6_56 +void PreTraverse(BiThrTree Thrt) { + BiThrTree p = Thrt->rchild; + + while(p != Thrt) { + printf("%c", p->data); + p = Algo_6_56(p); + } + + printf("\n"); +} + + +/* + * ںѰҽpĺ + */ +BiThrTree Algo_6_57(BiThrTree p) { + if(p == NULL) { + return NULL; + } + + // ںֱӻȡϢ + if(p->RTag == Thread) { + p = p->rchild; + } else { + // ǰ + if(p == p->parent->rchild) { + p = p->parent; + } else { + // ûҺ + if(p->parent->rchild == NULL || p->parent->RTag == Thread) { + p = p->parent; + } else { + p = p->parent->rchild; + + /* ֵܽҶ */ + + while(p->lchild != NULL) { + p = p->lchild; + } + + while(p->rchild != NULL && p->RTag == Link) { + p = p->rchild; + } + } + } + } + + return p; +} + +// ԷAlgo_6_57ĺ +void PosTraverse(BiThrTree Thrt) { + BiThrTree p = Thrt->rchild; + + while(p != Thrt) { + printf("%c", p->data); + p = Algo_6_57(p); + } + + printf("\n"); +} + + +/* + * ΪxҽxֻȫΪp + * УpڵҲȫThrxָxͷ㡣 + * עpѾժ£޽Ϊx + */ +Status Algo_6_58(BiThrTree p, BiThrTree x, BiThrTree Thrx) { + BiThrTree pPre; // pǰ + + BiThrTree xFirst; // xеĵһ + BiThrTree xLast; // xеһ + + BiThrTree lt; // p + BiThrTree ltFirst; // ltеĵһ + + if(p==NULL || x==NULL) { + return ERROR; + } + + // x㲻Һ + if(x->RTag==Link) { + return ERROR; + } + + // ȡxеĵһһ + xFirst = Thrx->lchild; + // һֱ + while(xFirst->LTag==Link){ + xFirst = xFirst->lchild; + } + xLast = Thrx->rchild; + + // p + if(p->LTag==Thread) { + pPre = p->lchild; // ֱӻȡpǰ + + p->LTag = Link; // ޸pΪ + p->lchild = x; // x + + xFirst->lchild = pPre; // xFirst + xLast->rchild = p; // xLast + + // p + } else { + // ָp + lt = p->lchild; + + // ltеĵһ + ltFirst = lt; + // ӣһֱ + while(ltFirst->LTag==Link){ + ltFirst = ltFirst->lchild; + } + + x->RTag = Link; // ltΪx + x->rchild = lt; + + xFirst->lchild = ltFirst->lchild; // ӹlt + ltFirst->lchild = x; // ltָx + + p->lchild = x; // p + } + + // xThrxƳ + Thrx->lchild = Thrx->rchild = Thrx; + + return OK; +} + + +// T +Status PreOrderThreading(BiThrTree* Thrt, BiThrTree T) { + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(*Thrt == NULL) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + (*Thrt)->LTag = Link; + (*Thrt)->RTag = Thread; + (*Thrt)->rchild = NULL; + + // ֻͷ + if(!T) { + (*Thrt)->lchild = (*Thrt)->rchild = *Thrt; + } else { + (*Thrt)->lchild = T; + pre = *Thrt; // ָͷ + + PreTheading(T); // ʼ + + pre->RTag = Thread; // һ + pre->rchild = *Thrt; // һָͷ + + (*Thrt)->rchild = T; // ͷָһ㣬ѭϵ + } + + return OK; +} + +// ڲʵ +void PreTheading(BiThrTree p) { + if(p == NULL) { + return; + } + + // Ϊһ + if(pre->rchild == NULL) { + pre->RTag = Thread; + pre->rchild = p; + } else { + // ΪգLink + pre->RTag = Link; + } + + // preǰŲһ + pre = p; + + // + PreTheading(p->lchild); + + // + if(p->rchild != NULL && p->RTag == Link) { + PreTheading(p->rchild); + } +} + +// ǵݹ㷨 +Status PreOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)) { + BiThrTree p = Thrt; // pָ + + while(p->rchild != Thrt) { + // ʣֱͷ + while(p->lchild != NULL) { + p = p->lchild; + if(Visit(p->data) == ERROR) { + return ERROR; + } + } + + // ʵͷҷʣͨ + if(p->rchild != Thrt) { + p = p->rchild; + if(Visit(p->data) == ERROR) { + return ERROR; + } + } + } + + printf("\n"); + + return OK; +} + + +// T˳ʼparent +Status PosOrderThreading(BiThrTree* Thrt, BiThrTree T) { + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(*Thrt == NULL) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + (*Thrt)->LTag = Link; + (*Thrt)->RTag = Thread; + (*Thrt)->rchild = *Thrt; + + if(T == NULL) { + (*Thrt)->lchild = (*Thrt)->rchild = *Thrt; + } else { + (*Thrt)->lchild = T; + pre = *Thrt; // ָͷ + + T->parent = *Thrt; + + PosTheading(T); // ʼ + + (*Thrt)->rchild = pre; // ͷָһ㣬ѭϵ + } + + return OK; +} + +// ڲʵ֣ıʽ +void PosTheading(BiThrTree p) { + if(p == NULL) { + return; + } + + // Ϊǰ + if(p->rchild == NULL) { + p->RTag = Thread; + p->rchild = pre; + } else { + // ΪգLink + p->RTag = Link; + } + + // pre˳Ϊһ + pre = p; + + // + if(p->RTag != Thread) { + if(p->rchild != NULL) { + p->rchild->parent = p; + } + + PosTheading(p->rchild); + } + + if(p->lchild != NULL) { + p->lchild->parent = p; + } + + // + PosTheading(p->lchild); +} + +// Ժкǵݹ㷨 +Status PosOrderTraverse_Thr(BiThrTree Thrt, Status(Visit)(TElemType)) { + BiThrTree r = Thrt->rchild; // pָһ + BiThrTree p; + + // Ϊ + while(r != Thrt) { + if(Visit(r->data) == ERROR) { + return ERROR; + } + + // ں + if(r->RTag == Thread) { + r = r->rchild; + } else { + p = r->parent; + if(p == Thrt) { + break; // Ѿ + } + + // ǰҺ + if(r == p->rchild) { + r = p; + + // ǰ + } else { + // ҺΪNULL + if(p->rchild == NULL || p->RTag == Thread) { + r = p; + } else { + r = p->rchild; + + /* rҶ */ + + while(r->lchild != NULL) { + r = r->lchild; + } + + while(r->rchild != NULL && r->RTag == Link) { + r = r->rchild; + } + } + } + } + } + + printf("\n"); + + return OK; +} + + +// ԺӡԪ +Status PrintElem(TElemType c) { + printf("%c", c); + return OK; +} diff --git a/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj b/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj new file mode 100644 index 0000000..b65ae4b --- /dev/null +++ b/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {8DEA25B2-B54A-4BDE-A572-20FB86BCD046} + My06560658 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj.filters b/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj.filters new file mode 100644 index 0000000..d444c9a --- /dev/null +++ b/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj.user b/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.56-06.58/06.56-06.58.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.56-06.58/BiThrTree.c b/VisualC++/ExerciseBook/06.56-06.58/BiThrTree.c new file mode 100644 index 0000000..0275869 --- /dev/null +++ b/VisualC++/ExerciseBook/06.56-06.58/BiThrTree.c @@ -0,0 +1,182 @@ +/*======================= + * + * + * 㷨: 6.56.66.7 + ========================*/ + +#include "BiThrTree.h" + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiThrTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * 㷨6.6 + * + * TȫΪThrt + * עǰ + */ +Status InOrderThreading(BiThrTree* Thrt, BiThrTree T) { + // ͷ + *Thrt = (BiThrTree) malloc(sizeof(BiThrNode)); + if(!*Thrt) { + exit(OVERFLOW); + } + + (*Thrt)->data = '\0'; + + (*Thrt)->LTag = Link; // ӣҪָĸ + (*Thrt)->RTag = Thread; // ָ룬ҪָһԪأԱ + + (*Thrt)->rchild = *Thrt; + + // Ϊգָָ + if(!T) { + (*Thrt)->lchild = *Thrt; + } else { + (*Thrt)->lchild = T; // ָͷ + pre = *Thrt; // ¼ǰϢʼΪͷ + + InTheading(T); // Խ + + pre->rchild = *Thrt; // һָͷ + pre->RTag = Thread; // һ + (*Thrt)->rchild = pre; // ͷָһ㣬˫ϵ + } + + return OK; + +} + +/* + * 㷨6.5 + * + * ȫǵݹ㷨 + */ +Status InOrderTraverse_Thr(BiThrTree T, Status(Visit)(TElemType)) { + BiThrTree p = T->lchild; // pָ㣨ͬͷ㣩 + + // ʱp==T + while(p != T) { + // ӣ + while(p->LTag == Link) { + p = p->lchild; + } + + // ΪյĽ㣨ߣ + if(!Visit(p->data)) { + return ERROR; + } + + // ںû + while(p->RTag == Thread && p->rchild != T) { + p = p->rchild; // pָ + Visit(p->data); // ʺ̽ + } + + // + p = p->rchild; + } + + printf("\n"); + + return OK; +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiThrTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiThrTree) malloc(sizeof(BiThrNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + +/* + * 㷨6.7 + * + * ȫڲʵ + */ +static void InTheading(BiThrTree p) { + if(p) { + InTheading(p->lchild); // + + // ǰΪգҪǰ + if(!p->lchild) { + p->LTag = Thread; + p->lchild = pre; + + // Ϊգӱǣ̲ȱһ裩 + } else { + p->LTag = Link; + } + + // ǰΪգΪǰ㽨 + if(!pre->rchild) { + pre->RTag = Thread; + pre->rchild = p; + + // ΪգҺӱǣ̲ȱһ裩 + } else { + p->RTag = Link; + } + + pre = p; // preǰŲһ + + InTheading(p->rchild); // + } +} diff --git a/VisualC++/ExerciseBook/06.56-06.58/BiThrTree.h b/VisualC++/ExerciseBook/06.56-06.58/BiThrTree.h new file mode 100644 index 0000000..386ee99 --- /dev/null +++ b/VisualC++/ExerciseBook/06.56-06.58/BiThrTree.h @@ -0,0 +1,89 @@ +/*======================= + * + * + * 㷨: 6.56.66.7 + ========================*/ + +#ifndef BITHRTREE_H +#define BITHRTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ͱ */ +typedef enum { + Link, Thread // Link==0ָ()Thread==1 +} PointerTag; + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiThrNode { + TElemType data; // Ԫ + struct BiThrNode* lchild; // ָ + struct BiThrNode* rchild; // Һָ + PointerTag LTag; // ָ + PointerTag RTag; // ָ + + struct BiThrNode* parent; // ˫׽ָ룬ڷǵݹʱʹ +} BiThrNode; + +/* ָָ */ +typedef BiThrNode* BiThrTree; + + +/* ȫֱ */ +static BiThrTree pre; // ָǰʽһ㣨ǰ + + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiThrTree* T, char* path); + +/* + * 㷨6.6 + * + * TȫΪThrt + * עǰ + */ +Status InOrderThreading(BiThrTree* Thrt, BiThrTree T); + +/* + * 㷨6.5 + * + * ȫTǵݹ㷨 + */ +Status InOrderTraverse_Thr(BiThrTree T, Status(Visit)(TElemType)); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiThrTree* T, FILE* fp); + +/* + * 㷨6.7 + * + * ȫڲʵ + */ +static void InTheading(BiThrTree p); + +#endif diff --git a/VisualC++/ExerciseBook/06.56-06.58/TestData_T.txt b/VisualC++/ExerciseBook/06.56-06.58/TestData_T.txt new file mode 100644 index 0000000..ca28844 --- /dev/null +++ b/VisualC++/ExerciseBook/06.56-06.58/TestData_T.txt @@ -0,0 +1 @@ +УϵǴս㣩ABDG^^^EH^^I^^CF^J^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.56-06.58/TestData_x.txt b/VisualC++/ExerciseBook/06.56-06.58/TestData_x.txt new file mode 100644 index 0000000..ea3fd92 --- /dev/null +++ b/VisualC++/ExerciseBook/06.56-06.58/TestData_x.txt @@ -0,0 +1 @@ +УϵǴս㣩012^47^^^35^^68^^9^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.c b/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.c new file mode 100644 index 0000000..994ec7f --- /dev/null +++ b/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.c @@ -0,0 +1,173 @@ +#include +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ĸ + */ +void Algo_6_59(CSTree T); + +/* + * Ҷӽ + */ +int Algo_6_60(CSTree T); + +/* + * Ķȣиȵֵ + */ +int Algo_6_61(CSTree T); + +/* + * + */ +int Algo_6_62(CSTree T); + + +int main(int argc, char* argv[]) { + CSTree T; + + printf("УT...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf(" 6.59 ֤...\n"); + { + printf("б...\n"); + Algo_6_59(T); + printf("\n\n"); + } + + printf(" 6.60 ֤...\n"); + { + int count; + + count = Algo_6_60(T); + printf("ҶӽΪcount = %d\n", count); + printf("\n"); + } + + printf(" 6.61 ֤...\n"); + { + int degree; + + degree = Algo_6_61(T); + printf("ĶΪdegree = %d\n", degree); + printf("\n"); + } + + printf(" 6.62 ֤...\n"); + { + int depth; + + depth = Algo_6_62(T); + printf("Ϊdepth = %d\n", depth); + printf("\n"); + } + + return 0; +} + + +/* + * ĸ + */ +void Algo_6_59(CSTree T) { + CSTree p, q; + + if(T == NULL) { + return; + } + + p = T; + q = T->firstchild; + + while(q != NULL) { + printf("(%c, %c) ", p->data, q->data); + q = q->nextsibling; + } + + Algo_6_59(T->firstchild); + Algo_6_59(T->nextsibling); +} + +/* + * Ҷӽ + */ +int Algo_6_60(CSTree T) { + if(T == NULL) { + return 0; + } + + // Ҷӽ + if(T->firstchild == NULL) { + return 1 + Algo_6_60(T->nextsibling); + } else { + return Algo_6_60(T->firstchild) + Algo_6_60(T->nextsibling); + } +} + +/* + * Ķȣиȵֵ + */ +int Algo_6_61(CSTree T) { + CSTree queue[MAX_TREE_SIZE]; // 洢ʹĽ + int parent[MAX_TREE_SIZE]; // 洢ÿĸ + int order[MAX_TREE_SIZE]; // 洢ÿı + CSTree p, r; + int col, max; + int m, n; + int curParent; // ¼ʽĸ + + if(T == NULL || T->firstchild == NULL) { + return 0; + } + + curParent = -2; + max = 0; + + m = n = 0; + + queue[n] = T; + parent[n] = -1; + order[n] = 0; + n++; + + while(m < n) { + p = queue[m]; + + // µĸ + if(parent[m] != curParent) { + curParent = parent[m]; + col = 1; // + } else { + col++; + } + + if(col > max) { + max = col; + } + + // 洢ӽ + for(r = p->firstchild; r != NULL; r = r->nextsibling) { + queue[n] = r; + parent[n] = order[m]; // Ϊӽ洢 + order[n] = n; // ¼ǰı + n++; + } + + m++; + } + + return max; +} + +/* + * + */ +int Algo_6_62(CSTree T) { + return TreeDepth(T); // Ѷ +} diff --git a/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj b/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj new file mode 100644 index 0000000..046a9cb --- /dev/null +++ b/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {FA787FE3-301A-41E0-B5CE-C7E30C30A718} + My06590662 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj.filters b/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj.filters new file mode 100644 index 0000000..4a65dbb --- /dev/null +++ b/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj.user b/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.59-06.62/06.59-06.62.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.59-06.62/CSTree.c b/VisualC++/ExerciseBook/06.59-06.62/CSTree.c new file mode 100644 index 0000000..64d258f --- /dev/null +++ b/VisualC++/ExerciseBook/06.59-06.62/CSTree.c @@ -0,0 +1,166 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CSTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûкӽûֵܽڵ㣬ʹ^棺"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CSTree T) { + int max = 0; + + Depth(T, 0, &max); + + return max; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CSTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (CSTree) malloc(sizeof(CSNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + Create(&((*T)->firstchild), fp); // + Create(&((*T)->nextsibling), fp); // ֵ + } +} + +// ȵڲʵ +static void Depth(CSTree T, int d, int* max) { + if(T == NULL) { + return; + } + + d++; // ָʾǰڵIJ + + if(d > *max) { + *max = d; + } + + Depth(T->firstchild, d, max); // ± + Depth(T->nextsibling, --d, max); // ұ +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/VisualC++/ExerciseBook/06.59-06.62/CSTree.h b/VisualC++/ExerciseBook/06.59-06.62/CSTree.h new file mode 100644 index 0000000..3d95beb --- /dev/null +++ b/VisualC++/ExerciseBook/06.59-06.62/CSTree.h @@ -0,0 +1,87 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CSTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CSTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CSTree* T, FILE* fp); + +// ȵڲʵ +static void Depth(CSTree T, int d, int *max); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/VisualC++/ExerciseBook/06.59-06.62/TestData.txt b/VisualC++/ExerciseBook/06.59-06.62/TestData.txt new file mode 100644 index 0000000..0b1431c --- /dev/null +++ b/VisualC++/ExerciseBook/06.59-06.62/TestData.txt @@ -0,0 +1 @@ +RAD^E^^B^CFG^H^K^^^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.63/06.63.c b/VisualC++/ExerciseBook/06.63/06.63.c new file mode 100644 index 0000000..dc1592e --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/06.63.c @@ -0,0 +1,32 @@ +#include +#include "Status.h" //**01 **// +#include "CTree.h" //**06 Ͷ**// + +/* + * 㺢ʾ + */ +int Algo_6_63(CTree T); + + +int main(int argc, char* argv[]) { + CTree T; + + printf("T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("Ϊ %d\n", Algo_6_63(T)); + printf("\n"); + + return 0; +} + + +/* + * 㺢ʾ + */ +int Algo_6_63(CTree T) { + return TreeDepth(T); // Ѷ +} diff --git a/VisualC++/ExerciseBook/06.63/06.63.vcxproj b/VisualC++/ExerciseBook/06.63/06.63.vcxproj new file mode 100644 index 0000000..df21201 --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/06.63.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {E0214AC8-3D49-4540-9D41-B9FAF1C7504E} + My0663 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.63/06.63.vcxproj.filters b/VisualC++/ExerciseBook/06.63/06.63.vcxproj.filters new file mode 100644 index 0000000..ba219e8 --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/06.63.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.63/06.63.vcxproj.user b/VisualC++/ExerciseBook/06.63/06.63.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/06.63.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.63/CTree.c b/VisualC++/ExerciseBook/06.63/CTree.c new file mode 100644 index 0000000..d2c194a --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/CTree.c @@ -0,0 +1,405 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#include "CTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("ԪϢڿս㣬ʹ^...\n"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T) { + int k, level; + + // + if(TreeEmpty(T)) { + return 0; + } + + /* + * kʼΪһλ + * Ľ㰴洢洢Ľضλ + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CTree* T, FILE* fp) { + int r; // ĸλã + int n; // ¼Ԫ + int cur; // α + TElemType ch; + LinkQueue Q; + QElemType e; // Ԫָʾλ + char s[MAX_CHILD_COUNT + 1]; + int i; + ChildPtr p, pc; + + InitQueue(&Q); + + n = 0; + + // ȡλ + if(fp == NULL) { + printf("λ(0~%d)", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("ֵ"); + scanf("%s", s); + ch = s[0]; + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // λó + + printf(" %c ĺӽ㣬ںʱһ^", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // ij + p = T->nodes[e].firstchild; + + // װǰ + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // ǰӵĺ + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // ҵβ + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // ¼λ + ReadData(fp, "%d", &r); + cur = r; + + // ¼ֵ + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ֵ%c\n", ch); + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ %c ĺӣ", ch); + + // ¼뺢ӽ + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // λó + + // + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // װǰ + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // ij + p = T->nodes[e].firstchild; + + // ǰӵĺ + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // ҵβ + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // λ + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // ڵIJ + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // ˸ı + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // eĺӼ0 + + // ÿʱһϢΪЧΪÿ㶼кӽ + pt[e].lastChild = -1; + + // ָýĺ + cp = T.nodes[e].firstchild; + + // ͷŸý㴦ĺռڴ + while(cp != NULL) { + // ǰλ + EnQueue(&Q, cp->child); + + // ¼ + pt[cp->child].row = pt[e].row + 1; + + // ¼ + pt[cp->child].col = ++count; + + // ¼ǰǵڼ + pt[cp->child].childIndex = ++n; + + // ΪһӵϢ + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework(T); +} + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // ʼΪЧ + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + // ˫ױ洢ṹӸ + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/VisualC++/ExerciseBook/06.63/CTree.h b/VisualC++/ExerciseBook/06.63/CTree.h new file mode 100644 index 0000000..873504b --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/CTree.h @@ -0,0 +1,129 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* ӽ㶨 */ +typedef struct CTNode { + int child; // úе + struct CTNode* next; // ָһ +} CTNode; + +/* ָӽָ */ +typedef CTNode* ChildPtr; + +/* (˫)Ľ㶨 */ +typedef struct { + int parent; // ˫λ + TElemType data; // ǰ + ChildPtr firstchild; // ͷָ +} CTBox; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} CTree; + + +/* + * ijϢ + * + * ע˫ױ洢ṹҪټǰĵһе + * */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CTree* T, FILE* fp); + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T); + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework(CTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.63/LinkQueue.c b/VisualC++/ExerciseBook/06.63/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.63/LinkQueue.h b/VisualC++/ExerciseBook/06.63/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.63/TestData.txt b/VisualC++/ExerciseBook/06.63/TestData.txt new file mode 100644 index 0000000..5786a62 --- /dev/null +++ b/VisualC++/ExerciseBook/06.63/TestData.txt @@ -0,0 +1,12 @@ +λã5 +ֵR +Rĺӽ㣺ABC +Aĺӽ㣺DE +Bĺӽ㣺^ +Cĺӽ㣺F +Dĺӽ㣺^ +Eĺӽ㣺^ +Fĺӽ㣺GHK +Gĺӽ㣺^ +Hĺӽ㣺^ +Kĺӽ㣺^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.64/06.64.c b/VisualC++/ExerciseBook/06.64/06.64.c new file mode 100644 index 0000000..2af54e0 --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/06.64.c @@ -0,0 +1,32 @@ +#include +#include "Status.h" //**01 **// +#include "PTree.h" //**06 Ͷ**// + +/* + * ˫ױʾ + */ +int Algo_6_64(PTree T); + + +int main(int argc, char* argv[]) { + PTree T; + + printf("T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("Ϊ %d\n", Algo_6_64(T)); + printf("\n"); + + return 0; +} + + +/* + * ˫ױʾ + */ +int Algo_6_64(PTree T) { + return TreeDepth(T); // Ѷ +} diff --git a/VisualC++/ExerciseBook/06.64/06.64.vcxproj b/VisualC++/ExerciseBook/06.64/06.64.vcxproj new file mode 100644 index 0000000..55ac023 --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/06.64.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {3A17210B-9672-442C-BC4C-235740FEFFC0} + My0664 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.64/06.64.vcxproj.filters b/VisualC++/ExerciseBook/06.64/06.64.vcxproj.filters new file mode 100644 index 0000000..686f78a --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/06.64.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.64/06.64.vcxproj.user b/VisualC++/ExerciseBook/06.64/06.64.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/06.64.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.64/LinkList.c b/VisualC++/ExerciseBook/06.64/LinkList.c new file mode 100644 index 0000000..4774f33 --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/LinkList.c @@ -0,0 +1,163 @@ +/*=============================== + * Աʽ洢ṹ + * + * 㷨: 2.82.92.102.11 + ================================*/ + +#include "LinkList.h" //**02 Ա**// + +/* + * ʼ + * + * ֻdzʼһͷ㡣 + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(LinkList* L) { + (*L) = (LinkList) malloc(sizeof(LNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + (*L)->next = NULL; + + return OK; +} + +/* + * (ṹ) + * + * ͷռڴ棬ͷҲᱻ + */ +Status DestroyList(LinkList* L) { + LinkList p; + + // ȷṹ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + + while(p != NULL) { + p = (*L)->next; + free(*L); + (*L) = p; + } + + *L = NULL; + + return OK; +} + +/* + * ÿ() + * + * Ҫͷзͷ㴦Ŀռ䡣 + */ +Status ClearList(LinkList L) { + LinkList pre, p; + + // ȷ + if(L == NULL) { + return ERROR; + } + + p = L->next; + + // ͷнռڴ + while(p != NULL) { + pre = p; + p = p->next; + free(pre); + } + + L->next = NULL; + + return OK; +} + +/* + * + * + * ׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + LinkList p; + + // ȷҲΪձ + if(L == NULL || L->next == NULL) { + return 0; + } + + i = 1; // iijֵΪ1Ԫصλ + p = L->next; // pijֵΪ1Ԫصָ + + while(p != NULL && !Compare(p->data, e)) { + i++; + p = p->next; + } + + if(p != NULL) { + return i; + } else { + return 0; + } +} + +/* + * 㷨2.9 + * + * + * + * iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(LinkList L, int i, ElemType e) { + LinkList p, s; + int j; + + // ȷ + if(L == NULL) { + return ERROR; + } + + p = L; + j = 0; + + // Ѱҵi-1㣬ұ֤ý㱾ΪNULL + while(p != NULL && j < i - 1) { + p = p->next; + ++j; + } + + // ͷˣiֵϹ(i<=0)˵ûҵϺĿĽ + if(p == NULL || j > i - 1) { + return ERROR; + } + + // ½ + s = (LinkList) malloc(sizeof(LNode)); + if(s == NULL) { + exit(OVERFLOW); + } + s->data = e; + s->next = p->next; + p->next = s; + + return OK; +} + + +/* */ + +// жԱԪǷ +Status Equal(ElemType e1, ElemType e2) { + return e1 == e2 ? TRUE : FALSE; +} diff --git a/VisualC++/ExerciseBook/06.64/LinkList.h b/VisualC++/ExerciseBook/06.64/LinkList.h new file mode 100644 index 0000000..b2fb1fc --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/LinkList.h @@ -0,0 +1,82 @@ +/*=============================== + * Աʽ洢ṹ + * + * 㷨: 2.82.92.102.11 + ================================*/ + +#ifndef LINKLIST_H +#define LINKLIST_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int ElemType; + +/* + * ṹ + * + * עĵͷ + */ +typedef struct LNode { + ElemType data; // ݽ + struct LNode* next; // ָһָ +} LNode; + +// ָָ +typedef LNode* LinkList; + + +/* + * ʼ + * + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(LinkList* L); + +/* + * (ṹ) + * + * ͷռڴ档 + */ +Status DestroyList(LinkList* L); + +/* + * ÿ() + * + * Ҫͷзͷ㴦Ŀռ䡣 + */ +Status ClearList(LinkList L); + +/* + * + * + * ׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * 㷨2.9 + * + * + * + * iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(LinkList L, int i, ElemType e); + + +/* */ + +// жԱԪǷ +Status Equal(ElemType e1, ElemType e2); + +#endif diff --git a/VisualC++/ExerciseBook/06.64/LinkQueue.c b/VisualC++/ExerciseBook/06.64/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.64/LinkQueue.h b/VisualC++/ExerciseBook/06.64/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.64/PTree.c b/VisualC++/ExerciseBook/06.64/PTree.c new file mode 100644 index 0000000..69fd054 --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/PTree.c @@ -0,0 +1,348 @@ +/*================== + * ˫ױ洢ʾ + ===================*/ + +#include "PTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(PTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(PTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("ԪϢڿս㣬ʹ^...\n"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(PTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(PTree T) { + int k, level; + + // + if(TreeEmpty(T)) { + return 0; + } + + /* + * kʼΪһλ + * Ľ㰴洢洢Ľضλ + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(PTree* T, FILE* fp) { + int r; // ĸλã + int n; // ¼Ԫ + int cur; // α + TElemType ch; + LinkQueue Q; + QElemType e; // Ԫָʾλ + char s[MAX_CHILD_COUNT + 1]; + int i; + + InitQueue(&Q); + + n = 0; + + // ȡλ + if(fp == NULL) { + printf("λ(0~%d)", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("ֵ"); + scanf("%s", s); + ch = s[0]; + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // λó + + printf(" %c ĺӽ㣬ںʱһ^", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // ¼λ + ReadData(fp, "%d", &r); + cur = r; + + // ¼ֵ + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ֵ%c\n", ch); + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ %c ĺӣ", ch); + + // ¼뺢ӽ + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // λó + + // + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(PTree T, Pos pt[]) { + LinkList Lt, Lt_parent, Lt_child; + int m, n, p, k, s; + int level; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty(T)) { + return; + } + + InitList(&Lt_parent); + InitList(&Lt_child); + + // parentΪ-1 + ListInsert(Lt_parent, 1, -1); + + level = 1; + k = T.r; + m = n = 0; + s = -1; // ʼͷĸΪ-1 + + while(k != (T.r + T.n) % MAX_TREE_SIZE) { + // kһеʼΪ-1 + pt[k].firstChild = -1; + + // kһеʼΪ-1 + pt[k].lastChild = -1; + + // ǰkĸ + p = T.nodes[k].parent; + if(p != s) { + s = p; // ׷ٸı仯 + n = 0; // ıʱҪ¼ + } + + // жϵǰǷΪlevel-1ĺ + if(LocateElem(Lt_parent, p, Equal)) { + ListInsert(Lt_child, ++m, k); + + pt[k].row = level; + pt[k].col = m; + pt[k].childIndex = ++n; + + // ȷǰ㸸 + if(p != -1) { + // һе + if(pt[p].firstChild==-1) { + pt[p].firstChild = k; + } + + // һе + pt[p].lastChild = k; + } + + k = (k + 1) % MAX_TREE_SIZE; + } else { + Lt = Lt_parent; + Lt_parent = Lt_child; + Lt_child = Lt; + ClearList(Lt_child); + + level++; + m = 0; + } + } + + DestroyList(&Lt_parent); + DestroyList(&Lt_child); +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(PTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework(T); +} + +// ͼλǰṹڲʵ +static void Print(PTree T, Pos pt[], int i) { + int firstChild; + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + firstChild = pt[i].firstChild; + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework(PTree T) { + int k; + + if(T.n == 0) { + printf("\n"); + return; + } + + printf("+---------+\n"); + printf("| i e p |\n"); + printf("+---------+\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + printf("| %2d %c %2d |\n", k, T.nodes[k].data, T.nodes[k].parent); + } + + printf("+---------+\n"); +} diff --git a/VisualC++/ExerciseBook/06.64/PTree.h b/VisualC++/ExerciseBook/06.64/PTree.h new file mode 100644 index 0000000..c47c6ed --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/PTree.h @@ -0,0 +1,117 @@ +/*================== + * ˫ױ洢ʾ + ===================*/ + +#ifndef PTREE_H +#define PTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkList.h" //**02 Ա**// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (˫)Ľ㶨 */ +typedef struct PTNode { + TElemType data; + int parent; // ˫λ +} PTNode; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + PTNode nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} PTree; + + +/* ijϢ */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int firstChild; // ǰĵһе + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree(PTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(PTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(PTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(PTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(PTree* T, FILE* fp); + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(PTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(PTree T); + +// ͼλǰṹڲʵ +static void Print(PTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework(PTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.64/TestData.txt b/VisualC++/ExerciseBook/06.64/TestData.txt new file mode 100644 index 0000000..5786a62 --- /dev/null +++ b/VisualC++/ExerciseBook/06.64/TestData.txt @@ -0,0 +1,12 @@ +λã5 +ֵR +Rĺӽ㣺ABC +Aĺӽ㣺DE +Bĺӽ㣺^ +Cĺӽ㣺F +Dĺӽ㣺^ +Eĺӽ㣺^ +Fĺӽ㣺GHK +Gĺӽ㣺^ +Hĺӽ㣺^ +Kĺӽ㣺^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.65/06.65.c b/VisualC++/ExerciseBook/06.65/06.65.c new file mode 100644 index 0000000..58c798b --- /dev/null +++ b/VisualC++/ExerciseBook/06.65/06.65.c @@ -0,0 +1,85 @@ +#include +#include // ṩstrlenԭ +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ȫֱ */ +char Pre[] = "ABDGEHICFJ"; // ǰ +char In[] = "GDBHEIAFJC"; // + +/* + * ǰкй + */ +Status Algo_6_65(BiTree* T); + +// ڲʵ +BiTree BuildTree(int pre_start, int pre_end, int in_start, int in_end); //ݹ鴴 + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("Ϊ%s\n", Pre); + printf("Ϊ%s\n", In); + printf("\n"); + + printf("ɴ˹ĶΪ T = \n"); + Algo_6_65(&T); + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * ǰкй + */ +Status Algo_6_65(BiTree* T) { + int len_pre, len_in; + + len_pre = strlen(Pre); + len_in = strlen(In); + + if(len_pre == 0 || len_in == 0 || len_pre != len_in) { + return ERROR; + } + + *T = BuildTree(0, len_pre - 1, 0, len_in - 1); + + return OK; +} + +// ڲʵ +BiTree BuildTree(int pre_start, int pre_end, int in_start, int in_end) { + BiTree T; + int i, LTreeLen, RTreeLen; + + T = (BiTree) malloc(sizeof(BiTNode)); // + if(T == NULL) { + exit(OVERFLOW); + } + T->data = Pre[pre_start]; // ǰ洢Ľ + T->lchild = T->rchild = NULL; // ʼʱÿҺָ + + i = in_start; + while(In[i] != T->data) { // ѰҸλ + i++; + } + + LTreeLen = i - in_start; // + RTreeLen = in_end - i; // + + // + if(LTreeLen) { + T->lchild = BuildTree(pre_start + 1, pre_start + LTreeLen, in_start, i - 1); + } + + // + if(RTreeLen) { + T->rchild = BuildTree(pre_start + LTreeLen + 1, pre_end, i + 1, in_end); + } + + return T; +} diff --git a/VisualC++/ExerciseBook/06.65/06.65.vcxproj b/VisualC++/ExerciseBook/06.65/06.65.vcxproj new file mode 100644 index 0000000..e323ccb --- /dev/null +++ b/VisualC++/ExerciseBook/06.65/06.65.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {72640607-3DA1-4DA7-A377-75D9B0891E56} + My0665 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.65/06.65.vcxproj.filters b/VisualC++/ExerciseBook/06.65/06.65.vcxproj.filters new file mode 100644 index 0000000..ffc6446 --- /dev/null +++ b/VisualC++/ExerciseBook/06.65/06.65.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.65/06.65.vcxproj.user b/VisualC++/ExerciseBook/06.65/06.65.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.65/06.65.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.65/BiTree.c b/VisualC++/ExerciseBook/06.65/BiTree.c new file mode 100644 index 0000000..76327ed --- /dev/null +++ b/VisualC++/ExerciseBook/06.65/BiTree.c @@ -0,0 +1,121 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.65/BiTree.h b/VisualC++/ExerciseBook/06.65/BiTree.h new file mode 100644 index 0000000..d53885f --- /dev/null +++ b/VisualC++/ExerciseBook/06.65/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.65/LinkQueue.c b/VisualC++/ExerciseBook/06.65/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.65/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.65/LinkQueue.h b/VisualC++/ExerciseBook/06.65/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.65/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.66/06.66.c b/VisualC++/ExerciseBook/06.66/06.66.c new file mode 100644 index 0000000..df12be3 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/06.66.c @@ -0,0 +1,74 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "PTree.h" //**06 Ͷ**// +#include "CSTree.h" //**06 Ͷ**// + +/* + * ˫ױʾתΪĺ-ֵܱʾ + */ +CSTree Algo_6_66(PTree T); + + +int main(int argc, char* argv[]) { + PTree PT; + CSTree CST; + + printf("T...\n"); + InitTree_P(&PT); + CreateTree_P(&PT, "TestData.txt"); + PrintGraph_P(PT); + printf("\n"); + + printf("˫ױʾתΪĺ-ֵܱʾ\n"); + CST = Algo_6_66(PT); + PrintGraph_CS(CST); + printf("\n"); + + return 0; +} + + +/* + * ˫ױʾתΪĺ-ֵܱʾ + */ +CSTree Algo_6_66(PTree T) { + CSTree p, q; + CSTree tree[MAX_TREE_SIZE] = {NULL}; + int i, j, k; + + // ˫ױ洢 + for(i = T.r, j = T.r; i != (T.r + T.n) % MAX_TREE_SIZE; i = (i + 1) % MAX_TREE_SIZE) { + // ȡýĸ + k = T.nodes[i].parent; + + // ƽϢ + p = (CSTree) malloc(sizeof(CSNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->data = T.nodes[i].data; + p->firstchild = p->nextsibling = NULL; + + // ǰڸ + if(k != -1) { + // ǰΪ˵һ + if(tree[k]->firstchild == NULL) { + tree[k]->firstchild = p; + + // ǰ㲻ǵһӣȲ丸ĺβ + } else { + for(q = tree[k]->firstchild; q->nextsibling != NULL; q = q->nextsibling) { + // ѰҺĩ + } + + q->nextsibling = p; + } + } + + tree[j] = p; + j = (j + 1) % MAX_TREE_SIZE; + } + + return tree[T.r]; +} diff --git a/VisualC++/ExerciseBook/06.66/06.66.vcxproj b/VisualC++/ExerciseBook/06.66/06.66.vcxproj new file mode 100644 index 0000000..07489cf --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/06.66.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {3899C603-022F-4A7C-869E-76975D077D5C} + My0666 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.66/06.66.vcxproj.filters b/VisualC++/ExerciseBook/06.66/06.66.vcxproj.filters new file mode 100644 index 0000000..c64941b --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/06.66.vcxproj.filters @@ -0,0 +1,53 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.66/06.66.vcxproj.user b/VisualC++/ExerciseBook/06.66/06.66.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/06.66.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.66/CSTree.c b/VisualC++/ExerciseBook/06.66/CSTree.c new file mode 100644 index 0000000..a121656 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/CSTree.c @@ -0,0 +1,67 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree_CS(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty_CS(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// ͼλʽǰṹ +void PrintGraph_CS(CSTree T) { + + // + if(TreeEmpty_CS(T)) { + printf("\n"); + return; + } + + Print_CS(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print_CS(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print_CS(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print_CS(T->nextsibling, row); + } +} diff --git a/VisualC++/ExerciseBook/06.66/CSTree.h b/VisualC++/ExerciseBook/06.66/CSTree.h new file mode 100644 index 0000000..2899652 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree_CS(CSTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty_CS(CSTree T); + +// ͼλʽǰṹ +void PrintGraph_CS(CSTree T); + +// ͼλǰṹڲʵ +static void Print_CS(CSTree T, int row); + +#endif diff --git a/VisualC++/ExerciseBook/06.66/LinkList.c b/VisualC++/ExerciseBook/06.66/LinkList.c new file mode 100644 index 0000000..4774f33 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/LinkList.c @@ -0,0 +1,163 @@ +/*=============================== + * Աʽ洢ṹ + * + * 㷨: 2.82.92.102.11 + ================================*/ + +#include "LinkList.h" //**02 Ա**// + +/* + * ʼ + * + * ֻdzʼһͷ㡣 + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(LinkList* L) { + (*L) = (LinkList) malloc(sizeof(LNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + (*L)->next = NULL; + + return OK; +} + +/* + * (ṹ) + * + * ͷռڴ棬ͷҲᱻ + */ +Status DestroyList(LinkList* L) { + LinkList p; + + // ȷṹ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + + while(p != NULL) { + p = (*L)->next; + free(*L); + (*L) = p; + } + + *L = NULL; + + return OK; +} + +/* + * ÿ() + * + * Ҫͷзͷ㴦Ŀռ䡣 + */ +Status ClearList(LinkList L) { + LinkList pre, p; + + // ȷ + if(L == NULL) { + return ERROR; + } + + p = L->next; + + // ͷнռڴ + while(p != NULL) { + pre = p; + p = p->next; + free(pre); + } + + L->next = NULL; + + return OK; +} + +/* + * + * + * ׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + LinkList p; + + // ȷҲΪձ + if(L == NULL || L->next == NULL) { + return 0; + } + + i = 1; // iijֵΪ1Ԫصλ + p = L->next; // pijֵΪ1Ԫصָ + + while(p != NULL && !Compare(p->data, e)) { + i++; + p = p->next; + } + + if(p != NULL) { + return i; + } else { + return 0; + } +} + +/* + * 㷨2.9 + * + * + * + * iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(LinkList L, int i, ElemType e) { + LinkList p, s; + int j; + + // ȷ + if(L == NULL) { + return ERROR; + } + + p = L; + j = 0; + + // Ѱҵi-1㣬ұ֤ý㱾ΪNULL + while(p != NULL && j < i - 1) { + p = p->next; + ++j; + } + + // ͷˣiֵϹ(i<=0)˵ûҵϺĿĽ + if(p == NULL || j > i - 1) { + return ERROR; + } + + // ½ + s = (LinkList) malloc(sizeof(LNode)); + if(s == NULL) { + exit(OVERFLOW); + } + s->data = e; + s->next = p->next; + p->next = s; + + return OK; +} + + +/* */ + +// жԱԪǷ +Status Equal(ElemType e1, ElemType e2) { + return e1 == e2 ? TRUE : FALSE; +} diff --git a/VisualC++/ExerciseBook/06.66/LinkList.h b/VisualC++/ExerciseBook/06.66/LinkList.h new file mode 100644 index 0000000..b2fb1fc --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/LinkList.h @@ -0,0 +1,82 @@ +/*=============================== + * Աʽ洢ṹ + * + * 㷨: 2.82.92.102.11 + ================================*/ + +#ifndef LINKLIST_H +#define LINKLIST_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int ElemType; + +/* + * ṹ + * + * עĵͷ + */ +typedef struct LNode { + ElemType data; // ݽ + struct LNode* next; // ָһָ +} LNode; + +// ָָ +typedef LNode* LinkList; + + +/* + * ʼ + * + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(LinkList* L); + +/* + * (ṹ) + * + * ͷռڴ档 + */ +Status DestroyList(LinkList* L); + +/* + * ÿ() + * + * Ҫͷзͷ㴦Ŀռ䡣 + */ +Status ClearList(LinkList L); + +/* + * + * + * ׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(LinkList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * 㷨2.9 + * + * + * + * iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(LinkList L, int i, ElemType e); + + +/* */ + +// жԱԪǷ +Status Equal(ElemType e1, ElemType e2); + +#endif diff --git a/VisualC++/ExerciseBook/06.66/LinkQueue.c b/VisualC++/ExerciseBook/06.66/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.66/LinkQueue.h b/VisualC++/ExerciseBook/06.66/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.66/PTree.c b/VisualC++/ExerciseBook/06.66/PTree.c new file mode 100644 index 0000000..9ea6921 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/PTree.c @@ -0,0 +1,320 @@ +/*================== + * ˫ױ洢ʾ + ===================*/ + +#include "PTree.h" + +/* + * ʼ + * + * + */ +Status InitTree_P(PTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree_P(PTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("ԪϢڿս㣬ʹ^...\n"); + Create_P(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create_P(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty_P(PTree T) { + return T.n == 0 ? TRUE : FALSE; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create_P(PTree* T, FILE* fp) { + int r; // ĸλã + int n; // ¼Ԫ + int cur; // α + TElemType ch; + LinkQueue Q; + QElemType e; // Ԫָʾλ + char s[MAX_CHILD_COUNT + 1]; + int i; + + InitQueue(&Q); + + n = 0; + + // ȡλ + if(fp == NULL) { + printf("λ(0~%d)", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("ֵ"); + scanf("%s", s); + ch = s[0]; + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // λó + + printf(" %c ĺӽ㣬ںʱһ^", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // ¼λ + ReadData(fp, "%d", &r); + cur = r; + + // ¼ֵ + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ֵ%c\n", ch); + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ %c ĺӣ", ch); + + // ¼뺢ӽ + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // λó + + // + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// ȡTĽϢЩϢPos͵Ķ +static void getPos_P(PTree T, Pos pt[]) { + LinkList Lt, Lt_parent, Lt_child; + int m, n, p, k, s; + int level; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty_P(T)) { + return; + } + + InitList(&Lt_parent); + InitList(&Lt_child); + + // parentΪ-1 + ListInsert(Lt_parent, 1, -1); + + level = 1; + k = T.r; + m = n = 0; + s = -1; // ʼͷĸΪ-1 + + while(k != (T.r + T.n) % MAX_TREE_SIZE) { + // kһеʼΪ-1 + pt[k].firstChild = -1; + + // kһеʼΪ-1 + pt[k].lastChild = -1; + + // ǰkĸ + p = T.nodes[k].parent; + if(p != s) { + s = p; // ׷ٸı仯 + n = 0; // ıʱҪ¼ + } + + // жϵǰǷΪlevel-1ĺ + if(LocateElem(Lt_parent, p, Equal)) { + ListInsert(Lt_child, ++m, k); + + pt[k].row = level; + pt[k].col = m; + pt[k].childIndex = ++n; + + // ȷǰ㸸 + if(p != -1) { + // һе + if(pt[p].firstChild==-1) { + pt[p].firstChild = k; + } + + // һе + pt[p].lastChild = k; + } + + k = (k + 1) % MAX_TREE_SIZE; + } else { + Lt = Lt_parent; + Lt_parent = Lt_child; + Lt_child = Lt; + ClearList(Lt_child); + + level++; + m = 0; + } + } + + DestroyList(&Lt_parent); + DestroyList(&Lt_child); +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph_P(PTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty_P(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos_P(T, pt); + + Print_P(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework_P(T); +} + +// ͼλǰṹڲʵ +static void Print_P(PTree T, Pos pt[], int i) { + int firstChild; + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + firstChild = pt[i].firstChild; + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print_P(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print_P(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework_P(PTree T) { + int k; + + if(T.n == 0) { + printf("\n"); + return; + } + + printf("+---------+\n"); + printf("| i e p |\n"); + printf("+---------+\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + printf("| %2d %c %2d |\n", k, T.nodes[k].data, T.nodes[k].parent); + } + + printf("+---------+\n"); +} diff --git a/VisualC++/ExerciseBook/06.66/PTree.h b/VisualC++/ExerciseBook/06.66/PTree.h new file mode 100644 index 0000000..9bf3676 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/PTree.h @@ -0,0 +1,110 @@ +/*================== + * ˫ױ洢ʾ + ===================*/ + +#ifndef PTREE_H +#define PTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkList.h" //**02 Ա**// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (˫)Ľ㶨 */ +typedef struct PTNode { + TElemType data; + int parent; // ˫λ +} PTNode; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + PTNode nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} PTree; + + +/* ijϢ */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int firstChild; // ǰĵһе + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree_P(PTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree_P(PTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty_P(PTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create_P(PTree* T, FILE* fp); + +// ȡTĽϢЩϢPos͵Ķ +static void getPos_P(PTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph_P(PTree T); + +// ͼλǰṹڲʵ +static void Print_P(PTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework_P(PTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.66/TestData.txt b/VisualC++/ExerciseBook/06.66/TestData.txt new file mode 100644 index 0000000..5786a62 --- /dev/null +++ b/VisualC++/ExerciseBook/06.66/TestData.txt @@ -0,0 +1,12 @@ +λã5 +ֵR +Rĺӽ㣺ABC +Aĺӽ㣺DE +Bĺӽ㣺^ +Cĺӽ㣺F +Dĺӽ㣺^ +Eĺӽ㣺^ +Fĺӽ㣺GHK +Gĺӽ㣺^ +Hĺӽ㣺^ +Kĺӽ㣺^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.67/06.67.c b/VisualC++/ExerciseBook/06.67/06.67.c new file mode 100644 index 0000000..e971e1c --- /dev/null +++ b/VisualC++/ExerciseBook/06.67/06.67.c @@ -0,0 +1,84 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ĺ-ֵܽṹ + */ +Status Algo_6_67(CSTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf("-ֵܶ\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_67(&T, fp); + fclose(fp); + printf("\n"); + + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * ĺ-ֵܽṹ + */ +Status Algo_6_67(CSTree* T, FILE* fp) { + char input[3]; + CSTree tree[MAX_TREE_SIZE]; // ˳洢ÿ + CSTree p, q; + int m, n, count; + + m = n = 0; + count = 0; + + while(TRUE) { + printf("¼ %2d Ԫ飺", ++count); + ReadData(fp, "%s", input); + printf("%s\n", input); + + // ˳־ + if(input[1] == '^') { + return OK; + } + + p = (CSTree) malloc(sizeof(CSNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->data = input[1]; // ǰϢ + p->firstchild = p->nextsibling = NULL; + + // + if(input[0] == '^') { + *T = p; + } else { + // Ҹtreeеλ + while(tree[m]->data != input[0]) { + m++; + } + + // ǰΪһ + if(tree[m]->firstchild == NULL) { + tree[m]->firstchild = p; + } else { + for(q = tree[m]->firstchild; q->nextsibling != NULL; q = q->nextsibling) { + // ѰҺĩ + } + + // 뵱ǰ + q->nextsibling = p; + } + } + + tree[n++] = p; + } +} diff --git a/VisualC++/ExerciseBook/06.67/06.67.vcxproj b/VisualC++/ExerciseBook/06.67/06.67.vcxproj new file mode 100644 index 0000000..3922558 --- /dev/null +++ b/VisualC++/ExerciseBook/06.67/06.67.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {FD67F164-0E8B-47CA-BA37-BCD17525D7DF} + My0667 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.67/06.67.vcxproj.filters b/VisualC++/ExerciseBook/06.67/06.67.vcxproj.filters new file mode 100644 index 0000000..51cfcb2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.67/06.67.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.67/06.67.vcxproj.user b/VisualC++/ExerciseBook/06.67/06.67.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.67/06.67.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.67/CSTree.c b/VisualC++/ExerciseBook/06.67/CSTree.c new file mode 100644 index 0000000..323fd9b --- /dev/null +++ b/VisualC++/ExerciseBook/06.67/CSTree.c @@ -0,0 +1,67 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/VisualC++/ExerciseBook/06.67/CSTree.h b/VisualC++/ExerciseBook/06.67/CSTree.h new file mode 100644 index 0000000..8c3b490 --- /dev/null +++ b/VisualC++/ExerciseBook/06.67/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/VisualC++/ExerciseBook/06.67/TestData.txt b/VisualC++/ExerciseBook/06.67/TestData.txt new file mode 100644 index 0000000..3804274 --- /dev/null +++ b/VisualC++/ExerciseBook/06.67/TestData.txt @@ -0,0 +1,7 @@ +^A +AB +AC +AD +CE +CF +^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.68/06.68.c b/VisualC++/ExerciseBook/06.68/06.68.c new file mode 100644 index 0000000..116a90b --- /dev/null +++ b/VisualC++/ExerciseBook/06.68/06.68.c @@ -0,0 +1,97 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +#define MAX_TREE_SIZE 1024 // Ԫֵ + +/* + * ĺ-ֵܽṹ + */ +Status Algo_6_68(CSTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf("-ֵܶ\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_68(&T, fp); + fclose(fp); + printf("\n"); + + PrintGraph(T); + printf("\n"); + + return 0; +} + + +/* + * ĺ-ֵܽṹ + */ +Status Algo_6_68(CSTree* T, FILE* fp) { + CSTree queue[MAX_TREE_SIZE] = {NULL}; // 洢Ľ + int d[MAX_TREE_SIZE]; // 洢ýĶ + int parent[MAX_TREE_SIZE]; // 洢ýĸϢ + CSTree p; + int x; + char ch; + int m, n; + int i; + + d[0] = 1; + + for(m = 0, n = 1; m < n; m++) { + p = NULL; + i = 0; + + while(i < d[m]) { + // б + ch = getc(fp); + if(ch == '\n' || ch == '\r') { + continue; + } else { + ungetc(ch, fp); + } + + // ȡϢ + ReadData(fp, "%c%d", &ch, &x); + printf("%c %d\n", ch, x); + if(x < 0) { + return ERROR; + } + + d[n] = x; + parent[n] = m; + + // ½ + queue[n] = (CSTree) malloc(sizeof(CSNode)); + if(queue[n] == NULL) { + exit(OVERFLOW); + } + queue[n]->data = ch; + queue[n]->firstchild = queue[n]->nextsibling = NULL; + + // ׷ٸò׸ + if(p == NULL) { + p = queue[n]; + } else { + // ӽ㴮һ + queue[n - 1]->nextsibling = queue[n]; + } + + n++; + i++; + } + + if(m > 0 && queue[m]->firstchild == NULL) { + queue[m]->firstchild = p; + } + } + + *T = queue[1]; + + return OK; +} diff --git a/VisualC++/ExerciseBook/06.68/06.68.vcxproj b/VisualC++/ExerciseBook/06.68/06.68.vcxproj new file mode 100644 index 0000000..f1ed678 --- /dev/null +++ b/VisualC++/ExerciseBook/06.68/06.68.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {43563BA8-24D9-4C8F-BA79-679816FE8783} + My0668 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.68/06.68.vcxproj.filters b/VisualC++/ExerciseBook/06.68/06.68.vcxproj.filters new file mode 100644 index 0000000..3334fd6 --- /dev/null +++ b/VisualC++/ExerciseBook/06.68/06.68.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.68/06.68.vcxproj.user b/VisualC++/ExerciseBook/06.68/06.68.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.68/06.68.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.68/CSTree.c b/VisualC++/ExerciseBook/06.68/CSTree.c new file mode 100644 index 0000000..323fd9b --- /dev/null +++ b/VisualC++/ExerciseBook/06.68/CSTree.c @@ -0,0 +1,67 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/VisualC++/ExerciseBook/06.68/CSTree.h b/VisualC++/ExerciseBook/06.68/CSTree.h new file mode 100644 index 0000000..8c3b490 --- /dev/null +++ b/VisualC++/ExerciseBook/06.68/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/VisualC++/ExerciseBook/06.68/TestData.txt b/VisualC++/ExerciseBook/06.68/TestData.txt new file mode 100644 index 0000000..15fc534 --- /dev/null +++ b/VisualC++/ExerciseBook/06.68/TestData.txt @@ -0,0 +1,10 @@ +R 3 +A 2 +B 0 +C 1 +D 0 +E 0 +F 3 +G 0 +H 0 +K 0 \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.69/06.69.c b/VisualC++/ExerciseBook/06.69/06.69.c new file mode 100644 index 0000000..856bd29 --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/06.69.c @@ -0,0 +1,45 @@ +#include +#include "BiTree.h" //**06 Ͷ**// + +/* + * Ұӡ + * iԸ˼˲Ϣ + */ +void Algo_6_69(BiTree T, int i); + + +int main(int argc, char* argv[]) { + BiTree T; + + printf("УT...\n"); + InitBiTree(&T); + CreateBiTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("Ұӡ\n"); + Algo_6_69(T, 0); + printf("\n"); + + return 0; +} + + +/* + * Ұӡ + * iԸ˼˲Ϣ + */ +void Algo_6_69(BiTree T, int i) { + int j; + + if(T) { + Algo_6_69(T->rchild, i + 1); // ȷ + + for(j = 1; j <= 2 * i; j++) { // i2ΪЧۣʵʿո + printf(" "); + } + printf("%c\n", T->data); + + Algo_6_69(T->lchild, i + 1); // + } +} diff --git a/VisualC++/ExerciseBook/06.69/06.69.vcxproj b/VisualC++/ExerciseBook/06.69/06.69.vcxproj new file mode 100644 index 0000000..8dd99c8 --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/06.69.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {0BB8D011-2CEC-493C-8F5E-A1E63A375E69} + My0669 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.69/06.69.vcxproj.filters b/VisualC++/ExerciseBook/06.69/06.69.vcxproj.filters new file mode 100644 index 0000000..b2bcbc4 --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/06.69.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.69/06.69.vcxproj.user b/VisualC++/ExerciseBook/06.69/06.69.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/06.69.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.69/BiTree.c b/VisualC++/ExerciseBook/06.69/BiTree.c new file mode 100644 index 0000000..3491ed2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/BiTree.c @@ -0,0 +1,220 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + // *TΪʱеݹ + if(*T) { + if((*T)->lchild!=NULL) { + ClearBiTree(&((*T)->lchild)); + } + + if((*T)->rchild!=NULL) { + ClearBiTree(&((*T)->rchild)); + } + + free(*T); + *T = NULL; + } + + return OK; +} + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûӽ㣬ʹ^棺"); + CreateTree(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + CreateTree(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (BiTree) malloc(sizeof(BiTNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + CreateTree(&((*T)->lchild), fp); // + CreateTree(&((*T)->rchild), fp); // + } +} + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.69/BiTree.h b/VisualC++/ExerciseBook/06.69/BiTree.h new file mode 100644 index 0000000..425dfa1 --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/BiTree.h @@ -0,0 +1,92 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ + + int DescNum; // ý +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * ÿ + * + * еݣʹΪ + */ +Status ClearBiTree(BiTree* T); + +/* + * 㷨6.4 + * + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateBiTree(BiTree* T, char* path); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void CreateTree(BiTree* T, FILE* fp); + + +/* ͼλ */ + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.69/LinkQueue.c b/VisualC++/ExerciseBook/06.69/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.69/LinkQueue.h b/VisualC++/ExerciseBook/06.69/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.69/TestData.txt b/VisualC++/ExerciseBook/06.69/TestData.txt new file mode 100644 index 0000000..de785cc --- /dev/null +++ b/VisualC++/ExerciseBook/06.69/TestData.txt @@ -0,0 +1 @@ +СAB^D^^CE^F^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.70/06.70.c b/VisualC++/ExerciseBook/06.70/06.70.c new file mode 100644 index 0000000..8eb0c29 --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/06.70.c @@ -0,0 +1,58 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* + * Ķṹ + */ +Status Algo_6_70(BiTree* T, FILE* fp); + + +int main(int argc, char* argv[]) { + BiTree T; + FILE* fp; + + printf("T...\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_70(&T, fp); + fclose(fp); + PrintGraph(T); + + return 0; +} + + +/* + * Ķṹ + */ +Status Algo_6_70(BiTree* T, FILE* fp) { + char c; + + while(TRUE) { + // ַȡ + if(feof(fp)!=0) { + return OK; + } + + ReadData(fp, "%c", &c); + + if(c == '#') { + *T = NULL; + } else if(c >= 'A' && c <= 'Z') { + *T = (BiTree) malloc(sizeof(BiTNode)); // + if(*T==NULL) { + exit(OVERFLOW); + } + (*T)->data = c; + (*T)->lchild = (*T)->rchild = NULL; + } else if(c == '(') { + Algo_6_70(&(*T)->lchild, fp); + Algo_6_70(&(*T)->rchild, fp); + } else { + break; + } + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/06.70/06.70.vcxproj b/VisualC++/ExerciseBook/06.70/06.70.vcxproj new file mode 100644 index 0000000..4a9decf --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/06.70.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {AF8102AC-E00C-4E7A-8313-3CA1241B14D7} + My0670 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.70/06.70.vcxproj.filters b/VisualC++/ExerciseBook/06.70/06.70.vcxproj.filters new file mode 100644 index 0000000..dae4759 --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/06.70.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.70/06.70.vcxproj.user b/VisualC++/ExerciseBook/06.70/06.70.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/06.70.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.70/BiTree.c b/VisualC++/ExerciseBook/06.70/BiTree.c new file mode 100644 index 0000000..76327ed --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/BiTree.c @@ -0,0 +1,121 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#include "BiTree.h" +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T) { + int LD, RD; + + if(T == NULL) { + return 0; // Ϊ0 + } else { + LD = BiTreeDepth(T->lchild); // + RD = BiTreeDepth(T->rchild); // + + return (LD >= RD ? LD : RD) + 1; + } +} + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T) { + int level, width; + int i, j, k, w; + int begin; + int distance; + TElemType** tmp; + LinkQueue Q; + BiTree e; + + // + if(BiTreeEmpty(T)) { + printf("\n"); + return; + } + + level = BiTreeDepth(T); // ȫṹ߶ + width = (int)pow(2, level)-1; // ȫṹ + + // ̬ + tmp = (TElemType**)malloc(level* sizeof(TElemType*)); + + // ̬ + for(i = 0; i < level; i++) { + tmp[i] = (TElemType*)malloc(width* sizeof(TElemType)); + + // ʼڴֵΪַ + memset(tmp[i], '\0', width); + } + + // ʵֲ + InitQueue(&Q); + EnQueue(&Q, T); + + // Ԫأ䰲ŵάtmpкʵλ + for(i = 0; i < level; i++) { + w = (int) pow(2, i); // ǰĿ + distance = width / w; // ǰԪؼ + begin = width / (int) pow(2, i + 1); // ǰ׸Ԫ֮ǰĿո + + for(k = 0; k < w; k++) { + DeQueue(&Q, &e); + + if(e == NULL) { + EnQueue(&Q, NULL); + EnQueue(&Q, NULL); + } else { + j = begin + k * (1 + distance); + tmp[i][j] = e->data; + + // + EnQueue(&Q, e->lchild); + + // Һ + EnQueue(&Q, e->rchild); + } + } + } + + for(i = 0; i < level; i++) { + for(j = 0; j < width; j++) { + if(tmp[i][j] != '\0') { + printf("%c", tmp[i][j]); + } else { + printf(" "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/06.70/BiTree.h b/VisualC++/ExerciseBook/06.70/BiTree.h new file mode 100644 index 0000000..d53885f --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/BiTree.h @@ -0,0 +1,54 @@ +/*============================= + * Ķ洢ṹ + * + * 㷨: 6.16.26.36.4 + =============================*/ + +#ifndef BITREE_H +#define BITREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include // ṩ pow ԭ +#include "Status.h" //**01 **// + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* 㶨 */ +typedef struct BiTNode { + TElemType data; // Ԫ + struct BiTNode* lchild; // ָ + struct BiTNode* rchild; // Һָ +} BiTNode; + +/* ָָ */ +typedef BiTNode* BiTree; + + +/* + * ʼ + * + * ն + */ +Status InitBiTree(BiTree* T); + +/* + * п + * + * ж϶ǷΪ + */ +Status BiTreeEmpty(BiTree T); + +/* + * + * + * ضȣ + */ +int BiTreeDepth(BiTree T); + +// ͼλʽǰṹڲʹ +void PrintGraph(BiTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.70/LinkQueue.c b/VisualC++/ExerciseBook/06.70/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.70/LinkQueue.h b/VisualC++/ExerciseBook/06.70/LinkQueue.h new file mode 100644 index 0000000..cc52316 --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/LinkQueue.h @@ -0,0 +1,65 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "BiTree.h" //**06 Ͷ**// + +/* ԪͶ */ +typedef BiTree QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.70/TestData.txt b/VisualC++/ExerciseBook/06.70/TestData.txt new file mode 100644 index 0000000..1c5af96 --- /dev/null +++ b/VisualC++/ExerciseBook/06.70/TestData.txt @@ -0,0 +1 @@ +A(B(#,D),C(E(#,F),#)) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.71/06.71.c b/VisualC++/ExerciseBook/06.71/06.71.c new file mode 100644 index 0000000..4ca6545 --- /dev/null +++ b/VisualC++/ExerciseBook/06.71/06.71.c @@ -0,0 +1,80 @@ +#include +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +/* + * ӡ + * 1ֱʹõݹ飬iʼΪ0 + */ +void Algo_6_71_1(CSTree T, int i); + +/* + * ӡ + * 2ѭʹõݹ飬iʼΪ0 + */ +void Algo_6_71_2(CSTree T, int i); + + +int main(int argc, char* argv[]) { + CSTree T; + + printf("УT...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf(" 1ӡ\n"); + Algo_6_71_1(T, 0); + printf("\n"); + + printf(" 2ӡ\n"); + Algo_6_71_2(T, 0); + printf("\n"); + + return 0; +} + + +/* + * ӡ + * 1ֱʹõݹ飬iʼΪ0 + */ +void Algo_6_71_1(CSTree T, int i) { + int j; + + if(!T) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T->data); + + Algo_6_71_1(T->firstchild, i + 1); + Algo_6_71_1(T->nextsibling, i); // ˴Ϊi +} + +/* + * ӡ + * 2ѭʹõݹ飬iʼΪ0 + */ +void Algo_6_71_2(CSTree T, int i) { + int j; + CSTree p; + + if(!T) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T->data); + + // ӽ + for(p = T->firstchild; p; p = p->nextsibling) { + Algo_6_71_2(p, i + 1); + } +} diff --git a/VisualC++/ExerciseBook/06.71/06.71.vcxproj b/VisualC++/ExerciseBook/06.71/06.71.vcxproj new file mode 100644 index 0000000..e35ad25 --- /dev/null +++ b/VisualC++/ExerciseBook/06.71/06.71.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {45D83A8A-850B-4488-A0D7-E708A39EF9F4} + My0671 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.71/06.71.vcxproj.filters b/VisualC++/ExerciseBook/06.71/06.71.vcxproj.filters new file mode 100644 index 0000000..88c0a96 --- /dev/null +++ b/VisualC++/ExerciseBook/06.71/06.71.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.71/06.71.vcxproj.user b/VisualC++/ExerciseBook/06.71/06.71.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.71/06.71.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.71/CSTree.c b/VisualC++/ExerciseBook/06.71/CSTree.c new file mode 100644 index 0000000..64d258f --- /dev/null +++ b/VisualC++/ExerciseBook/06.71/CSTree.c @@ -0,0 +1,166 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CSTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("Уûкӽûֵܽڵ㣬ʹ^棺"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CSTree T) { + int max = 0; + + Depth(T, 0, &max); + + return max; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CSTree* T, FILE* fp) { + char ch; + + // ȡǰֵ + if(fp == NULL) { + scanf("%c", &ch); + } else { + ReadData(fp, "%c", &ch); + } + + if(ch == '^') { + *T = NULL; + } else { + // ɸ + *T = (CSTree) malloc(sizeof(CSNode)); + if(!(*T)) { + exit(OVERFLOW); + } + (*T)->data = ch; + Create(&((*T)->firstchild), fp); // + Create(&((*T)->nextsibling), fp); // ֵ + } +} + +// ȵڲʵ +static void Depth(CSTree T, int d, int* max) { + if(T == NULL) { + return; + } + + d++; // ָʾǰڵIJ + + if(d > *max) { + *max = d; + } + + Depth(T->firstchild, d, max); // ± + Depth(T->nextsibling, --d, max); // ұ +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/VisualC++/ExerciseBook/06.71/CSTree.h b/VisualC++/ExerciseBook/06.71/CSTree.h new file mode 100644 index 0000000..3d95beb --- /dev/null +++ b/VisualC++/ExerciseBook/06.71/CSTree.h @@ -0,0 +1,87 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CSTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CSTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CSTree* T, FILE* fp); + +// ȵڲʵ +static void Depth(CSTree T, int d, int *max); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/VisualC++/ExerciseBook/06.71/TestData.txt b/VisualC++/ExerciseBook/06.71/TestData.txt new file mode 100644 index 0000000..24661d5 --- /dev/null +++ b/VisualC++/ExerciseBook/06.71/TestData.txt @@ -0,0 +1 @@ +ABE^F^^CG^^D^^^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.72/06.72.c b/VisualC++/ExerciseBook/06.72/06.72.c new file mode 100644 index 0000000..6933c36 --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/06.72.c @@ -0,0 +1,91 @@ +#include +#include "Status.h" //**01 **// +#include "CTree.h" //**06 Ͷ**// + +/* + * ӡ + * 1ֱʹõݹ飬iʼΪ0 + */ +void Algo_6_72_1(CTree T, int order, int i); + +/* + * ӡ + * 2ѭʹõݹ飬iʼΪ0 + */ +void Algo_6_72_2(CTree T, int order, int i); + + +int main(int argc, char* argv[]) { + CTree T; + + printf("T...\n"); + InitTree(&T); + CreateTree(&T, "TestData.txt"); + PrintGraph(T); + printf("\n"); + + printf("ӡ\n"); + Algo_6_72_1(T, T.r, 0); + printf("\n"); + + printf("ӡ\n"); + Algo_6_72_2(T, T.r, 0); + printf("\n"); + + return 0; +} + + +/* + * ӡ + * 1ֱʹõݹ飬iʼΪ0 + */ +void Algo_6_72_1(CTree T, int order, int i) { + int j, k; + + if(!T.n) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T.nodes[order].data); + + // ʺӽ + if(T.nodes[order].firstchild) { + Algo_6_72_1(T, T.nodes[order].firstchild->child, i + 1); + } + + // ȡorderҽλ + k = (order + 1) % MAX_TREE_SIZE; + + // ֵ + if(T.nodes[order].parent == T.nodes[k].parent) { + // ֵܽ + Algo_6_72_1(T, k, i); + } +} + +/* + * ӡ + * 2ѭʹõݹ飬iʼΪ0 + */ +void Algo_6_72_2(CTree T, int order, int i) { + int j; + ChildPtr p; + + if(!T.n) { + return; + } + + for(j = 1; j <= 2 * i; j++) { + printf(" "); + } + printf("%c\n", T.nodes[order].data); + + // ӽ + for(p = T.nodes[order].firstchild; p; p = p->next) { + Algo_6_72_2(T, p->child, i + 1); + } +} diff --git a/VisualC++/ExerciseBook/06.72/06.72.vcxproj b/VisualC++/ExerciseBook/06.72/06.72.vcxproj new file mode 100644 index 0000000..298f8d2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/06.72.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {03935CAC-6FCE-4064-8595-5A5A7826D44D} + My0672 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.72/06.72.vcxproj.filters b/VisualC++/ExerciseBook/06.72/06.72.vcxproj.filters new file mode 100644 index 0000000..e94deda --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/06.72.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.72/06.72.vcxproj.user b/VisualC++/ExerciseBook/06.72/06.72.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/06.72.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.72/CTree.c b/VisualC++/ExerciseBook/06.72/CTree.c new file mode 100644 index 0000000..d2c194a --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/CTree.c @@ -0,0 +1,405 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#include "CTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CTree* T, char* path) { + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("ԪϢڿս㣬ʹ^...\n"); + Create(T, NULL); + } else { + // ļ׼ȡ + fp = fopen(path, "r"); + if(fp == NULL) { + return ERROR; + } + Create(T, fp); + fclose(fp); + } + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T) { + int k, level; + + // + if(TreeEmpty(T)) { + return 0; + } + + /* + * kʼΪһλ + * Ľ㰴洢洢Ľضλ + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CTree* T, FILE* fp) { + int r; // ĸλã + int n; // ¼Ԫ + int cur; // α + TElemType ch; + LinkQueue Q; + QElemType e; // Ԫָʾλ + char s[MAX_CHILD_COUNT + 1]; + int i; + ChildPtr p, pc; + + InitQueue(&Q); + + n = 0; + + // ȡλ + if(fp == NULL) { + printf("λ(0~%d)", MAX_TREE_SIZE - 1); + scanf("%d", &r); + cur = r; + + printf("ֵ"); + scanf("%s", s); + ch = s[0]; + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); // λó + + printf(" %c ĺӽ㣬ںʱһ^", T->nodes[e].data); + scanf("%s", s); + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // ij + p = T->nodes[e].firstchild; + + // װǰ + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // ǰӵĺ + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // ҵβ + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } else { + // ¼λ + ReadData(fp, "%d", &r); + cur = r; + + // ¼ֵ + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ֵ%c\n", ch); + + // + EnQueue(&Q, cur); + T->nodes[cur].data = ch; + T->nodes[cur].parent = -1; + T->nodes[cur].firstchild = NULL; + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + + while(!QueueEmpty(Q)) { + ReadData(fp, "%s", s); + ch = s[0]; + printf("¼ %c ĺӣ", ch); + + // ¼뺢ӽ + ReadData(fp, "%s", s); + printf("%s\n", s); + + DeQueue(&Q, &e); // λó + + // + for(i = 0; i < strlen(s); i++) { + if(s[i] == '^') { + break; + } + + EnQueue(&Q, cur); // ǰλ + T->nodes[cur].data = s[i]; + T->nodes[cur].parent = e; + T->nodes[cur].firstchild = NULL; + + // װǰ + pc = (ChildPtr) malloc(sizeof(CTNode)); + pc->child = cur; + pc->next = NULL; + + // ij + p = T->nodes[e].firstchild; + + // ǰӵĺ + if(p == NULL) { + T->nodes[e].firstchild = pc; + } else { + // ҵβ + while(p->next != NULL) { + p = p->next; + } + + p->next = pc; + } + + cur = (cur + 1) % MAX_TREE_SIZE; + n++; + } + } + } + + T->r = r; + T->n = n; +} + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // λ + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // ڵIJ + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // ˸ı + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // eĺӼ0 + + // ÿʱһϢΪЧΪÿ㶼кӽ + pt[e].lastChild = -1; + + // ָýĺ + cp = T.nodes[e].firstchild; + + // ͷŸý㴦ĺռڴ + while(cp != NULL) { + // ǰλ + EnQueue(&Q, cp->child); + + // ¼ + pt[cp->child].row = pt[e].row + 1; + + // ¼ + pt[cp->child].col = ++count; + + // ¼ǰǵڼ + pt[cp->child].childIndex = ++n; + + // ΪһӵϢ + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework(T); +} + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // ʼΪЧ + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + // ˫ױ洢ṹӸ + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/VisualC++/ExerciseBook/06.72/CTree.h b/VisualC++/ExerciseBook/06.72/CTree.h new file mode 100644 index 0000000..873504b --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/CTree.h @@ -0,0 +1,129 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* ӽ㶨 */ +typedef struct CTNode { + int child; // úе + struct CTNode* next; // ָһ +} CTNode; + +/* ָӽָ */ +typedef CTNode* ChildPtr; + +/* (˫)Ľ㶨 */ +typedef struct { + int parent; // ˫λ + TElemType data; // ǰ + ChildPtr firstchild; // ͷָ +} CTBox; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} CTree; + + +/* + * ijϢ + * + * ע˫ױ洢ṹҪټǰĵһе + * */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T); + +/* + * + * + * ԤĶ + * ԼʹáС + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateTree(CTree* T, char* path); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T); + + +/* ڲʹõĺ */ + +// ڲ +static void Create(CTree* T, FILE* fp); + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T); + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework(CTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.72/LinkQueue.c b/VisualC++/ExerciseBook/06.72/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.72/LinkQueue.h b/VisualC++/ExerciseBook/06.72/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.72/TestData.txt b/VisualC++/ExerciseBook/06.72/TestData.txt new file mode 100644 index 0000000..054a1ad --- /dev/null +++ b/VisualC++/ExerciseBook/06.72/TestData.txt @@ -0,0 +1,9 @@ +λã5 +ֵA +Aĺӽ㣺BCD +Bĺӽ㣺EF +Cĺӽ㣺G +Dĺӽ㣺^ +Eĺӽ㣺^ +Fĺӽ㣺^ +Gĺӽ㣺^ \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.c b/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.c new file mode 100644 index 0000000..49f6c9d --- /dev/null +++ b/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.c @@ -0,0 +1,97 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "CSTree.h" //**06 Ͷ**// + +/* + * -ֵ + */ +Status Algo_6_73(CSTree* T, FILE* fp); + +/* + * ʽӡ-ֵ + */ +void Algo_6_74(CSTree T); + + +int main(int argc, char* argv[]) { + CSTree T; + FILE* fp; + + printf(" 6.73 ֤... \n"); + printf("-ֵܶ\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_73(&T, fp); + fclose(fp); + PrintGraph(T); + printf("\n"); + + printf(" 6.74 ֤... \n"); + printf("ӡ-ֵ...\n"); + Algo_6_74(T); + printf("\n"); + + return 0; +} + + +/* + * -ֵ + */ +Status Algo_6_73(CSTree* T, FILE* fp) { + char c; + + while(TRUE) { + if(feof(fp) != 0) { + break; + } + + ReadData(fp, "%c", &c); + + if(c >= 'A' && c <= 'Z') { + *T = (CSTree) malloc(sizeof(CSNode)); // + if(*T == NULL) { + exit(OVERFLOW); + } + (*T)->data = c; + (*T)->firstchild = (*T)->nextsibling = NULL; + } else if(c == '(') { + Algo_6_73(&(*T)->firstchild, fp); + } else if(c == ',') { + Algo_6_73(&(*T)->nextsibling, fp); + break; // ע˴Ӧ÷ + } else { + break; + } + } + + return OK; +} + +/* + * ʽӡ-ֵ + */ +void Algo_6_74(CSTree T) { + CSTree p; + + if(!T) { + return; + } + + printf("%c", T->data); + + if(T->firstchild) { + printf("("); + + for(p = T->firstchild; p; p = p->nextsibling) { + Algo_6_74(p); + + // һֵܣ"," + if(p->nextsibling) { + printf(","); + } + } + + printf(")"); + } +} diff --git a/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj b/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj new file mode 100644 index 0000000..5d7e567 --- /dev/null +++ b/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {44A70A66-D0E4-4734-8005-ECDD0CF65C20} + My06730674 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj.filters b/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj.filters new file mode 100644 index 0000000..f8e51f4 --- /dev/null +++ b/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj.user b/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.73-06.74/06.73-06.74.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.73-06.74/CSTree.c b/VisualC++/ExerciseBook/06.73-06.74/CSTree.c new file mode 100644 index 0000000..323fd9b --- /dev/null +++ b/VisualC++/ExerciseBook/06.73-06.74/CSTree.c @@ -0,0 +1,67 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#include "CSTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T) { + if(T == NULL) { + return ERROR; + } + + *T = NULL; + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T) { + return T == NULL ? TRUE : FALSE; +} + +// ͼλʽǰṹ +void PrintGraph(CSTree T) { + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + Print(T, 0); + + printf("\n"); +} + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row) { + int k; + + if(T == NULL) { + return; + } + + // ʵǰ + printf("%c ", T->data); + + Print(T->firstchild, row + 1); + + if(T->nextsibling != NULL) { + printf("\n"); + + for(k = 0; k < row; k++) { + printf(". "); + } + + Print(T->nextsibling, row); + } +} diff --git a/VisualC++/ExerciseBook/06.73-06.74/CSTree.h b/VisualC++/ExerciseBook/06.73-06.74/CSTree.h new file mode 100644 index 0000000..8c3b490 --- /dev/null +++ b/VisualC++/ExerciseBook/06.73-06.74/CSTree.h @@ -0,0 +1,50 @@ +/*=================================== + * Ķ-ֵܣṹ洢ʾ + ====================================*/ + +#ifndef CSTREE_H +#define CSTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* (-ֵ)Ľ㶨 */ +typedef struct CSNode { + TElemType data; + struct CSNode* firstchild; // ָ + struct CSNode* nextsibling; // ֵָ +} CSNode; + +/* (-ֵ)Ͷ */ +typedef CSNode* CSTree; + + +/* + * ʼ + * + * + */ +Status InitTree(CSTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CSTree T); + +// ͼλʽǰṹ +void PrintGraph(CSTree T); + +// ͼλǰṹڲʵ +static void Print(CSTree T, int row); + +#endif diff --git a/VisualC++/ExerciseBook/06.73-06.74/TestData.txt b/VisualC++/ExerciseBook/06.73-06.74/TestData.txt new file mode 100644 index 0000000..6502a45 --- /dev/null +++ b/VisualC++/ExerciseBook/06.73-06.74/TestData.txt @@ -0,0 +1 @@ +A(B(E,F),C(G),D) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.c b/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.c new file mode 100644 index 0000000..a67f7f2 --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.c @@ -0,0 +1,167 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "CTree.h" //**06 Ͷ**// + +/* + * (ѿ˫׽) + */ +void Algo_6_75(CTree* T, FILE* fp); + +// ڲʵ֣parentǵǰλý˫׽λ +void Create(CTree* T, int parent, FILE* fp); + +/* + * ʽӡ + */ +void Algo_6_76(CTree T, int i); + + +int main(int argc, char* argv[]) { + FILE* fp; + CTree T; + + printf(" 6.75 ֤...\n"); + printf("ʽ\n"); + fp = fopen("TestData.txt", "r"); + Algo_6_75(&T, fp); + fclose(fp); + PrintGraph(T); + printf("\n"); + + printf(" 6.76 ֤...\n"); + printf("ʽӡ...\n"); + Algo_6_76(T, T.r); + printf("\n"); + + return 0; +} + + +/* + * (ѿ˫׽) + */ +void Algo_6_75(CTree* T, FILE* fp) { + CTree CT; + ChildPtr r; + int mark[MAX_TREE_SIZE]; + int i, j, p; + + CT.r = 0; // Ĭõ0ŵԪ + CT.n = 0; // 0ŵԪʼ洢 + Create(&CT, -1, fp); // ˴ + + T->n = CT.n; + T->r = 0; + j = T->r; + + // ˳Ϊ + for(p = -1; p < CT.n; p++) { + // ѡΪpԪ + for(i = 0; i < CT.n; i++) { + if(CT.nodes[i].parent == p) { + T->nodes[j] = CT.nodes[i]; + mark[i] = j; // ±ΪiԪƶ±j + j++; + } + } + } + + // ± + for(i = 0; i < T->n; i++) { + p = T->nodes[i].parent; + if(p != -1) { + // ޸parent± + T->nodes[i].parent = mark[p]; + } + + // ޸ĺеԪ± + for(r = T->nodes[i].firstchild; r != NULL; r = r->next) { + r->child = mark[r->child]; + } + } +} + +// ڲʵ֣parentǵǰλý˫׽λ +void Create(CTree* T, int parent, FILE* fp) { + char c; + ChildPtr p, q; + + while(TRUE) { + if(feof(fp) != 0) { + break; + } + + ReadData(fp, "%c", &c); + + if(c >= 'A' && c <= 'Z') { + T->nodes[T->n].data = c; // T.n׷ٽ + T->nodes[T->n].parent = parent; + T->nodes[T->n].firstchild = NULL; + + // Ǹ + if(parent != -1) { + // ӽ + p = (ChildPtr) malloc(sizeof(CTNode)); + p->child = T->n; + p->next = NULL; + + // ȡǰӽĸĺ + q = T->nodes[parent].firstchild; + + // ĺΪ + if(q == NULL) { + T->nodes[parent].firstchild = p; + } else { + // Ҹ㺢β + while(q->next != NULL) { + q = q->next; + } + + // 򸸽ĺúӽ + q->next = p; + } + } + + T->n++; + } else if(c == '(') { + Create(T, T->n - 1, fp); // T.n-1ĵһ + + } else if(c == ',') { + Create(T, parent, fp); // ֵܽ + break; + } else { + break; + } + } +} + +/* + * ʽӡ + */ +void Algo_6_76(CTree T, int i) { + ChildPtr p; + + if(!T.n) { + return; + } + + // ӡ˫׽ + printf("%c", T.nodes[i].data); + + if(T.nodes[i].firstchild) { + printf("("); + + // ӽ + for(p = T.nodes[i].firstchild; p; p = p->next) { + Algo_6_76(T, p->child); + + // һ + if(p->next != NULL) { + printf(","); + } + } + + printf(")"); + } +} diff --git a/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj b/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj new file mode 100644 index 0000000..9b0790c --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {70DFF7ED-7543-4F3A-BE38-FCC77CD6D1E5} + My06750676 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj.filters b/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj.filters new file mode 100644 index 0000000..319d51b --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj.user b/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/06.75-06.76.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/06.75-06.76/CTree.c b/VisualC++/ExerciseBook/06.75-06.76/CTree.c new file mode 100644 index 0000000..ba0d57d --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/CTree.c @@ -0,0 +1,223 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#include "CTree.h" + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T) { + if(T == NULL) { + return ERROR; + } + + T->n = 0; + + // + memset(T->nodes, 0, sizeof(T->nodes)); + + return OK; +} + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T) { + return T.n == 0 ? TRUE : FALSE; +} + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T) { + int k, level; + + // + if(TreeEmpty(T)) { + return 0; + } + + /* + * kʼΪһλ + * Ľ㰴洢洢Ľضλ + */ + k = (T.r + T.n - 1) % MAX_TREE_SIZE; + level = 0; + + do { + level++; + k = T.nodes[k].parent; + } while(k != -1); + + return level; +} + + +/* ڲʹõĺ */ + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]) { + LinkQueue Q; + QElemType e; + ChildPtr cp; + + int level, n, count; + + memset(pt, 0, MAX_TREE_SIZE * sizeof(Pos)); + + // + if(TreeEmpty(T)) { + return; + } + + InitQueue(&Q); + + // λ + EnQueue(&Q, T.r); + pt[T.r].row = 1; + pt[T.r].col = 1; + pt[T.r].childIndex = 1; + + // ڵIJ + level = 0; + + while(!QueueEmpty(Q)) { + DeQueue(&Q, &e); + + // ˸ı + if(pt[e].row != level) { + count = 0; + level = pt[e].row; + } + + n = 0; // eĺӼ0 + + // ÿʱһϢΪЧΪÿ㶼кӽ + pt[e].lastChild = -1; + + // ָýĺ + cp = T.nodes[e].firstchild; + + // ͷŸý㴦ĺռڴ + while(cp != NULL) { + // ǰλ + EnQueue(&Q, cp->child); + + // ¼ + pt[cp->child].row = pt[e].row + 1; + + // ¼ + pt[cp->child].col = ++count; + + // ¼ǰǵڼ + pt[cp->child].childIndex = ++n; + + // ΪһӵϢ + pt[e].lastChild = cp->child; + + cp = cp->next; + } + } +} + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T) { + Pos pt[MAX_TREE_SIZE]; + + // + if(TreeEmpty(T)) { + printf("\n"); + return; + } + + // TнλϢ + getPos(T, pt); + + Print(T, pt, T.r); + + printf("\n"); + + printf("洢ṹ\n"); + PrintFramework(T); +} + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i) { + int firstChild = -1; // ʼΪЧ + int rightBrother; + int k; + + // ʵǰ + printf("%c ", T.nodes[i].data); + + // ˫ױ洢ṹӸ + if(T.nodes[i].firstchild!=NULL) { + firstChild = T.nodes[i].firstchild->child; + } + + // ӣҪȷӵݣ + if(firstChild != -1) { + Print(T, pt, firstChild); + } + + rightBrother = (i + 1) % MAX_TREE_SIZE; + + // ֵܣҪȷֵܵݣ + if(rightBrother != (T.r + T.n) % MAX_TREE_SIZE && T.nodes[i].parent == T.nodes[rightBrother].parent) { + // ʵǰֵǰǰ㲻һӣһλ + if(pt[T.nodes[i].parent].lastChild != i) { + printf("\n"); + + for(k = 0; k < pt[rightBrother].row - 1; k++) { + printf(". "); + } + } + + Print(T, pt, rightBrother); + } +} + +// ͼλнṹڲʹ +static void PrintFramework(CTree T) { + int k; + ChildPtr cp; + + if(T.n == 0) { + return; + } + + printf("+---------+-----------\n"); + printf("| i e p | child list\n"); + printf("+---------+-----------\n"); + + for(k = T.r; k != (T.r + T.n) % MAX_TREE_SIZE; k = (k + 1) % MAX_TREE_SIZE) { + + printf("| %2d %c %2d", k, T.nodes[k].data, T.nodes[k].parent); + + cp = T.nodes[k].firstchild; + if(cp != NULL) { + printf(" ->"); + } else { + printf(" | "); + } + + while(cp != NULL) { + printf(" %2d", cp->child); + cp = cp->next; + } + + printf("\n"); + } + + printf("+---------+-----------\n"); +} diff --git a/VisualC++/ExerciseBook/06.75-06.76/CTree.h b/VisualC++/ExerciseBook/06.75-06.76/CTree.h new file mode 100644 index 0000000..2647e1b --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/CTree.h @@ -0,0 +1,108 @@ +/*============================= + * ĺ(˫)Ĵ洢ʾ + =============================*/ + +#ifndef CTREE_H +#define CTREE_H + +#include +#include // ṩ mallocfree ԭ +#include // ṩ memsetstrcmp ԭ +#include "Status.h" //**01 **// +#include "LinkQueue.h" //**03 ջͶ**// + +/* */ +#define MAX_TREE_SIZE 1024 + +/* ĺ */ +#define MAX_CHILD_COUNT 8 + +/* ԪͶ壬ԪΪchar */ +typedef char TElemType; + +/* ӽ㶨 */ +typedef struct CTNode { + int child; // úе + struct CTNode* next; // ָһ +} CTNode; + +/* ָӽָ */ +typedef CTNode* ChildPtr; + +/* (˫)Ľ㶨 */ +typedef struct { + int parent; // ˫λ + TElemType data; // ǰ + ChildPtr firstchild; // ͷָ +} CTBox; + +/* + * (˫)Ͷ + * + *ע + * 1.нnodes""洢ûп϶ + * 2.rܳnodesλ + * 3.⣬ΰ˳ŸУһ̲ͼʾܻ + * 4.nodesѭʹõģһ̲δᵽ + * 5.nodesռ㹻ģΪ̬洢 + */ +typedef struct { + CTBox nodes[MAX_TREE_SIZE]; // 洢н + int r; // λ() + int n; // Ľ +} CTree; + + +/* + * ijϢ + * + * ע˫ױ洢ṹҪټǰĵһе + * */ +typedef struct{ + int row; // ǰ + int col; // ǰ + int childIndex; // ǰǵڼ + int lastChild; // ǰһе +} Pos; + + +/* + * ʼ + * + * + */ +Status InitTree(CTree* T); + +/* + * п + * + * жǷΪ + */ +Status TreeEmpty(CTree T); + +/* + * + * + * ȣ + */ +int TreeDepth(CTree T); + + +/* ڲʹõĺ */ + +// ȡTĽϢЩϢPos͵Ķ +static void getPos(CTree T, Pos pt[]); + + +/* ͼλ */ + +// ͼλʽǰṹ +void PrintGraph(CTree T); + +// ͼλǰṹڲʵ +static void Print(CTree T, Pos pt[], int i); + +// ͼλнṹڲʹ +static void PrintFramework(CTree T); + +#endif diff --git a/VisualC++/ExerciseBook/06.75-06.76/LinkQueue.c b/VisualC++/ExerciseBook/06.75-06.76/LinkQueue.c new file mode 100644 index 0000000..111c53e --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/LinkQueue.c @@ -0,0 +1,102 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_C +#define LINKQUEUE_C + +#include "LinkQueue.h" //**03 ջͶ**// + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q) { + if(Q == NULL) { + return ERROR; + } + + (*Q).front = (*Q).rear = (QueuePtr) malloc(sizeof(QNode)); + if(!(*Q).front) { + exit(OVERFLOW); + } + + (*Q).front->next = NULL; + + return OK; +} + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q) { + if(Q.front == Q.rear) { + return TRUE; + } else { + return FALSE; + } +} + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL) { + return ERROR; + } + + p = (QueuePtr) malloc(sizeof(QNode)); + if(!p) { + exit(OVERFLOW); + } + + p->data = e; + p->next = NULL; + + (*Q).rear->next = p; + (*Q).rear = p; + + return OK; +} + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e) { + QueuePtr p; + + if(Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) { + return ERROR; + } + + p = (*Q).front->next; + *e = p->data; + + (*Q).front->next = p->next; + if((*Q).rear == p) { + (*Q).rear = (*Q).front; + } + + free(p); + + return OK; +} + +#endif diff --git a/VisualC++/ExerciseBook/06.75-06.76/LinkQueue.h b/VisualC++/ExerciseBook/06.75-06.76/LinkQueue.h new file mode 100644 index 0000000..a380617 --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/LinkQueue.h @@ -0,0 +1,64 @@ +/*========================= + * еʽ洢ṹӣ + ==========================*/ + +#ifndef LINKQUEUE_H +#define LINKQUEUE_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* ԪͶ */ +typedef int QElemType; + +// Ԫؽṹ +typedef struct QNode { + QElemType data; + struct QNode* next; +} QNode, * QueuePtr; + +// нṹ +typedef struct { + QueuePtr front; // ͷָ + QueuePtr rear; // βָ +} LinkQueue; // еʽ洢ʾ + + +/* + * ʼ + * + * һյӡ + * ʼɹ򷵻OK򷵻ERROR + * + *ע + * Ķдͷ + */ +Status InitQueue(LinkQueue* Q); + +/* + * п + * + * жǷЧݡ + * + * ֵ + * TRUE : Ϊ + * FALSE: ӲΪ + */ +Status QueueEmpty(LinkQueue Q); + +/* + * + * + * Ԫeӵβ + */ +Status EnQueue(LinkQueue* Q, QElemType e); + +/* + * + * + * ƳͷԪأ洢eС + */ +Status DeQueue(LinkQueue* Q, QElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/06.75-06.76/TestData.txt b/VisualC++/ExerciseBook/06.75-06.76/TestData.txt new file mode 100644 index 0000000..6502a45 --- /dev/null +++ b/VisualC++/ExerciseBook/06.75-06.76/TestData.txt @@ -0,0 +1 @@ +A(B(E,F),C(G),D) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/ExerciseBook.sdf b/VisualC++/ExerciseBook/ExerciseBook.sdf index 4eadf33..c501911 100644 Binary files a/VisualC++/ExerciseBook/ExerciseBook.sdf and b/VisualC++/ExerciseBook/ExerciseBook.sdf differ diff --git a/VisualC++/ExerciseBook/ExerciseBook.sln b/VisualC++/ExerciseBook/ExerciseBook.sln index df7ec92..0999a8f 100644 --- a/VisualC++/ExerciseBook/ExerciseBook.sln +++ b/VisualC++/ExerciseBook/ExerciseBook.sln @@ -185,6 +185,60 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.38.1", "05.38.1\05.38.1. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.38.2", "05.38.2\05.38.2.vcxproj", "{564E9CB9-3C86-4823-98A5-777D1B0A3104}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.68", "06.68\06.68.vcxproj", "{43563BA8-24D9-4C8F-BA79-679816FE8783}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.56-06.58", "06.56-06.58\06.56-06.58.vcxproj", "{8DEA25B2-B54A-4BDE-A572-20FB86BCD046}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.33-06.34", "06.33-06.34\06.33-06.34.vcxproj", "{E2A9BA52-345F-4538-9291-68F3FC7617F5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.35", "06.35\06.35.vcxproj", "{643D5705-B868-4A77-8E6A-17BEFD90F6C8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.36", "06.36\06.36.vcxproj", "{07804D85-D6E3-4A9C-B600-48DD65807835}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.37-06.38", "06.37-06.38\06.37-06.38.vcxproj", "{D9DAFB4C-B792-40D8-913E-A5FB1304A383}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.39", "06.39\06.39.vcxproj", "{73823E0A-5C7D-4785-B42D-7F10221D5698}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.40", "06.40\06.40.vcxproj", "{DB178717-F4B4-40C7-AD1A-CEDFB66D6313}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.41-06.49", "06.41-06.49\06.41-06.49.vcxproj", "{8D15F734-D022-4049-B6B2-B8CDE3845D00}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.50", "06.50\06.50.vcxproj", "{CEBDCC1E-C3FE-4E9A-B830-D3B43268C645}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.51", "06.51\06.51.vcxproj", "{28F75E62-9AE5-49E2-BA2E-A5CD592505AF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.52", "06.52\06.52.vcxproj", "{C01BDD71-C820-4EF9-A153-C92CF6A252C3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.53", "06.53\06.53.vcxproj", "{FA895CBA-DCA0-4539-B4CE-4E9D79195282}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.54", "06.54\06.54.vcxproj", "{4A4F7F91-A802-4881-9459-94AAEB825CAF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.55", "06.55\06.55.vcxproj", "{677775A1-798C-4F33-A703-546AFC56875C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.59-06.62", "06.59-06.62\06.59-06.62.vcxproj", "{FA787FE3-301A-41E0-B5CE-C7E30C30A718}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.63", "06.63\06.63.vcxproj", "{E0214AC8-3D49-4540-9D41-B9FAF1C7504E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.64", "06.64\06.64.vcxproj", "{3A17210B-9672-442C-BC4C-235740FEFFC0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.65", "06.65\06.65.vcxproj", "{72640607-3DA1-4DA7-A377-75D9B0891E56}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.66", "06.66\06.66.vcxproj", "{3899C603-022F-4A7C-869E-76975D077D5C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.67", "06.67\06.67.vcxproj", "{FD67F164-0E8B-47CA-BA37-BCD17525D7DF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.69", "06.69\06.69.vcxproj", "{0BB8D011-2CEC-493C-8F5E-A1E63A375E69}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.70", "06.70\06.70.vcxproj", "{AF8102AC-E00C-4E7A-8313-3CA1241B14D7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.71", "06.71\06.71.vcxproj", "{45D83A8A-850B-4488-A0D7-E708A39EF9F4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.72", "06.72\06.72.vcxproj", "{03935CAC-6FCE-4064-8595-5A5A7826D44D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.73-06.74", "06.73-06.74\06.73-06.74.vcxproj", "{44A70A66-D0E4-4734-8005-ECDD0CF65C20}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06.75-06.76", "06.75-06.76\06.75-06.76.vcxproj", "{70DFF7ED-7543-4F3A-BE38-FCC77CD6D1E5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -559,6 +613,114 @@ Global {564E9CB9-3C86-4823-98A5-777D1B0A3104}.Debug|Win32.Build.0 = Debug|Win32 {564E9CB9-3C86-4823-98A5-777D1B0A3104}.Release|Win32.ActiveCfg = Release|Win32 {564E9CB9-3C86-4823-98A5-777D1B0A3104}.Release|Win32.Build.0 = Release|Win32 + {43563BA8-24D9-4C8F-BA79-679816FE8783}.Debug|Win32.ActiveCfg = Debug|Win32 + {43563BA8-24D9-4C8F-BA79-679816FE8783}.Debug|Win32.Build.0 = Debug|Win32 + {43563BA8-24D9-4C8F-BA79-679816FE8783}.Release|Win32.ActiveCfg = Release|Win32 + {43563BA8-24D9-4C8F-BA79-679816FE8783}.Release|Win32.Build.0 = Release|Win32 + {8DEA25B2-B54A-4BDE-A572-20FB86BCD046}.Debug|Win32.ActiveCfg = Debug|Win32 + {8DEA25B2-B54A-4BDE-A572-20FB86BCD046}.Debug|Win32.Build.0 = Debug|Win32 + {8DEA25B2-B54A-4BDE-A572-20FB86BCD046}.Release|Win32.ActiveCfg = Release|Win32 + {8DEA25B2-B54A-4BDE-A572-20FB86BCD046}.Release|Win32.Build.0 = Release|Win32 + {E2A9BA52-345F-4538-9291-68F3FC7617F5}.Debug|Win32.ActiveCfg = Debug|Win32 + {E2A9BA52-345F-4538-9291-68F3FC7617F5}.Debug|Win32.Build.0 = Debug|Win32 + {E2A9BA52-345F-4538-9291-68F3FC7617F5}.Release|Win32.ActiveCfg = Release|Win32 + {E2A9BA52-345F-4538-9291-68F3FC7617F5}.Release|Win32.Build.0 = Release|Win32 + {643D5705-B868-4A77-8E6A-17BEFD90F6C8}.Debug|Win32.ActiveCfg = Debug|Win32 + {643D5705-B868-4A77-8E6A-17BEFD90F6C8}.Debug|Win32.Build.0 = Debug|Win32 + {643D5705-B868-4A77-8E6A-17BEFD90F6C8}.Release|Win32.ActiveCfg = Release|Win32 + {643D5705-B868-4A77-8E6A-17BEFD90F6C8}.Release|Win32.Build.0 = Release|Win32 + {07804D85-D6E3-4A9C-B600-48DD65807835}.Debug|Win32.ActiveCfg = Debug|Win32 + {07804D85-D6E3-4A9C-B600-48DD65807835}.Debug|Win32.Build.0 = Debug|Win32 + {07804D85-D6E3-4A9C-B600-48DD65807835}.Release|Win32.ActiveCfg = Release|Win32 + {07804D85-D6E3-4A9C-B600-48DD65807835}.Release|Win32.Build.0 = Release|Win32 + {D9DAFB4C-B792-40D8-913E-A5FB1304A383}.Debug|Win32.ActiveCfg = Debug|Win32 + {D9DAFB4C-B792-40D8-913E-A5FB1304A383}.Debug|Win32.Build.0 = Debug|Win32 + {D9DAFB4C-B792-40D8-913E-A5FB1304A383}.Release|Win32.ActiveCfg = Release|Win32 + {D9DAFB4C-B792-40D8-913E-A5FB1304A383}.Release|Win32.Build.0 = Release|Win32 + {73823E0A-5C7D-4785-B42D-7F10221D5698}.Debug|Win32.ActiveCfg = Debug|Win32 + {73823E0A-5C7D-4785-B42D-7F10221D5698}.Debug|Win32.Build.0 = Debug|Win32 + {73823E0A-5C7D-4785-B42D-7F10221D5698}.Release|Win32.ActiveCfg = Release|Win32 + {73823E0A-5C7D-4785-B42D-7F10221D5698}.Release|Win32.Build.0 = Release|Win32 + {DB178717-F4B4-40C7-AD1A-CEDFB66D6313}.Debug|Win32.ActiveCfg = Debug|Win32 + {DB178717-F4B4-40C7-AD1A-CEDFB66D6313}.Debug|Win32.Build.0 = Debug|Win32 + {DB178717-F4B4-40C7-AD1A-CEDFB66D6313}.Release|Win32.ActiveCfg = Release|Win32 + {DB178717-F4B4-40C7-AD1A-CEDFB66D6313}.Release|Win32.Build.0 = Release|Win32 + {8D15F734-D022-4049-B6B2-B8CDE3845D00}.Debug|Win32.ActiveCfg = Debug|Win32 + {8D15F734-D022-4049-B6B2-B8CDE3845D00}.Debug|Win32.Build.0 = Debug|Win32 + {8D15F734-D022-4049-B6B2-B8CDE3845D00}.Release|Win32.ActiveCfg = Release|Win32 + {8D15F734-D022-4049-B6B2-B8CDE3845D00}.Release|Win32.Build.0 = Release|Win32 + {CEBDCC1E-C3FE-4E9A-B830-D3B43268C645}.Debug|Win32.ActiveCfg = Debug|Win32 + {CEBDCC1E-C3FE-4E9A-B830-D3B43268C645}.Debug|Win32.Build.0 = Debug|Win32 + {CEBDCC1E-C3FE-4E9A-B830-D3B43268C645}.Release|Win32.ActiveCfg = Release|Win32 + {CEBDCC1E-C3FE-4E9A-B830-D3B43268C645}.Release|Win32.Build.0 = Release|Win32 + {28F75E62-9AE5-49E2-BA2E-A5CD592505AF}.Debug|Win32.ActiveCfg = Debug|Win32 + {28F75E62-9AE5-49E2-BA2E-A5CD592505AF}.Debug|Win32.Build.0 = Debug|Win32 + {28F75E62-9AE5-49E2-BA2E-A5CD592505AF}.Release|Win32.ActiveCfg = Release|Win32 + {28F75E62-9AE5-49E2-BA2E-A5CD592505AF}.Release|Win32.Build.0 = Release|Win32 + {C01BDD71-C820-4EF9-A153-C92CF6A252C3}.Debug|Win32.ActiveCfg = Debug|Win32 + {C01BDD71-C820-4EF9-A153-C92CF6A252C3}.Debug|Win32.Build.0 = Debug|Win32 + {C01BDD71-C820-4EF9-A153-C92CF6A252C3}.Release|Win32.ActiveCfg = Release|Win32 + {C01BDD71-C820-4EF9-A153-C92CF6A252C3}.Release|Win32.Build.0 = Release|Win32 + {FA895CBA-DCA0-4539-B4CE-4E9D79195282}.Debug|Win32.ActiveCfg = Debug|Win32 + {FA895CBA-DCA0-4539-B4CE-4E9D79195282}.Debug|Win32.Build.0 = Debug|Win32 + {FA895CBA-DCA0-4539-B4CE-4E9D79195282}.Release|Win32.ActiveCfg = Release|Win32 + {FA895CBA-DCA0-4539-B4CE-4E9D79195282}.Release|Win32.Build.0 = Release|Win32 + {4A4F7F91-A802-4881-9459-94AAEB825CAF}.Debug|Win32.ActiveCfg = Debug|Win32 + {4A4F7F91-A802-4881-9459-94AAEB825CAF}.Debug|Win32.Build.0 = Debug|Win32 + {4A4F7F91-A802-4881-9459-94AAEB825CAF}.Release|Win32.ActiveCfg = Release|Win32 + {4A4F7F91-A802-4881-9459-94AAEB825CAF}.Release|Win32.Build.0 = Release|Win32 + {677775A1-798C-4F33-A703-546AFC56875C}.Debug|Win32.ActiveCfg = Debug|Win32 + {677775A1-798C-4F33-A703-546AFC56875C}.Debug|Win32.Build.0 = Debug|Win32 + {677775A1-798C-4F33-A703-546AFC56875C}.Release|Win32.ActiveCfg = Release|Win32 + {677775A1-798C-4F33-A703-546AFC56875C}.Release|Win32.Build.0 = Release|Win32 + {FA787FE3-301A-41E0-B5CE-C7E30C30A718}.Debug|Win32.ActiveCfg = Debug|Win32 + {FA787FE3-301A-41E0-B5CE-C7E30C30A718}.Debug|Win32.Build.0 = Debug|Win32 + {FA787FE3-301A-41E0-B5CE-C7E30C30A718}.Release|Win32.ActiveCfg = Release|Win32 + {FA787FE3-301A-41E0-B5CE-C7E30C30A718}.Release|Win32.Build.0 = Release|Win32 + {E0214AC8-3D49-4540-9D41-B9FAF1C7504E}.Debug|Win32.ActiveCfg = Debug|Win32 + {E0214AC8-3D49-4540-9D41-B9FAF1C7504E}.Debug|Win32.Build.0 = Debug|Win32 + {E0214AC8-3D49-4540-9D41-B9FAF1C7504E}.Release|Win32.ActiveCfg = Release|Win32 + {E0214AC8-3D49-4540-9D41-B9FAF1C7504E}.Release|Win32.Build.0 = Release|Win32 + {3A17210B-9672-442C-BC4C-235740FEFFC0}.Debug|Win32.ActiveCfg = Debug|Win32 + {3A17210B-9672-442C-BC4C-235740FEFFC0}.Debug|Win32.Build.0 = Debug|Win32 + {3A17210B-9672-442C-BC4C-235740FEFFC0}.Release|Win32.ActiveCfg = Release|Win32 + {3A17210B-9672-442C-BC4C-235740FEFFC0}.Release|Win32.Build.0 = Release|Win32 + {72640607-3DA1-4DA7-A377-75D9B0891E56}.Debug|Win32.ActiveCfg = Debug|Win32 + {72640607-3DA1-4DA7-A377-75D9B0891E56}.Debug|Win32.Build.0 = Debug|Win32 + {72640607-3DA1-4DA7-A377-75D9B0891E56}.Release|Win32.ActiveCfg = Release|Win32 + {72640607-3DA1-4DA7-A377-75D9B0891E56}.Release|Win32.Build.0 = Release|Win32 + {3899C603-022F-4A7C-869E-76975D077D5C}.Debug|Win32.ActiveCfg = Debug|Win32 + {3899C603-022F-4A7C-869E-76975D077D5C}.Debug|Win32.Build.0 = Debug|Win32 + {3899C603-022F-4A7C-869E-76975D077D5C}.Release|Win32.ActiveCfg = Release|Win32 + {3899C603-022F-4A7C-869E-76975D077D5C}.Release|Win32.Build.0 = Release|Win32 + {FD67F164-0E8B-47CA-BA37-BCD17525D7DF}.Debug|Win32.ActiveCfg = Debug|Win32 + {FD67F164-0E8B-47CA-BA37-BCD17525D7DF}.Debug|Win32.Build.0 = Debug|Win32 + {FD67F164-0E8B-47CA-BA37-BCD17525D7DF}.Release|Win32.ActiveCfg = Release|Win32 + {FD67F164-0E8B-47CA-BA37-BCD17525D7DF}.Release|Win32.Build.0 = Release|Win32 + {0BB8D011-2CEC-493C-8F5E-A1E63A375E69}.Debug|Win32.ActiveCfg = Debug|Win32 + {0BB8D011-2CEC-493C-8F5E-A1E63A375E69}.Debug|Win32.Build.0 = Debug|Win32 + {0BB8D011-2CEC-493C-8F5E-A1E63A375E69}.Release|Win32.ActiveCfg = Release|Win32 + {0BB8D011-2CEC-493C-8F5E-A1E63A375E69}.Release|Win32.Build.0 = Release|Win32 + {AF8102AC-E00C-4E7A-8313-3CA1241B14D7}.Debug|Win32.ActiveCfg = Debug|Win32 + {AF8102AC-E00C-4E7A-8313-3CA1241B14D7}.Debug|Win32.Build.0 = Debug|Win32 + {AF8102AC-E00C-4E7A-8313-3CA1241B14D7}.Release|Win32.ActiveCfg = Release|Win32 + {AF8102AC-E00C-4E7A-8313-3CA1241B14D7}.Release|Win32.Build.0 = Release|Win32 + {45D83A8A-850B-4488-A0D7-E708A39EF9F4}.Debug|Win32.ActiveCfg = Debug|Win32 + {45D83A8A-850B-4488-A0D7-E708A39EF9F4}.Debug|Win32.Build.0 = Debug|Win32 + {45D83A8A-850B-4488-A0D7-E708A39EF9F4}.Release|Win32.ActiveCfg = Release|Win32 + {45D83A8A-850B-4488-A0D7-E708A39EF9F4}.Release|Win32.Build.0 = Release|Win32 + {03935CAC-6FCE-4064-8595-5A5A7826D44D}.Debug|Win32.ActiveCfg = Debug|Win32 + {03935CAC-6FCE-4064-8595-5A5A7826D44D}.Debug|Win32.Build.0 = Debug|Win32 + {03935CAC-6FCE-4064-8595-5A5A7826D44D}.Release|Win32.ActiveCfg = Release|Win32 + {03935CAC-6FCE-4064-8595-5A5A7826D44D}.Release|Win32.Build.0 = Release|Win32 + {44A70A66-D0E4-4734-8005-ECDD0CF65C20}.Debug|Win32.ActiveCfg = Debug|Win32 + {44A70A66-D0E4-4734-8005-ECDD0CF65C20}.Debug|Win32.Build.0 = Debug|Win32 + {44A70A66-D0E4-4734-8005-ECDD0CF65C20}.Release|Win32.ActiveCfg = Release|Win32 + {44A70A66-D0E4-4734-8005-ECDD0CF65C20}.Release|Win32.Build.0 = Release|Win32 + {70DFF7ED-7543-4F3A-BE38-FCC77CD6D1E5}.Debug|Win32.ActiveCfg = Debug|Win32 + {70DFF7ED-7543-4F3A-BE38-FCC77CD6D1E5}.Debug|Win32.Build.0 = Debug|Win32 + {70DFF7ED-7543-4F3A-BE38-FCC77CD6D1E5}.Release|Win32.ActiveCfg = Release|Win32 + {70DFF7ED-7543-4F3A-BE38-FCC77CD6D1E5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VisualC++/ExerciseBook/ExerciseBook.suo b/VisualC++/ExerciseBook/ExerciseBook.suo index ae6da02..99e18d7 100644 Binary files a/VisualC++/ExerciseBook/ExerciseBook.suo and b/VisualC++/ExerciseBook/ExerciseBook.suo differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128104451884_2337.png b/习题解析/06 树和二叉树/_v_images/20181128104451884_2337.png new file mode 100644 index 0000000..415e362 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128104451884_2337.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128105117033_11930.png b/习题解析/06 树和二叉树/_v_images/20181128105117033_11930.png new file mode 100644 index 0000000..a92a9a8 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128105117033_11930.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128110257751_2313.png b/习题解析/06 树和二叉树/_v_images/20181128110257751_2313.png new file mode 100644 index 0000000..c1211db Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128110257751_2313.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128110446156_31457.png b/习题解析/06 树和二叉树/_v_images/20181128110446156_31457.png new file mode 100644 index 0000000..ca48bec Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128110446156_31457.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128110544582_1478.png b/习题解析/06 树和二叉树/_v_images/20181128110544582_1478.png new file mode 100644 index 0000000..0be0c46 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128110544582_1478.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128110700998_2241.png b/习题解析/06 树和二叉树/_v_images/20181128110700998_2241.png new file mode 100644 index 0000000..64eb0cb Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128110700998_2241.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128110807195_1534.png b/习题解析/06 树和二叉树/_v_images/20181128110807195_1534.png new file mode 100644 index 0000000..7d5c405 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128110807195_1534.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128111210473_26662.png b/习题解析/06 树和二叉树/_v_images/20181128111210473_26662.png new file mode 100644 index 0000000..10a1297 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128111210473_26662.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128111324990_11971.png b/习题解析/06 树和二叉树/_v_images/20181128111324990_11971.png new file mode 100644 index 0000000..58ca5a1 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128111324990_11971.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128111347282_25506.png b/习题解析/06 树和二叉树/_v_images/20181128111347282_25506.png new file mode 100644 index 0000000..766ec42 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128111347282_25506.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128111517428_31507.png b/习题解析/06 树和二叉树/_v_images/20181128111517428_31507.png new file mode 100644 index 0000000..12a65c3 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128111517428_31507.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128111617527_25095.png b/习题解析/06 树和二叉树/_v_images/20181128111617527_25095.png new file mode 100644 index 0000000..79de70b Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128111617527_25095.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128111720515_30465.png b/习题解析/06 树和二叉树/_v_images/20181128111720515_30465.png new file mode 100644 index 0000000..7db545e Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128111720515_30465.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128111800422_9602.png b/习题解析/06 树和二叉树/_v_images/20181128111800422_9602.png new file mode 100644 index 0000000..51dc886 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128111800422_9602.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128111948527_12516.png b/习题解析/06 树和二叉树/_v_images/20181128111948527_12516.png new file mode 100644 index 0000000..1b70113 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128111948527_12516.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112021723_27773.png b/习题解析/06 树和二叉树/_v_images/20181128112021723_27773.png new file mode 100644 index 0000000..8694cfd Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112021723_27773.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112043365_31014.png b/习题解析/06 树和二叉树/_v_images/20181128112043365_31014.png new file mode 100644 index 0000000..b228de0 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112043365_31014.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112124438_19135.png b/习题解析/06 树和二叉树/_v_images/20181128112124438_19135.png new file mode 100644 index 0000000..05fbfa5 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112124438_19135.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112431087_3438.png b/习题解析/06 树和二叉树/_v_images/20181128112431087_3438.png new file mode 100644 index 0000000..5e44d8f Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112431087_3438.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112511543_1120.png b/习题解析/06 树和二叉树/_v_images/20181128112511543_1120.png new file mode 100644 index 0000000..6e1b2bb Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112511543_1120.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112604397_29242.png b/习题解析/06 树和二叉树/_v_images/20181128112604397_29242.png new file mode 100644 index 0000000..36ca5f5 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112604397_29242.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112634220_16780.png b/习题解析/06 树和二叉树/_v_images/20181128112634220_16780.png new file mode 100644 index 0000000..7534c1d Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112634220_16780.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112658086_5668.png b/习题解析/06 树和二叉树/_v_images/20181128112658086_5668.png new file mode 100644 index 0000000..fe25e08 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112658086_5668.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112717108_26921.png b/习题解析/06 树和二叉树/_v_images/20181128112717108_26921.png new file mode 100644 index 0000000..05fbfa5 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112717108_26921.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112755558_29791.png b/习题解析/06 树和二叉树/_v_images/20181128112755558_29791.png new file mode 100644 index 0000000..23c34d3 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112755558_29791.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112819135_8667.png b/习题解析/06 树和二叉树/_v_images/20181128112819135_8667.png new file mode 100644 index 0000000..225fad8 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112819135_8667.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128112956491_22591.png b/习题解析/06 树和二叉树/_v_images/20181128112956491_22591.png new file mode 100644 index 0000000..a5c0a2e Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128112956491_22591.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113036652_13308.png b/习题解析/06 树和二叉树/_v_images/20181128113036652_13308.png new file mode 100644 index 0000000..54c5dd6 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113036652_13308.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113055910_12732.png b/习题解析/06 树和二叉树/_v_images/20181128113055910_12732.png new file mode 100644 index 0000000..72493a4 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113055910_12732.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113124638_7297.png b/习题解析/06 树和二叉树/_v_images/20181128113124638_7297.png new file mode 100644 index 0000000..e8079e1 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113124638_7297.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113157354_11093.png b/习题解析/06 树和二叉树/_v_images/20181128113157354_11093.png new file mode 100644 index 0000000..4bfcf23 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113157354_11093.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113646146_24550.png b/习题解析/06 树和二叉树/_v_images/20181128113646146_24550.png new file mode 100644 index 0000000..189ef58 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113646146_24550.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113658838_29627.png b/习题解析/06 树和二叉树/_v_images/20181128113658838_29627.png new file mode 100644 index 0000000..de884ec Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113658838_29627.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113735845_26004.png b/习题解析/06 树和二叉树/_v_images/20181128113735845_26004.png new file mode 100644 index 0000000..6231bf9 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113735845_26004.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113809629_557.png b/习题解析/06 树和二叉树/_v_images/20181128113809629_557.png new file mode 100644 index 0000000..a72ba7b Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113809629_557.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113927365_10083.png b/习题解析/06 树和二叉树/_v_images/20181128113927365_10083.png new file mode 100644 index 0000000..a3ed3a8 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113927365_10083.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128113938045_4724.png b/习题解析/06 树和二叉树/_v_images/20181128113938045_4724.png new file mode 100644 index 0000000..e958699 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128113938045_4724.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128114035067_7704.png b/习题解析/06 树和二叉树/_v_images/20181128114035067_7704.png new file mode 100644 index 0000000..5b304bb Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128114035067_7704.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128114109728_15826.png b/习题解析/06 树和二叉树/_v_images/20181128114109728_15826.png new file mode 100644 index 0000000..edf0a03 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128114109728_15826.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128114330751_23331.png b/习题解析/06 树和二叉树/_v_images/20181128114330751_23331.png new file mode 100644 index 0000000..e4a07a6 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128114330751_23331.png differ diff --git a/习题解析/06 树和二叉树/_v_images/20181128114433193_105.png b/习题解析/06 树和二叉树/_v_images/20181128114433193_105.png new file mode 100644 index 0000000..a9275b5 Binary files /dev/null and b/习题解析/06 树和二叉树/_v_images/20181128114433193_105.png differ diff --git a/习题解析/06 树和二叉树/▼第06章 树和二叉树.md b/习题解析/06 树和二叉树/▼第06章 树和二叉树.md new file mode 100644 index 0000000..c18a4fe --- /dev/null +++ b/习题解析/06 树和二叉树/▼第06章 树和二叉树.md @@ -0,0 +1,473 @@ +# 第6章 树和二叉树 + +## 一、基础知识题 + +### 6.1 已知一棵树的集合为{, , , , , , , , , , , , },请画出这棵树,并回答下列问题: +##### (1)哪个是根结点? +##### (2)哪些是叶子节点? +##### (3)哪个是结点G的双亲? +##### (4)哪些是结点G的祖先? +##### (5)哪些是结点G的孩子? +##### (6)哪些是结点E的子孙? +##### (7)哪些是结点E的兄弟?哪些是结点F的兄弟? +##### (8)结点B和N的层次号分别是什么? +##### (9)树的深度是多少? +##### (10)以结点C为根的子树的深度是多少? + +>![6.1](_v_images/20181128111210473_26662.png) +> +> (1) A +> (2) D, M, N, F, J, K, L +> (3) C +> (4) A, C +> (5) J, K +> (6) I, M, N +> (7) E的兄弟是D,F的兄弟是G和H +> (8) 2和5 +> (9) 5 +> (10) 3 + +### 6.2 一棵度为2的树与一棵二叉树有何区别? + +> 二叉树有序,而度为2的树未必有序。 + +### 6.3 试分别画出具有3个结点的树和3个结点的二叉树的所有不同形态。 + +> 具有3个结点的树有以下两种形态: +> +> ![6.3.1](_v_images/20181128111324990_11971.png) +> +> 具有3个结点的二叉树有以下5种形态: +> +> ![6.3.2](_v_images/20181128111347282_25506.png) + +### 6.4 一棵深度为H的满k叉树有如下性质:第H层上的结点都是叶子结点,其余各层上每个结点都有k棵非空子树。如果按层次顺序从1开始对全部结点编号,问: +##### (1)各层的结点数目是多少? +##### (2)编号为p的结点的父结点(若存在)的编号是多少? +##### (3)编号为p的结点的第i个儿子结点(若存在)的编号是多少? +##### (4)编号为p的结点有右兄弟的条件是什么?其右兄弟的编号是多少? + +> (1) 第i层有ki-1个结点。 +> (2) p=1时,该结点为根,无父结点;否则,其父结点编号为![6.4](_v_images/20181128111517428_31507.png)(k≥2)。 +> (3) p结点第k-1个儿子的编号为p\*k。所以,若其第i个孩子存在,则其编号为:p\*k+(i-(k-1))。 +> (4) (p-1)%k≠0时,该结点有右兄弟,其右兄弟编号为p+1。 + +### 6.5 已知一棵深度为k的树中有n1个度为1的结点,n2个度为2的结点,…,nk个度为k的结点,问该树中有多少个叶子结点? + +> 设该树共有n个结点,其中叶子结点有n0个。 +> 结点关系:n = n0 + n1 + n2 + … + nk +> 分支关系:n-1 = n1 + 2▪n2 + … + k▪nk +> 因而可得:![6.5](_v_images/20181128111617527_25095.png) + +### 6.6 已知在一棵含有n个结点的树中,只有度为k的分支结点和度为0的叶子结点。试求该树含有的叶子结点的书目。 + +> 设该树度为k的结点有nk个,度为0的结点有n0个。 +> 结点关系:n = nk + n0 +> 分支关系:n-1 = k▪nk +> 因而可得:![6.6](_v_images/20181128111720515_30465.png) + +### 6.7 一棵含有n个结点的k叉树,可能达到的最大深度和最小深度各为多少? + +> k叉树为有序树,其达到最大深度时为单支树,其深度为:n; +> 达到最小深度时为完全k叉树,其深度为:![6.7](_v_images/20181128111800422_9602.png)。 + +### 6.8 证明:一棵满k叉树上的叶子结点数n0和非叶子结点数n1之间满足以下关系:n0=(k-1)n1+1。 + +> 证明:由于是满k叉树,因而只有度为0和度为k的结点。设度为0的结点有n0个,度为k的结点有n1个,结点总数为n,则: +> 结点关系:n = n1 + n0 +> 分支关系:n-1 = k▪n1 +> 因而可得:n0 = (k-1)n1 + 1 + +### 6.9 试分别推导含有n个结点和含n0个叶子结点的完全三叉树的深度H。 + +> (1) n个结点的情况: +> ![6.9.1](_v_images/20181128111948527_12516.png) +> (2) 结合6.8可得,当叶子结点有n0个时,总结点数为:![6.9.2](_v_images/20181128112021723_27773.png) +> 再结合(1)的结论可得: ![6.9.3](_v_images/20181128112043365_31014.png) + +### 6.10 对于那些所有非叶子结点均有非空左右子树的二叉树: +##### (1)试问:有n个叶子结点的树中共有多少个结点? +##### (2)试证明:![6.10.1](_v_images/20181128112124438_19135.png),其中n为叶子结点的个数,li表示第i个叶子结点所在的层次(设根结点所在的层次为1)。 + +> (1)根据题意,此树只有度为0和度为2的结点。设其度为2的结点有n2个,总结点数为n,则: +> 结点关系:n = n + n2 +> 分支关系:n-1 = 2 ▪n2 +> 因而可得:n = 2n - 1 +> +> (2)用数学归纳法证明: +>> 当n=1时,只有一个叶子结点,也就是树中只有根结点,l1=1,因而:![6.10.2](_v_images/20181128112431087_3438.png) +>> 满足题意。 +> +>> 假设当树中有n(n>1)个结点时,等式成立,且p为其任一叶子结点。此时有: +>> ![6.10.3](_v_images/20181128112511543_1120.png) +>> 那么当叶子结点个数为n+1时,树的总结点数增2,叶子结点增1。假设增加的叶子结点来源于p的孩子结点。此时,p不再作为叶子结点,其孩子结点充当叶子结点,设其两个孩子结点为x个y,则有等式:lp +1 = lx = ly。因而有:![6.10.4](_v_images/20181128112604397_29242.png) +>> 故: +>> ![6.10.5](_v_images/20181128112634220_16780.png) +>> 因此有: +>> ![6.10.6](_v_images/20181128112658086_5668.png) +> +>> 至此,原等式得证,即![6.10.7](_v_images/20181128112717108_26921.png)成立。 + +### 6.11 在二叉树的顺序存储结构中,实际上隐含着双亲的信息,因此可和三叉链表对应。假设每个指针域占4个字节的存储,每个信息域占k个字节的存储。试问:对于一棵有n个结点的二叉树,且在顺序存储结构中最后一个结点的下标为m,在什么条件下顺序存储结构比三叉链表更节省空间? + +> 采用三叉链表结构,需要n(k+12)个字节的存储空间。采用顺序存储结构,需要mk个字节的存储空间,则当mk (a) 不含左子树的二叉树 +> (b) 不含右子树的二叉树 +> (b) 既无左子树,又无右子树的二叉树 + +### 6.15 请对下图所示二叉树进行后序线索化,为每个空指针建立相应的前驱或后继线索。 + +![6.15.1](_v_images/20181128113036652_13308.png) + +> 此树的后序遍历序列为:G D B E H F C A +> 后序线索化之后的树为: +> ![6.15.2](_v_images/20181128113055910_12732.png) + +### 6.16 将下列二叉链表改为先序线索链表(不画出树的形态)。 + +![6.16.1](_v_images/20181128113157354_11093.png) + +> ![6.16.2](_v_images/20181128113124638_7297.png) + +### 6.17 阅读下列算法,若有错,则改正之。 + +```c +BiTree InSucc (BiTree q) +{ + //已知q是指向中序线索二叉树上某个结点的指针。 + //本函数返回指向*q的后继的指针。 + + r = q->rchild; + if(!r->rtag) + while(!r->rtag) + r = r->rchild; + return r; +}//InSucc +``` + +> 有3处错误,应该先往左遍历。 +> ```c +> BiTree InSucc (BiTree q) +> { +> r = q->rchild; +> if(!r->ltag) +> while(!r->ltag) +> r = r->lchild; +> return r; +> }//InSucc +> ``` + +### 6.18 试讨论,能否在一棵中序全线索二叉树上查找给定结点*p在后序序列中的后继。 + +> (1)若p为根结点,则其在后序序列中无后继。 +> (2)若p不为根结点,则中序线索遍历查找p的双亲结点。 +>> 若p为其双亲结点的左孩子,则其在后序序列中的后继为其兄弟结点最左下的子孙; +>> 若p为其双亲结点的右孩子,则其在后序序列中的后继为双亲结点。 + +### 6.19 分别画出和下列树对应的各个二叉树: + +![6.19.1](_v_images/20181128113646146_24550.png) + +> ![6.19.2](_v_images/20181128113658838_29627.png) + +### 6.20 将下列森林转换为相应的二叉树,并分别按以下说明进行线索化: +##### (1)先序前驱线索化; +##### (2)中序全线索化前驱线索和后继线索; +##### (3)后序后继线索化。 + +![6.20.1](_v_images/20181128113735845_26004.png) + +> ![6.20.2](_v_images/20181128113809629_557.png) + +### 6.21 画出和下列二叉树相应的森林: + +![6.21.1](_v_images/20181128113927365_10083.png) + +> ![6.21.2](_v_images/20181128113938045_4724.png) + +### 6.22 对于6.19题中给出的各树分别求出以下遍历序列: +##### (1)先根序列; +##### (2)后根序列。 + +> (1) (a)A (b)A B C (c)A B C (d)A B C E I J F G K H D +> (2) (a)A (b)C B A (c)B C A (d)B I J E F K G H C D A + +### 6.23 画出和下列已知序列对应的树T: +##### 树的先根次序访问序列为GFKDAIEBCHJ; +##### 树的后根次序访问序列为DIAEKFCJHBG。 + +> ★★树的先根次序相当于二叉树的先序次序;树的后跟次序相当于二叉树的中序次序。 +> 先画出相应的二叉树如(1),再根据二叉树画出树如(2): +> ![6.23](_v_images/20181128114035067_7704.png) + +### 6.24 画出和下列已知序列对应的森林F: +##### 森林的先序次序访问序列为:ABCDEFGHIJKL; +##### 森林的中序次序访问序列为:CBEFDGAJIKLH。 + +> ★★森林的先序次序相当于二叉树的先序次序;森林的中序次序相当于二叉树的中序次序。 +> 先画出相应的二叉树如(1),再根据二叉树画出森林如(2): +> ![6.24](_v_images/20181128114109728_15826.png) + +### 6.25 证明:在结点数多于1的哈夫曼树中不存在度为1的结点。 + +> 证明:(数学归纳法) +> +> (1)当n=2时,要使其成为最优二叉树,必须使两个结点都成为叶子结点。 +> +> (2)假设当n=k(k>2)时,结论也成立,则当n=k+1时,要使其成为最优二叉树,必须用前k个结点构造出的哈夫曼树与第k+1个结点组成一个新的最优二叉树,所以n=k+1也成立。 +> +> (3)综上,结论成立。 + +### 6.26 假设用于通信的电文仅由8个字母组成,字母在电文中出现的频率分别为0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10。试为这8个字母设计哈夫曼编码。使用0~7的二进制表示形式是另一种编码方案。对于上述实例,比较两种方案的优缺点。 + +> (1) 哈夫曼树如下: +> ![6.26](_v_images/20181128114330751_23331.png) +> 由此可得哈夫曼编码为: +> 0.02 →→ 1 1 1 1 0 +> 0.03 →→ 1 1 1 1 1 +> 0.06 →→ 1 1 1 0 +> 0.07 →→ 1 1 0 0 +> 0.10 →→ 1 1 0 1 +> 0.19 →→ 0 0 +> 0.21 →→ 0 1 +> 0.32 →→ 1 0 +> +> (2)若采用0-7的二进制编码,则(方式不一): +> 0.02 →→ 0 →→ 0 0 0 +> 0.03 →→ 1 →→ 0 0 1 +> 0.06 →→ 2 →→ 0 1 0 +> 0.07 →→ 3 →→ 0 1 1 +> 0.10 →→ 4 →→ 1 0 0 +> 0.19 →→ 5 →→ 1 0 1 +> 0.21 →→ 6 →→ 1 1 0 +> 0.32 →→ 7 →→ 1 1 1 +> 哈夫曼编码计算时候比直接用二进制编码要繁琐些,但是在发电文时,采用哈夫曼编码制作的电文长度最短。 + +### 6.27 假设一棵二叉树的先序序列为EBADCFHGIKJ和中序序列为ABCDEFGHIJK。请画出该树。 +### 6.28 假设一棵二叉树的中序序列为DCBGEAHFIJK和后序序列为DCEGBFHKJIA。请画出该树。 +### 6.29 假设一棵二叉树的层序序列为ABCDEFGHIJ和中序序列为DBGEHJACIF。请画出该树。 + +> ![6.27-28-29](_v_images/20181128114433193_105.png) + +### 6.30 证明:树中结点u是结点v的祖先,当且仅当在先序序列中u在v之前,且在后序序列中u在v之后。 +> 证明:命题等价于遍历时u在v之前的充要条件是遍历序列为先序序列,u在v之后的充要条件是遍历序列为后序遍历。 +> +> 由于u是v的祖先,故若以u为根结点,v必在u的左子树或右子树上。考虑三种遍历次序,先序遍历是根结点-左子树-右子树,中序遍历是左子树-根结点-右子树,后序遍历是左子树-右子树-根结点。 +> +> (1) 充分性: +> 若要保证u在v之前,必须保证根结点的访问先于子树,即采用先序遍历。相反,要保证u在v之后,必须保证根结点的访问迟于子树,即采用后序遍历。 +> +> (2)必要性: +> 若采用先序序列,必然先访问根结点,后访问其子树,故u的访问必先于v。若采用后序序列,则根结点在最后被访问,因而u的访问必在v之后。 +> +> 综上分析,原命题成立。 + +### 6.31 证明:由一棵二叉树的先序序列和中序序列可唯一确定这课二叉树。 +> 证明:命题等价于证明由一棵二叉树的先序序列和中序序列可唯一确定任一结点的位序,进一步等价于证明由一棵二叉树的先序序列和中序序列可唯一确定任一结点的父结点值及其属于此父结点的左孩子还是右孩子。 +> +> (1)根据二叉树性质,每一个结点最多只有一个父结点,所以无论其遍历序列如何,其父结点的值要么不存在(根结点),要么存在且唯一。 +> +> (2)二叉树先序遍历序列为根结点-左子树-右子树,中序遍历序列为左子树-根结点-右子树。由此可得,对于任一结点,在先序序列中寻找其前驱,若前驱不存在,说明此结点是树的根结点,若前驱存在,再判断此结点与其前驱在中序序列中的相对次序,若其前驱位于其右边, 则可断定该结点为其父结点的左子树,否则为右子树。 +> +> 这样一来,根据先序序列和中序序列,就可以唯一确定每一个结点的父结点值及其相对位置(左子树或右子树),进而确定每个结点的位置,由此就可确定唯一的二叉树。 + +### 6.32 证明:如果一棵二叉树的先序序列是u1,u2,…,un,中序序列是up1,up2,…,upn,则序列1,2,…,n可以通过一个栈得到序列p1,p2,…,pn;反之,若以上述中的结论作为前提,则存在一棵二叉树,若其前序序列是u1,u2,…,un,则其中序序列为up1,up2,…,upn。 + +> 暂未想到合适的证明过程。如有好的方案,欢迎提交Issues。 + +### 二、算法设计题 + +### 6.33 假定用两个一维数组L[n+1]和R[n+1]作为有n个结点的二叉树的存储结构,L[i]和r[i]分别指示结点i(i=1,2,…,n)的左孩子和右孩子,0表示空。试写一个算法判别结点u是否为结点v的子孙。 + +### 6.34 同6.33题的条件。先由L和R建立一维数组T[n+1],使T中第i(i=1,2,…,n)个分量指示结点i的双亲,然后写判别结点u是否为结点v的子孙的算法。 + +---------- + +### 6.35 假设二叉树中左分支的标号为“0”,右分支的标号为“1”,并对二叉树增设一个头结点,令根结点为其右孩子,则从头结点到树中任一结点所经分支的序列为一个二进制序列,可认作是某个十进制数的二进制表示。例如,右图所示二叉树中,和结点A对应的二进制序列为“110”,即十进制整数6的二进制表示。已知一棵非空二叉树以顺序存储结构表示,试写一尽可能简单的算法,求出与在树的顺序存储结构中下标值为i的结点对应的十进制整数。 + +![6.35](_v_images/20181128104451884_2337.png) + +---------- + +>> ### 在以下6.36至6.38和6.41至6.53题中,均以二叉链表作为二叉树的存储结构。 + +### 6.36 若已知两棵二叉树B1和B2皆为空,或者皆不空且B1的左、右子树和B2的左、右子树分别相似,则称二叉树B1和B2相似。试编写算法,判别给定两棵二叉树是否相似。 + +---------- + +### 6.37 试利用栈的基本操作写出先序遍历的非递归形式的算法。 + +### 6.38 同6.37题条件,写出后序遍历的非递归算法(提示:为分辨后序遍历时两次进栈的不同返回点,需在指针进栈时同时将一个标志进栈)。 + +---------- + +### 6.39 假设在二叉链表的结点中增设两个域:双亲域(parent)以指示其双亲结点;标志域(mark取值0、1、2)以区分在遍历过程中到达该结点时应继续向左或向右或访问该结点。试以此存储结构编写不用栈进行后序遍历的递推形式的算法。 + +---------- + +### 6.40 若在二叉链表的结点中只增设一个双亲域以指示其双亲结点,则在遍历过程中能否不设栈?试以此存储结构编写不设栈进行中序遍历的递推形式的算法。 + +---------- + +### 6.41 编写递归算法,在二叉树中求位于先序序列中第k个位置的结点的值。 +### 6.42 编写递归算法,计算二叉树中叶子结点的数目。 +### 6.43 编写递归算法,将二叉树中所有结点的左、右子树相互交换。 +### 6.44 编写递归算法:求二叉树中以元素值为x的结点为根的子树的深度。 +### 6.45 编写递归算法:对于二叉树中每一个元素值为x的结点,删去以它为根的子树,并释放相应的空间。 +### 6.46 编写复制一棵二叉树的非递归算法。 +### 6.47 编写按层次顺序(同一层自左至右)遍历二叉树的算法。 +### 6.48 已知在二叉树中,\*root为根结点,\*p和\*q为二叉树中两个结点,试编写求距离它们最近的共同祖先的算法。 +### 6.49 编写算法判别给定二叉树是否为完全二叉树。 + +---------- + +### 6.50 假设以三元组(F,C,L/R)的形式输入一棵二叉树的诸边(其中F表示双亲结点的标识,C表示孩子结点标识,L/R表示C为F的左孩子或右孩子),且在输入的三元组序列中,C是按层次顺序出现的。设结点的标识是字符类型。F=‘\^’时C为根结点标识,若C也为‘\^’,则表示输入结束。例如,6.15题所示的二叉树的三元组序列输入格式为: + +![6.50](_v_images/20181128105117033_11930.png) + +``` +^AL +ABL +ACR +BDL +CEL +CFR +DGR +FHL +^^L +``` + +#### 试编写算法,由输入的三元组序列建立二叉树的二叉链表。 + +---------- + +### 6.51 编写一个算法,输出以二叉树表示的算术表达式,若该表达式中含有括号,则在输出时应添上。 + +---------- + +### 6.52 一棵二叉树的繁茂度定义为各层结点数的最大值与树的高度的乘积。试写一算法,求二叉树的繁茂度。 + +---------- + +### 6.53 试编写算法,求给定二叉树上从根结点到叶子结点的一条其路径长度等于树的深度减一的路径(即列出从根结点到该叶子结点的结点序列),若这样的路径存在多条,则输出路径终点(叶子结点)在“最左”的一条。 + +---------- + +### 6.54 假设以顺序表sa表示一棵完全二叉树,sa.elem[1..sa.last]中存放树中各结点的数据元素。试编写算法由此顺序存储结构建立该二叉树的二叉链表。 + +---------- + +### 6.55 为二叉链表的结点增加DescNum域。试编写一算法,求二叉树的每个结点的子孙数目并存入其DescNum域。请给出算法的时间复杂度。 + +---------- + +### 6.56 试写一个算法,在先序后继线索二叉树中,查找给定结点\*p在先序序列中的后继(假设二叉树的根结点未知)。并讨论实现此算法对存储结构有何要求? + +---------- + +### 6.57 试写一个算法,在后序后继线索二叉树中,查找给定结点\*p在后序序列中的后继(二叉树的根结点指针并未给出)。并讨论实现此算法对存储结构有何要求? + +---------- + +### 6.58 试写一个算法,在中序全线索二叉树的结点\*p之下,插入一棵以结点\*x为根、只有左子树的中序全线索二叉树,使\*x为根的二叉树成为\*p的左子树。若\*p原来有左子树,则令它为\*x的右子树。完成插入之后的二叉树应保持全线索化特性。 + +---------- + +### 6.59 编写算法完成下列操作:无重复地输出以孩子-兄弟链表存储的树T中所有的边。输出的形式为(k1, k2), …, (ki, kj), …,其中,ki和kj为树结点中的结点标识。 +### 6.60 试编写算法,对一棵以孩子-兄弟链表表示的树统计叶子的个数。 +### 6.61 试编写算法,求一棵以孩子-兄弟链表表示的树的度。 +### 6.62 对以孩子-兄弟链表表示的树编写计算树的深度的算法。 + +---------- + +### 6.63 对以孩子链表表示的树编写计算树的深度的算法。 + +---------- + +### 6.64 对以双亲表表示的树编写计算树的深度的算法。 + +---------- + +### 6.65 已知一棵二叉树的前序序列和中序序列分别存于两个一维数组中,试编写算法建立该二叉树的二叉链表。 + +---------- + +### 6.66 假设有n个结点的树T采用了双亲表示法,写出由此建立树的孩子-兄弟链表的算法。 + +---------- + +### 6.67 假设以二元组(F,C)的形式输入一棵树的诸边(其中F表示双亲结点的标识,C表示孩子结点标识),且在输入的二元组序列C中,C是按层次顺序出现的。F='\^'时C为根结点标识,若C也为'\^',则表示输入结束。例如,如下所示树的输入序列为: + +![6.7](_v_images/20181128110257751_2313.png) + +``` +^A +AB +AC +AD +CE +CF +^^ +``` + +#### 试编写算法,由输入的二元组序列建立该树的孩子-兄弟链表。 + +---------- + +### 6.68 已知一棵树的由根至叶子结点按层次输入的结点序列及每个结点的度(每层中自左至右输入),试写出构造此树的孩子-兄弟链表的算法。 + +---------- + +### 6.69 假设以二叉链表存储的二叉树中,每个结点所含数据元素均为单字母,试编写算法,按树形状打印二叉树的算法。例如:左下二叉树印为右下形状。 + +![6.69](_v_images/20181128110446156_31457.png) + +> 根据题意,图中形状从上到下为树的逆中序遍历(右-根-左),且带层序信息的访问次序。逆中序序列反映在行,层序信息反应在列。 + +---------- + +### 6.70 如果用大写字母标识二叉树结点,则一棵二叉树可以用符合下面语法图的字符序列表示。试写一个递归算法,由这种形式的字符序列,建立相应的二叉树的二叉链表存储结构。 + +![6.70](_v_images/20181128110544582_1478.png) + +#### 例如:6.39题所示的二叉树输入形式为A(B(#,D),C(E(#,F),#))。 + +---------- + +### 6.71 假设树上每个结点所含的数据元素为一个字母,并且以孩子-兄弟链表为树的存储结构,试写一个按凹入表方式打印一棵树的算法。例如:左下所示树印为右下形状。 + +![6.71](_v_images/20181128110700998_2241.png) + +---------- + +### 6.72 以孩子链表为树的存储结构,重做6.71题。 + +---------- + +### 6.73 若用大写字母标识树的结点,则可用带标号的广义表形式表示一棵树,其语法图如下所示: +![6.73](_v_images/20181128110807195_1534.png) +#### 例如,6.71题中的树可用下列形式的广义表表示:A(B(E,F),C(G),D) +### 试写一递归算法,由这种广义表表示的字符序列构造树的孩子-兄弟链表(提示:按照森林和树相互递归的定义写两个互相递归调用的算法,语法图中一对圆括号内的部分可看成为森林的语法图)。 + +### 6.74 试写一递归算法,以6.73题给定的树的广义表表示法的字符序列形式输出以孩子-兄弟链表表示的树。 + +---------- + +### 6.75 试写以递归算法,由6.73题定义的广义表表示法的字符序列,构造树的孩子链表。 +### 6.76 试写以递归算法,以6.73题给定的树的广义表表示法的字符序列形式输出以孩子链表表示的树。 + +----------