linux下运行链表栈(实现栈的基本功能 push,pop,删除任意结点,遍历输出等)

一、简要叙述设计思想和技术路线(不少于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

 

猜你喜欢

转载自blog.csdn.net/gyx1549624673/article/details/84197617