1. 程式人生 > >linux下執行連結串列棧(實現棧的基本功能 push,pop,刪除任意結點,遍歷輸出等)

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 [email protected] $^

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