數據結構鏈棧的基本操作的實現

一、實驗目的

(1)掌握棧的鏈式存儲結構;
(2)掌握棧的操作特性;
(3)掌握基於鏈棧的基本操作的實現方法。

二、實驗內容

(1)建立一個空棧;
(2)對已建立的棧進行插入、刪除、取棧頂元素等基本操作。

三、問題分析

棧 (stack) 是限定僅在表尾進行插入或刪除操作的線性表。對棧來說,表尾端有其特殊含義,稱爲棧頂 (top), 表頭端稱爲棧底 (bottom)。不含元素的空表稱爲空棧。棧的修改是按後進先出的原則進行的,棧又稱爲後進先出的線性表。
鏈棧是指採用鏈式存儲結構實現的棧。通常鏈棧用單鏈表來表示,鏈棧的結點結構與單鏈表的結構相同,在此用StackNode 表示。鏈棧有着初始化、入棧、出棧、去棧頂元素等操作。

四、算法設計

1、主要數據結構的設計
1.1 鏈棧的入棧
①爲入棧元素 e 分配空間,用指針 p 指向。
②將新結點數據域置爲e。
③將新結點插入棧頂。
④修改棧頂指針爲 p。

入棧示意圖
入棧示意圖

1.2 鏈棧的出棧
①判斷棧是否爲空,若空則返回ERROR。
②將棧頂元素賦給e。
③臨時保存棧頂元素的空間,以備釋放。
④修改棧頂指針,指向新的棧頂元素。
⑤釋放原棧頂元素的空間。

出棧示意圖
出棧示意圖

1.3 取棧頂元素
當棧非空時, 此操作返回當前棧頂元素的值, 棧頂指針S保持不變。
2、算法設計
2.1 鏈棧初始化算法
Status InitStack(LinkStack &S){  
//構造一個空棧S,棧頂指針置空
    S = NULLreturn OK;
}
2.2 入棧操作算法
Status Push (LinkStack &S, SElenType e){//在棧頂插人元素e
	p-new StackNode;                     //生成新結點
	p->data=e;                           //將新結點數據城置爲e
	p->next=S;                           //將新結點插人棧頂
	S=p;                                 //修改棧頂指針爲p
	return OK;
}
2.3 出棧操作算法
Status Pop (LinkStack &S, SElemType &e){//刪除s的棧頂元素,用e返回其值
	if(S==NULL) return ERROR;           //棧空
	e=S->data;                          //將棧頂元素賦給e
	p=S;                              //用p臨時保存棧頂元素空間,以備釋放
	S=S->next;                          //修改棧頂指針
	delete p;                          //釋放原棧頂元素的空間
	return OK;
}
2.4 取棧頂元素算法
SElemtype GetTop(LinkStack S){         
//返回S的棧頂元素,不修改棧頂指針
    if(S!=NULL)
       return S->data;
}

五、代碼實現

#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int SElemtype;
typedef struct Node{
    SElemtype data;
    struct Node *next;
}StackNode,*LinkStack;

//初始化棧
int InitStack(LinkStack &S){
    S = new StackNode;
    S->next = NULL;
    return OK;
}

int DestroyStack(LinkStack &S){
    LinkStack p;
    while(S){
        p = S;
        S = S->next;
        delete p;
    }
    return OK;
}

//清空棧
void ClearStack(LinkStack S){
    LinkStack p,q;
    p = S->next;
    while(p){
        q = p->next;
        delete p;
        p = q;
    }
    S->next = NULL;//頭指針指針域爲空,空棧
}

//判斷鏈棧是否爲空
int StackEmply(LinkStack S){
    return(S->next==NULL);
}
//入棧操作
void PushStack(LinkStack S,SElemtype e){
    LinkStack p;
    p = new StackNode;
    p->data = e;
    p->next = S->next;
    S->next = p;
}

//出棧操作
int PopStack(LinkStack S,SElemtype &e){
    LinkStack p;
    if(StackEmply(S))
    	return ERROR;
    p = S->next;
    e = p->data;
    S->next = p->next;
    delete p;
    return OK;
}

//取棧頂元素
int GetTop(LinkStack S,SElemtype e){
    LinkStack p;
    if(StackEmply(S))
        return ERROR;
    p = S->next;
    e = p->data;
    return OK;
}

//輸出鏈棧
void DispStack(LinkStack S){
    LinkStack p = S->next;
    printf("鏈棧爲:");
    if(StackEmply(S)){
        printf("棧空!\n");
        return;
    }
    while(p){
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}

//顯示菜單
void Showmenu(){
    printf("\n      ---鏈棧基本操作---     \n");
    printf("*******************************\n");
    printf("*       1、初始化鏈棧          *\n");
    printf("*       2、創建鏈棧            *\n");
    printf("*       3、入棧操作            *\n");
    printf("*       4、出棧操作            *\n");
    printf("*       5、取棧頂元素          *\n");
    printf("*       0、退出程序            *\n");
    printf("*******************************\n");
    printf("請選擇菜單(0-5):");
}

void Stack(){
    int choice,m,e;
    SElemtype item;
    LinkStack S;
    int flag = 0;
    while(choice){
        Showmenu();
        scanf("%d",&choice);
        switch(choice){
        case 1:
            if(InitStack(S)){
                printf("初始化鏈棧成功!\n");
                flag = 1;
            }else
                printf("初始化鏈棧失敗!\n");
            break;
        case 2:
        	if(flag){
				printf("請輸入鏈棧長度:");
				scanf("%d",&m);
				for(int i = 0;i<m;i++){
					e = rand()%20+1;
					PushStack(S,e);
				}
				DispStack(S);
			}else
                printf("初始化鏈棧失敗!\n");
            break;
        case 3:
            if(flag){
                printf("請輸入入棧元素值:");
                scanf("%d",&item);
                PushStack(S,item);
                printf("元素已入棧!\n");
                DispStack(S);
            }else{
                printf("鏈棧不存在,操作失敗!\n");
            }
            break;
        case 4:
            if(flag){
                if(PopStack(S,item))
                    printf("出棧元素爲:%d !\n",item);
                else printf("棧空!\n");
                DispStack(S);
            }else{
                printf("鏈棧不存在,操作失敗!\n");
            }
            break;
        case 5:
        	if(flag){
	            if(GetTop(S,item))
	                printf("棧頂元素爲:%d!\n",item);
	            else printf("棧空!\n");
	                DispStack(S);
            }
			else{
                printf("鏈棧不存在,操作失敗!\n");
            }
            break;
        case 0:
            printf("\t程序結束!\t\n");
            DestroyStack(S);
        	break;
        default:
            printf("選擇錯誤,請重新選擇!!\n");
            break;
        }
    }
}

//主函數
int main(){
    Stack();
    return 0;
}

作者文壇寫於2020年5月10日

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章