提交 bcf6875c 创建 作者: 宋海霞's avatar 宋海霞

template

上级
流水线 #479 已失败 于阶段
/Debug
/Release
*.bak
image: "registry.cn-hangzhou.aliyuncs.com/engintime/ubuntu_16.04_cpp:latest"
stages:
- make
- case1
- teacher-check
variables:
TEMPLATE_REPO: "engintime/ds-lab/Project-Template/Lab014.git"
.codecode-runner: &codecode-runner
tags:
- ubuntu-16.04
- short-job
make:
stage: make
<<: *codecode-runner
script:
- make
- execscore.sh 40
only:
- master
case1:
stage: case1
<<: *codecode-runner
script:
- make
- ./app > user_output.txt
- diff output.txt user_output.txt -b -B -y -i --suppress-common-lines
- execscore.sh 100
only:
- master
teacher-check:
stage: teacher-check
<<: *codecode-runner
script:
- make
- ./app
- git clone ${CODECODE_PROTOCOL}gitlab-ci-token:${CI_JOB_TOKEN}@${CODECODE_DOMAIN}/${TEMPLATE_REPO} template
- diff template/.gitlab-ci.yml .gitlab-ci.yml -b -B -y -i --suppress-common-lines
- diff template/output.txt output.txt -b -B -y -i --suppress-common-lines
- fileidentity.sh
only:
- master
when: manual
allow_failure: false
<?xml version="1.0" encoding="gb2312"?>
<OSLProject Version="1.00" Name="CSTree" SubjectID="cf4dda31-1275-49ef-9b0f-36a6eff372e4" ProjectTemplateID="4aa1519c-621b-4f60-b306-3a23207331fb">
<Configurations>
<Configuration Name="Debug">
<Tool Name="PreBuildEventTool"/>
<Tool Name="CustomBuildTool"/>
<Tool Name="GCCCompilerTool" PreprocessorDefinitions="_DEBUG" GenerateDebugInformation="-1"/>
<Tool Name="PreLinkEventTool"/>
<Tool Name="GCCLinkerTool" AdditionalDependencies="&quot;$(DSLInstallDir)Dump\lib\CSTree_Demo.o&quot;"/>
<Tool Name="PostBuildEventTool"/>
<VisualContext>
<WatchPoints>
<WatchPoint FunctionName="PreOrder" ObserverID="B651D7BF-AB07-49af-8634-A66270D47BA0">
</WatchPoint>
</WatchPoints>
</VisualContext>
</Configuration>
<Configuration Name="Release">
<Tool Name="PreBuildEventTool"/>
<Tool Name="CustomBuildTool"/>
<Tool Name="GCCCompilerTool" PreprocessorDefinitions="NDEBUG"/>
<Tool Name="PreLinkEventTool"/>
<Tool Name="GCCLinkerTool"/>
<Tool Name="PostBuildEventTool"/>
</Configuration>
</Configurations>
<Files>
<Filter Name="ͷļ" Filter="h;hpp;hxx">
<File RelativePath=".\CSTree.h">
</File>
<File RelativePath=".\Stack.h">
</File>
</Filter>
<Filter Name="Դļ" Filter="cpp;c;cc;cxx">
<File RelativePath=".\main.c">
</File>
<File RelativePath=".\Stack.c">
</File>
</Filter>
<File RelativePath=".\makefile">
</File>
<File RelativePath=".\output.txt">
</File>
<File RelativePath=".\readme.md">
</File>
</Files>
</OSLProject>
#ifndef _CSTREE_H_
#define _CSTREE_H_
//
// 在此处包含 C 标准库头文件
//
#include <stdio.h>
//
// 在此处包含其他头文件
//
#include "Stack.h"
//
// 在此处定义数据结构
//
#define MAX_NUMBER 50
typedef struct CSNode{
char data; // 节点数据
struct CSNode *firstchild; // 孩子节点
struct CSNode *nextsibling; // 兄弟节点
}CSNode, *CSTree;
//
// 在此处声明函数
//
CSTree InitTree();
int PreOrder(CSTree pTree);
CSNode* CreateNode(char data);
CSNode* PreOrderCreate(CSTree pTree, char Key);
void CreateSubTree(char* data, CSTree pRootNode);
void DeleteTree(CSTree pTree);
void OutputResult();
//
// 在此处声明全局变量
//
extern Stack stack;
extern char g_string[MAX_NUMBER];
extern int g_length;
#endif /* _CSTREE_H_ */
添加文件
#include "Stack.h"
/*
功能:
初始化栈。
参数:
pS -- 栈的指针
*/
void InitStack(Stack* pS)
{
pS->top = -1;
}
/*
功能:
将元素入栈。
参数:
pS -- 栈的指针
Elem -- 入栈的元素
返回值:
如果插入成功返回入栈元素的值。
如果插入失败返回 -1。
*/
struct CSNode* Push(Stack* pS, struct CSNode* Elem)
{
//
// 栈满,入栈失败。
//
if(MAX_STACK_LENGTH < pS->top)
return 0;
pS->top++;
pS->buffer[pS->top] = Elem; // 将元素插入栈顶
return Elem;
}
/*
功能:
将栈顶元素出栈
参数:
pS -- 栈的指针
返回值:
如果出栈成功返回出栈元素的值。
如果出栈失败返回 -1。
*/
struct CSNode* Pop(Stack* pS)
{
struct CSNode* Elem;
//
// 栈为空,出栈失败
//
if(StackEmpty(pS))
return 0;
Elem = pS->buffer[pS->top];
pS->top--;
return Elem;
}
/*
功能:
判断栈是否为空。
参数:
pQ -- 栈的指针
返回值:
如果栈空返回 1(真)
如果栈非空返回 0(假)
*/
int StackEmpty(Stack* pS)
{
return -1 == pS->top ? 1 : 0;
}
#ifndef _STACK_H_
#define _STACK_H_
//
// 在此处包含 C 标准库头文件
//
//
// 在此处包含其他头文件
//
//
// 在此处定义数据结构
//
#define MAX_STACK_LENGTH 64 // 栈的最大长度
// 栈
struct CSNode;
typedef struct Stack{
struct CSNode* buffer[MAX_STACK_LENGTH]; // 栈的缓冲区
int top; // 指示栈顶的位置,而不是栈中元素的个数
}Stack;
//
// 在此处声明函数
//
void InitStack(Stack* pS);
struct CSNode* Push(Stack* pS, struct CSNode* Elem);
struct CSNode* Pop(Stack* pS);
int StackEmpty(Stack* pS);
//
// 在此处声明全局变量
//
#endif /* _STACK_H_ */
#include "CSTree.h"
Stack stack; // 栈。用于储存节点
int main(int argc, char* argv[])
{
CSTree pTree; // 树指针
//
// 初始化栈
//
InitStack(&stack);
//
// 创建树, 使用二叉链表表示法
//
pTree = InitTree();
//
// 先序遍历树
//
PreOrder(pTree);
//
// 输出结果
//
OutputResult();
//
// 销毁树
//
DeleteTree(pTree);
return 0;
}
/*
功能:
先序遍历树。利用栈实现非递归算法。
参数:
pTree -- 树的指针。
返回值:
如果遍历成功返回 1
如果遍历失败返回 0
*/
char g_string[MAX_NUMBER]; // 字符串。用于在遍历过程中保存树的先序序列
int g_length = 0; // 字符串长度。0 表示空字符串
int PreOrder(CSTree pTree)
{
CSNode* pNode; // 树节点指针
//
// TODO: 在此添加代码
//
return 0;
}
/*
功能:
创建树的一个节点。
参数:
data -- 树节点保存的数据
返回值:
返回节点指针
*/
CSNode* CreateNode(char data)
{
CSNode* pNode = (CSNode*)malloc(sizeof(CSNode));
pNode->data = data;
pNode->firstchild = NULL;
pNode->nextsibling = NULL;
return pNode;
}
/*
功能:
创建一个子树。
参数:
data -- 树节点保存的数据
pRootNode -- 树指针
返回值:
*/
void CreateSubTree(char* data, CSTree pRootNode)
{
int i;
CSTree pFirstChild;
pRootNode->firstchild = CreateNode(data[1]);
pFirstChild = pRootNode->firstchild;
for(i = 2; data[i] != '\0'; i++)
{
pFirstChild->nextsibling = CreateNode(data[i]);
pFirstChild = pFirstChild->nextsibling;
}
}
/*
功能:
使用先序遍历算法创建树。
参数:
CSTree -- 树指针
返回值:
返回数据为 Key 的节点的指针
*/
CSNode* PreOrderCreate(CSTree pTree, char Key)
{
CSNode* pNode = NULL;
if(pTree != NULL)
{
if(pTree->data == Key)
return pTree;
pNode = PreOrderCreate(pTree->firstchild, Key);
if(pNode != NULL)
return pNode;
pNode = PreOrderCreate(pTree->nextsibling, Key);
if(pNode != NULL)
return pNode;
}
return NULL;
}
/*
功能:
利用二维数组初始化树。
返回值:
返回树指针
*/
const char data[MAX_NUMBER][MAX_NUMBER] =
{ { 'R', 'A', 'B', 'C' }, // 用于初始化树的二维数组,二维数组的每一行构造一棵子树,
{ 'A', 'D', 'E' }, // 第一个字符用于初始化子树的根节点,第二个字符用于初始
{ 'C', 'F' }, // 化孩子节点,其余的字符用于初始化兄弟节点。注意:第一
{ 'F', 'G', 'H', 'K' } }; // 行的第一个字符用于构造整棵树的根节点,其余行的第一个
// 字符应为之前某一行的孩子节点或兄弟节点。
CSTree InitTree()
{
int i = 0;
CSNode* pNode = NULL;
CSTree pRootNode = CreateNode(data[0][0]);
for(i = 0; data[i][0] != 0; i++)
{
pNode = PreOrderCreate(pRootNode, data[i][0]);
CreateSubTree((char*)data[i], pNode);
}
return pRootNode;
}
/*
功能:
销毁树。
参数:
pTree -- 树的指针。
返回值:
*/
void DeleteTree(CSTree pTree)
{
//
// 利用递归实现后序遍历算法
//
if(pTree != NULL)
{
DeleteTree(pTree->firstchild);
DeleteTree(pTree->nextsibling);
free(pTree);
}
}
/*
功能:
输出结果。
参数:
返回值:
*/
void OutputResult()
{
int i;
for(i = 0; i < g_length - 1; i++)
{
printf("%c", g_string[i]);
}
printf("\n");
}
app:main.o Stack.o
gcc main.o Stack.o -o app
main.o:main.c CSTree.h
gcc -c -w -O3 -std=c99 -fsigned-char main.c -o main.o
Stack.o:Stack.c Stack.h
gcc -c -w -O3 -std=c99 -fsigned-char Stack.c -o Stack.o
\ No newline at end of file
RADEBCFGHK
# 阅读实验源代码
**main.c文件**
在main函数中首先创建了一般树,然后调用PreOrder函数对一般树进行先序遍历操作,并将产生的先序序列保存在全局变量g_string中。
在main函数的后面,定义了一般树的先序遍历函数PreOrder, 此函数的函数体还不完整,留给读者完成。
**CSTree.h文件**
定义了与一般树相关的数据结构并声明了相关的操作函数和全局变量。注意,此头文件中还包含了栈模块的头文件Stack.h。
**Stack.h文件**
定义了与栈相关的数据结构并声明了相关的操作函数。
**Stack.c文件**
定义了与栈相关的操作函数。
# 在演示模式下调试项目
**按照下面的步骤调试项目:**
1. 按F7生成项目。
2. 在演示模式下,按F5启动调试项目。程序会在观察点函数的开始位置中断。
3. 重复按F5,直到调试过程结束。
在调试的过程中,每执行“演示流程”窗口中的一行后,仔细观察“可视化数据”窗口内容所发生的变化,理解一般树先序遍历的执行过程。“可视化数据”窗口显示的数据信息(如下图所示),包括:
- 先序遍历一般树时,树节点按照其被访问的先后顺序所组成的先序遍历字符串。
- 一般树的详细信息。
a) 一般树节点的值和地址。
b) 已访问过的结点的底色为灰色,并且在该结点中,用白色的字体标出了访问过的序号。
c) 在栈中的结点的底色为绿色。
d) 用红色带箭头的虚线表示出了访问节点的轨迹。
e) 游标指向了当前的节点。
- 先序遍历一般树时使用的栈,栈的填充色为绿色。包括了一般树节点的地址、值(空地址的值会被忽略)。
![一般树的遍历](./img/14.png)
# 编写源代码并通过验证
**按照下面的步骤继续实验:**
1. 为PreOrder函数编写源代码,要求利用栈实现非递归的先序遍历算法,并生成先序序列字符串。注意,尽量使用已定义的局部变量。
2. 按F7生成项目。如果生成失败,根据“输出”窗口中的提示信息修改源代码中的语法错误。
3. 按Alt+F5启动验证。如果验证失败,可以使用“输出”窗口中的“比较”功能,或者在“非演示模式”下按F5启动调试后重复按F10单步调试读者编写的源代码,从而定位错误的位置,然
后回到步骤1。
提示:在验证过程中,主要是检测先序序列字符串生成的是否正确,所以,为了顺利通过验证,请读者在遍历一般树的同时一定要在全局变量g_string中生成先序序列字符串。
# 教师参考答案
访问教师参考答案[domain relative url](engintime/ds-lab/teachers-packet/Lab014.git)
\ No newline at end of file
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论