數據結構:線性結構之棧

這世間,唯有青春和夢想不可辜負。花開正好,微風不燥,揚帆起航,追逐夢想。

從數據結構上看,棧和隊列也是線性表,不過是兩種特殊的線性表。棧只允許在的一端進行插人或刪除操作,而隊列只允許在表的一端進行插人操作、而在另一端進行刪除操作。因而,棧和隊列也可以被稱作爲操作受限的線性表。從數據類型角度講,棧和隊列是與線性表不同的重要抽象數據類型,廣泛地應用於各類軟件系統中。

什麼是棧?

棧(stack)是種只允許在一端進行插人和刪除的線性表, 它是一種操作受限的線性表。在表中只允許進行插人和刪除的端稱爲棧頂 (top),,另端稱爲棧底( bottom)。棧的插人操作通常稱爲人棧或進棧( push ),而棧的刪除操作則稱爲出棧或退棧( pop )。當棧中無數據元素時,稱爲空棧。根據棧定義,每次進棧的元素都被放在原棧頂元素之上而成爲新的棧項,而每次出棧的總是當前棧中“最新”的元素,即最後進棧的元素。棧具有後進先出的特性,因此又稱爲後進先出(Last In First Out, LIFO) 表。
在這裏插入圖片描述

(一)棧的順序存儲結構

利用順序存儲方式實現的棧稱爲順序棧。
類似於順序表的定義,棧中的數據元素用一個預設的足夠長度的一維數組來實現: datatype data[MAXSIZE],棧底位置可以設置在數組的任一個端點,而由於順序表在元素尾部的插入和刪除最爲方便,因此棧頂一般選着在元素尾部,用一個int top來作爲棧頂的指針,指明當前棧頂的位置。

C語言實現順序棧
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 50
#define dataType int
typedef struct {

    dataType data[MAXSIZE];
    int top;
}SeqStack;


//初始化順序棧
SeqStack* Init_SeqStack(){

    SeqStack* s = (SeqStack*)malloc(sizeof(SeqStack));
    s->top = 0;
    return s;
}

//非空判斷
int IsEmpty_SeqStack(SeqStack* s){
    if (s->top == 0) {
        return 1;
    } else{
        return 0;
    }
}

//判滿
int IsFull_SeqStack(SeqStack* s){
    if (s->top == MAXSIZE){
        return 1;
    } else{
        return 0;
    }
}

//入棧
int Push_SeqStack(SeqStack* s,dataType elem){

    if (IsFull_SeqStack(s)){
        return 0;
    }
    s->data[s->top] = elem;
    s->top ++;
    return 1;
}

//出棧
int Pop_SeqStack(SeqStack* s , dataType* elem){

    if(IsEmpty_SeqStack(s)){
        return 0;
    }
    s->top --;
    *elem = s->data[s->top];
    return 1;
}

//取棧頂元素
dataType GetTop_SeqStack(SeqStack* s){

    if (IsEmpty_SeqStack(s)){
        return 0;
    }
    return s->data[s->top - 1];
}

Java實現順序棧

基於上一篇博客實現的順序表,這裏直接複用SeqList實現順序棧。
數據結構:線性數據結構

package cn.boom.stack;

public interface Stack<T> {
    public abstract int getSize(); //獲取元素個數
    public abstract void push(T elem);   //入棧
    public abstract T pop();       //出棧
    public abstract T getTop();    //獲取棧頂元素
    public abstract boolean isEmpty();//判空
}
package cn.boom.stack;

public class SeqStack<T> implements Stack<T> {

    private SeqList<T> seqList;

    public SeqStack() {
        seqList = new SeqList<T>();
    }

    @Override
    public int getSize() {
        return seqList.getSize();
    }

    @Override
    public void push(T elem) {
        seqList.addLast(elem);
    }

    @Override
    public T pop() {
        return  seqList.removeLast();
    }

    @Override
    public T getTop() {
        return seqList.getIndexOf(seqList.getSize() - 1);
    }

    @Override
    public boolean isEmpty() {
        return seqList.isEmpty();
    }
}

(二)棧的鏈式存儲結構

要避免棧上溢,更好的辦法是使用鏈式存儲結構,所以棧也可以採用鏈式存儲結構表示,這種結構的棧簡稱爲鏈棧。
根據鏈表的特點,由於頭結點的存在,因而棧頂應取鏈表第一個結點操作方便,棧底就是鏈表的最後一個結點,因此,新入棧的元素即爲鏈表新的第一個結點, 只要系統還有存儲空間,就不會有棧滿的情況發生。一個鏈棧可由棧頂指針top唯一確定。
在這裏插入圖片描述

C語言實現鏈棧
#include <stdlib.h>
#include <stdio.h>
#define dataType int

typedef struct Stacknode{
    dataType data;
    struct Stacknode *next;
}slStacktype;

//初始化鏈棧
slStacktype *Init_slStacktype(){
    slStacktype *top = (slStacktype *) malloc(sizeof(slStacktype));
    top->next = NULL;
    return top;
}

//非空判斷
int IsEmpty_slStacktype(slStacktype *top){
    if (top->next == NULL) {
        return 1;
    } else {
        return 0;
    }
}

//入棧
int Push_slStacktype(slStacktype *top, dataType elem) {

    slStacktype *s = (slStacktype *) malloc(sizeof(slStacktype));
    //malloc申請空間失敗
    if (s == NULL){
        return 0;
    }
    s->data = elem;
    s->next = top->next;
    top->next = s;
    return 1;
}

//出棧
int Pop_slStcaktype(slStacktype *top ,dataType *elem) {

    if (!IsEmpty_slStacktype(top)) {

        slStacktype *p = top->next;
        *elem = p->data;
        top->next = p->next;
        free(p);
        return 1;

    } else {
        return 0;
    }
}
Java實現鏈棧

基於上一篇博客實現的鏈表,這裏直接複用LinkedListList實現鏈棧。
數據結構:線性數據結構

package cn.boom.stack;

public class LinkedListStack<T> implements Stack<T> {

    private LinkedList<T> linkedList;

    public LinkedListStack() {
        linkedList = new LinkedList<T>();
    }

    @Override
    public int getSize() {
        return linkedList.getSize();
    }

    @Override
    public void push(T elem) {
        linkedList.addFirst(elem);
    }

    @Override
    public T pop() {
        return linkedList.remove(0);
    }

    @Override
    public T getTop() {
        return linkedList.get(0);
    }

    @Override
    public boolean isEmpty() {
        return linkedList.isEmpty();
    }
}

參考文獻

[1]王曙燕.數據結構與算法:人民郵電出版社
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章