一、简要叙述设计思想和技术路线(不少于300字)(20分)。
设计思想:利用Linux GNU make C 项目管理软件工具实现数据结构栈(Stack)。实现Push,Pop,Delete,Search,Visit through,Clear功能。节点的数据设计具有一般性(使用void *data),使用链表栈实现本功能,且栈的Top指针作为每个函数的形式参数。最后以int型序号管理为实例,演示实验功能。ac_impl.c负责输出选择菜单项;test_impl.c中实现对菜单的选择,以及具体实例的验证;main.c作为入口,对test_impl.c进行调用;mod_impl.c中实现具体的功能函数。
技术路线:采用链表栈。Push和Pop功能严格遵循栈的先进后出特性,从栈顶删除,压入新元素时从栈顶压入。对于Delete功能,若要删除的节点在栈顶,直接删除,若该元素不在栈顶,将需删除元素之上的其它元素先push入创建的临时栈tempStack中,若找到要删除元素则删除,然后将tempStack中元素重新push入原栈,返回true;若未找到该元素,返回false。对于Search功能,从栈顶开始搜索,若找到该元素则返回该元素,若未找到top指针指向top->nextPtr,若搜索到栈底(即top->nextPtr==NULL)则返回NULL。对于Visit through功能,从栈顶开始遍历并依次输出访问到的元素。对于Clear功能,将top指针一步步移到栈底,最后释放指针。
二、文字叙说各个功能模块的“算法”、技术难点并附上代码(5*7=35分)。
2.1 Push功能
首先利用malloc函数分配空间给一个新的结构体指针node,将形参data赋值给该结构体成员data,node的nextPtr元素指向原栈顶指针的nextPtr指针指向的空间,然后将栈顶指针的nextPtr指针指向node以实现将node结点加入链表栈中。
//push data to the stack
void Push(ListNodePtr top, void* data) {
//allocate node space
ListNodePtr node = (ListNodePtr)malloc(sizeof(ListNode));
//assign the parameter to the data of the struct
node->data = data;
//the pointer move to the next
node->nextPtr = top->nextPtr;
//top->nextPtr point to the node in order to push the node into the stack
top->nextPtr = node;
}
2.2 Pop功能
首先判断栈当前是否为空,若为空直接返回NULL。若不为空,则创建一个结构体指针pop_node指向栈顶指针的nextPtr元素指针所指空间,然后将top->nextPtr指向pop_node->nextPtr,使原栈顶结点指针脱离链表,实现栈顶元素的删除,并用pop_node保存要删除的栈顶结点,返回原栈顶结点的data元素。
//pop data
void* Pop(ListNodePtr top) {
//the stack is empty,return null
if (!top->nextPtr) {
return NULL;
}
//discard the top element of the stack
ListNodePtr pop_node = top->nextPtr;
//the pointer crosses the pop_node to the next node
top->nextPtr = pop_node->nextPtr;
//return the data which is popped
return pop_node->data;
}
2.3 Delete功能
首先创建一个临时栈tempStack,后面用于存放可能的元素。接着判断形参中传入的栈是否为空,若栈为空直接返回。若栈不为空,从栈顶元素开始,一个个与形参data对比,看是否为想要删除的元素,如果不是,将该元素压入tempStack,并弹出当前的栈;如果找的了要删除的元素,则将其指向该结点的指针脱离链表,pop该元素,并将该元素返回。若遍历了整个栈还未找到返回null。
//delete data
void* Delete(ListNodePtr top, void* data) {
//create a temporary stack which used to temporarily store the data
ListNodePtr tempStack= InitStack();
//the satck is empty,return
if (!top->nextPtr) {
return ;
}
//loop until we find the element to delete
while (top->nextPtr->data != data) {
//push the date which is before the required element into the temporary stack
Push(tempStack, top->nextPtr->data);
//pop the top element out of the satck
Pop(top);
}
//if the stack is empty and we don't find the requried element ,return
if (!top->nextPtr) {
return;
}
//if we find the data we want to delete
else {
//pop the data we want to delete then push the data into the stack which we stored in the tempStack
ListNodePtr delete_node = top->nextPtr;
Pop(top);
while (tempStack->nextPtr) {
Push(top, Pop(tempStack));
}
free(delete_node);
//return the data we delete
return data;
}
}
2.4 Search功能
指针从栈顶向栈底方向移动,并依次对比当前结点的data元素与形参data是否一致以判断是否找到需要找的元素,若找到则将该data返回,若遍历了整个栈都未找到则返回NULL。
//Search the data
void* Search(ListNodePtr top, void* data) {
ListNodePtr temp = top;
while (top->nextPtr) { //loop until we find the data we want
if (top->nextPtr->data == data) { //if we find the data ,return the data
return top->nextPtr->data;
}
top=top->nextPtr; //if data is not we want,*top point to the next node
}
return NULL; //if we search through the whole stack and don't find the data just return
}
2.5 VisitThough功能
指针从栈顶向栈底方向移动,并依次输出data,直到输出整给栈的元素。
//Visit through the stack
void VisitThrough(ListNodePtr top) {
ListNodePtr temp = top; //create temporary pointer
while (temp->nextPtr) { //the pointer moves from the
//top of the stack and output the data of
//the node until the pointer is point to
printf("%d ",temp->nextPtr->data); //the end of the stack
temp = temp->nextPtr;
}
}
2.6 Clear功能
从栈顶指针开始一个个脱离链表,直到栈为空,释放指针空间。
//Clear the stack
void Clear(ListNodePtr top) {
while (top->nextPtr) { //detach the linked list one by
//one from the top of the stack until the stack is empty
ListNodePtr temp = top->nextPtr;
top->nextPtr = top->nextPtr->nextPtr;
free(temp);
}
}
三、 提供makefile脚本(15分)。
OBJS = main.o test_impl.o mod_impl.o ac_impl.o
CC = gcc
prog:$(OBJS)
$(CC) -o $@ $^
main.o:main.c menu.h
$(CC) -c $<
test_impl.o:test_impl.c menu.h
$(CC) -c $<
mod_impl.o:mod_impl.c modify.h
$(CC) -c $<
ac_impl.o:ac_impl.c access.h
$(CC) -c $<
clean:
rm *.o
四、 提供Cygwin之下应用实例的测试截图(15分)。
由于有Linux服务器,所以直接用xshell连接服务器,上传相关项目后运行。
1.make 此过程遇到问题,由于代码在传输过程中,makefile中的tab居然被空格代替了,导致make命令无法运行,于是在vim命令下,重写了makefile文件,最终得以正确运行,截图如下。
2.push功能 键入1,执行push操作,依次入栈11 22 33 55 66 77 88,然后选择5,遍历输出此时的栈,验证push确实成功。运行截图如下。
3.pop功能,键入2,执行pop操作,将栈顶元素弹出栈,本实例中,pop两次,应当将88 77弹出栈,然后键入5,遍历输出pop之后的栈以验证。实验截图如下:
4.delete功能 键入3,执行delete的操作,实例中删除33,然后键入5遍历输出以验证,如下:
5.search功能 键入4,执行search操作,用于搜索一个元素,实例中搜索栈中元素66显示成功,搜索非栈中元素88显示not exist。实验截图如下:
6.visit through功能 键入5,执行visitthrough操作,遍历输出栈中所有元素,截图如下:
7.clear功能 键入6,执行clear操作,将栈清空,截图如下
8.end 键入7,退出系统,截图如下:
五、 附录提供完整带有详细英文注释的代码(15分)。
完整的见https://download.csdn.net/download/gyx1549624673/10811624