大話數據結構系列之共享棧結構(八)

共享棧定義

共享棧圖解
在這裏插入圖片描述

推理
它們是在數組的兩端,向中間靠攏。top1 和 top2 是棧 1 和棧 2 的棧頂指針,可以想象,只要它們倆不見面,兩個棧就可以一直使用。

優點
理論上適用一塊兒地兒,辦了兩塊地兒的事兒,節省了 1/2 的空間。

適用情景
比較適用於兩個棧的空間需求有相反關係的情況,也就是一個棧增長時,另一個棧在縮短。
跟買股票一樣,你買入時,一定是有一個你不知道的人在做賣出操作。

實際例子:線程還是協程(有棧的),共享一塊兒內存空間

共享棧代碼實現( C、Java)

C 語言實現

#include "stdio.h"    
#include "stdlib.h"   
#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存儲空間初始分配量 */

typedef int Status; 

typedef int SElemType; /* SElemType類型根據實際情況而定,這裏假設爲int */


/* 兩棧共享空間結構 */
typedef struct 
{
        SElemType data[MAXSIZE];
        int top1;   /* 棧1棧頂指針 */
        int top2;   /* 棧2棧頂指針 */
}SqDoubleStack;


Status visit(SElemType c)
{
        printf("%d ",c);
        return OK;
}

/*  構造一個空棧S */
Status InitStack(SqDoubleStack *S)
{ 
        S->top1=-1;
        S->top2=MAXSIZE;
        return OK;
}

/* 把S置爲空棧 */
Status ClearStack(SqDoubleStack *S)
{ 
        S->top1=-1;
        S->top2=MAXSIZE;
        return OK;
}

/* 若棧S爲空棧,則返回TRUE,否則返回FALSE */
Status StackEmpty(SqDoubleStack S)
{ 
        if (S.top1==-1 && S.top2==MAXSIZE)
                return TRUE;
        else
                return FALSE;
}

/* 返回S的元素個數,即棧的長度 */
int StackLength(SqDoubleStack S)
{ 
        return (S.top1+1)+(MAXSIZE-S.top2);
}

/* 插入元素e爲新的棧頂元素 */
Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
        if (S->top1+1==S->top2) /* 棧已滿,不能再push新元素了 */
                return ERROR;   
        if (stackNumber==1)         /* 棧1有元素進棧 */
                S->data[++S->top1]=e; /* 若是棧1則先top1+1後給數組元素賦值。 */
        else if (stackNumber==2)    /* 棧2有元素進棧 */
                S->data[--S->top2]=e; /* 若是棧2則先top2-1後給數組元素賦值。 */
        return OK;
}

/* 若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR */
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{ 
        if (stackNumber==1) 
        {
                if (S->top1==-1) 
                        return ERROR; /* 說明棧1已經是空棧,溢出 */
                *e=S->data[S->top1--]; /* 將棧1的棧頂元素出棧 */
        }
        else if (stackNumber==2)
        { 
                if (S->top2==MAXSIZE) 
                        return ERROR; /* 說明棧2已經是空棧,溢出 */
                *e=S->data[S->top2++]; /* 將棧2的棧頂元素出棧 */
        }
        return OK;
}

Status StackTraverse(SqDoubleStack S)
{
        int i;
        i=0;
        while(i<=S.top1)
        {
                visit(S.data[i++]);
        }
        i=S.top2;
        while(i<MAXSIZE)
        {
                visit(S.data[i++]);
        }
        printf("\n");
        return OK;
}

int main()
{
        int j;
        SqDoubleStack s;
        int e;
        if(InitStack(&s)==OK)
        {
                for(j=1;j<=5;j++)
                        Push(&s,j,1);
                for(j=MAXSIZE;j>=MAXSIZE-2;j--)
                        Push(&s,j,2);
        }

        printf("棧中元素依次爲:");
        StackTraverse(s);

        printf("當前棧中元素有:%d \n",StackLength(s));

        Pop(&s,&e,2);
        printf("彈出的棧頂元素 e=%d\n",e);
        printf("棧空否:%d(1:空 0:否)\n",StackEmpty(s));

        for(j=6;j<=MAXSIZE-2;j++)
                Push(&s,j,1);

        printf("棧中元素依次爲:");
        StackTraverse(s);

        printf("棧滿否:%d(1:否 0:滿)\n",Push(&s,100,1));

        
        ClearStack(&s);
        printf("清空棧後,棧空否:%d(1:空 0:否)\n",StackEmpty(s));
        
        return 0;
}

Java 語言實現

package com.example.stack;

/* 兩棧共享空間結構 */
public class SqDoubleStack<T> {
    
    /* 存儲空間初始分配量 */
    int maxsize=20; 
    
     /* 數組,存儲數據元素 */
    Object[] values = new Object[20];
    
    /* 線性表當前長度 */
    int length;
    
    /* 棧1棧頂指針 */
    int top1; 
    
    /* 棧2棧頂指針 */
    int top2;
    
    /*  構造一個空棧S */
    int initStack(){
     this.top1 = -1;
     this.top2 = maxsize;
     return 1;  
    }
    
    /* 把S置爲空棧 */
    int clearStack(){
        this.top1 = -1;
         this.top2 = maxsize;
         return 1;  
    }
    
    /* 若棧S爲空棧,則返回TRUE,否則返回FALSE */
    boolean stackEmpty(){
        if( this.top1 == -1 && this.top2 == this.maxsize)
            return true;
        else
            return false;
    }
    

    /* 返回S的元素個數,即棧的長度 */
    int stackLength(){
        return (this.top1 + 1) + (this.maxsize - this.top2);
    }
    
    
    /* 插入元素e爲新的棧頂元素 */
    int push(T elem,int stackNumber){
        if(this.top1 + 1== this.top2){
            System.out.println("棧已滿,不能再push新元素了!");
            return -1;
        }
        if(stackNumber == 1)
            this.values[++this.top1] = elem;
        else if(stackNumber ==2)
            this.values[--this.top2] = elem;
        else
            System.out.println("stackNumber有誤!");
        return 1;
    }
    
    @SuppressWarnings("unchecked")
    /* 若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR */
    T pop(int stackNumber){
        if(stackNumber == 1){
            if(this.top1 == -1)
                throw new NullPointerException();
            return (T)this.values[this.top1--];
        }else if(stackNumber == 2){
            if(this.top2 == this.maxsize)
                throw new NullPointerException();
            return (T)this.values[this.top2++];
        }else
            System.out.println("stackNumber有誤!");
        return null;
    }
    
    /* 從棧底到棧頂依次對棧中每個元素顯示 */
    void stackTraverse(){
        int i =0;
        while (i <= this.top1){
            System.out.println(this.values[i++]);
        }
        i = this.top2;
        while (i < this.maxsize){
            System.out.println(this.values[i++]);
        }
    }
    
    public static void main(String[] args){
        int j;
        SqDoubleStack<Integer> s = new SqDoubleStack<Integer>();
        if(s.initStack() == 1)
        {
                for(j=1;j<=5;j++)
                        s.push(j,1);
                for(j=s.maxsize;j>=s.maxsize-2;j--)
                        s.push(j,2);
        }

        System.out.println("棧中元素依次爲:");
        s.stackTraverse();

        System.out.println("當前棧中元素有:%d \n"+s.stackLength());

        
        System.out.println("彈出的棧頂元素 e=%d\n"+s.pop(2));
        System.out.println("棧空否:%d(1:空 0:否)\n"+s.stackEmpty());

        for(j=6;j<=s.maxsize-2;j++)
                s.push(j,1);

        System.out.println("棧中元素依次爲:");
        s.stackTraverse();

        System.out.println("棧滿否:%d(1:否 0:滿)\n"+s.push(100,1));
        
        s.clearStack();
        System.out.println("清空棧後,棧空否:%d(1:空 0:否)\n"+s.stackEmpty());
    }
    
}
發佈了240 篇原創文章 · 獲贊 91 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章