共享棧
共享棧:兩個棧共享同一片存儲空間,這片存儲空間不單獨屬於任何一個棧,某個棧需要的多一點,它就可能得到更多的存儲空間;
兩個棧的棧底在這片存儲空間的兩端,當元素入棧時,兩個棧的棧頂指針相向而行。
基本概念
棧是一種特殊的線性表,是一種只允許在表的一端進行插入或刪除操作的線性表。表中允許進行插入、刪除操作的一端稱為棧頂。表的另一端稱為棧底。棧頂的當前位置是動態的,對棧頂當前位置的標記稱為棧頂指針。當棧中沒有數據元素時,稱之為空棧。棧的插入操作通常稱為進棧或入棧,棧的刪除操作通常稱為退棧或出棧。棧是一種特殊的線性表,是一種只允許在表的一端進行插入或刪除操作的線性表。表中允許進行插入、刪除操作的一端稱為棧頂。表的另一端稱為棧底。棧頂的當前位置是動態的,對棧頂當前位置的標記稱為棧頂指針。當棧中沒有數據元素時,稱之為空棧。棧的插入操作通常稱為進棧或入棧,棧的刪除操作通常稱為退棧或出棧。
共享棧示意圖
第一個棧從數組頭開始存儲,第二個棧從數組尾開始,兩個棧向中間拓展。
當top1+1 == top2或者top1 == top2-1時,即staock overflow!.
與普通棧一樣,共享棧出棧入棧的時間復雜度仍為O(1).
實驗報告
當一個應用程序中需要使用多少個棧時,為了提高空間的使用效率,要讓多個棧共享空間,這樣既能減少預分配的空間過多造成的浪費,又能降低發生棧上溢產生錯誤中斷的可能性,如上圖所示,僅當兩個棧相遇才會發生上溢
一、問題描述(標題黑體小四)
實現共享棧
二、實驗目的
實現共享棧
三、實驗設計
1.邏輯結構
邏輯結構是指數據元素之間的邏輯關系,即從邏輯關系上描述數據。它與數據的存儲無關,是獨立於計算機的。數據的邏輯結構分為線性結構和非線性結構,線性表是典型的線性結構;集合、樹和圖是典型的非線性結構。數據的邏輯結構分類見圖1-1。
- 集合結構中的數據元素之間除了 “同屬於一個集合”的關系外,別無其他關系。
- 線性結構結構中的數據元素之間只存在一對一的關系。
- 樹形結構結構中的數據元素之間存在一對多的關系。
- 圖狀結構或網狀結構結構中的數據元素之間存在多對多的關系。
棧是特殊的線性表,它的邏輯結構和線性表相同,只是起操作規則受到了限制,因此,又稱它是操作受限的線性表。共享棧也是棧,故邏輯結構為線性結構。
2.存儲結構
存儲結構是指數據結構在計算機中的表示(又稱映像),也稱物理結構。它包括數據元素的表示和關系的表示。數據的存儲結構是邏輯結構用計算機語言的實現,它依賴於計算機語言。數據的存儲結構主要有:順序存儲、鏈式存儲、索引存儲和散列存儲。
- 順序存儲:把邏輯上相鄰的元素存儲在物理位置上也相鄰的存儲單元里,元素之間的關系由存儲單元的鄰接關系來體現。其優點是可以實現隨機存取,每個元素占用最少的存儲空間;缺點是只能使用相鄰的一整塊存儲單元,因此可能產生較多的外部碎片。
- 鏈接存儲:不要求邏輯上相鄰的元素在物理位置上也相鄰,借助指示元素存儲地址的指針表示元素之間的邏輯關系。其優點是不會出現碎片現象,充分利用所有存儲單元;缺點是每個元素因存儲指針而占用額外的存儲空間,並且只能實現順序存取。
- 索引存儲:在存儲元素信息的同時,還建立附加的索引表。索引表中的每一項稱為索引項,索引項的一般形式是:(關鍵字,地址)。其優點是檢索速度快;缺點是增加了附加的索引表,會占用較多的存儲空間。另外,在增加和刪除數據時要修改索引表,因而會花費較多的時間。
- 散列存儲:根據元素的關鍵字直接計算出該元素的存儲地址,又稱為Hash存儲。其優點是檢索、增加和刪除結點的操作都很快;缺點是如果散列函數不好可能出現元素存儲單元的沖突,而解決沖突會增加時間和空間開銷。
可以采用順序表,也可以采用鏈式表。本次實驗用順序表實現。故本次為順序存儲。
/---變量的定義---/
typedef int Selemtype;
#define Maxsize 100 //定義共享棧中元素的最大個數
#define TURE 1;
#define FALSE 0;
/---棧的順序存儲結構---/
typedef struct
{
Selemtype data[Maxsize]; //棧的大小
int top1; //第一個棧的棧頂
int top2; //第二個棧的棧頂
}ShareStack;
3.算法設計思想
兩個棧共享一個存儲空間,top1棧在指向空間的左端,依次向右入棧同時top1++,top2棧在指定空間的右端,依次向左入棧同時top2--,
棧滿,既
S1入棧:指針右移一個位置,即stack[++top[0]]=x;
S2入棧:指針左移一個位置,即stack[--top[0]]=x;
當top1-1 = top2時 棧滿
4.輸入、輸出設計
輸入:入棧(數字+棧序)
結束入棧操作(F)
輸出:出棧(棧內存儲變量值)
四、主要代碼
/---初始化---/
int InitStack(ShareStack *s)
{
s->top1 = 0;
s->top2 = Maxsize-1;
return TURE;
}
/---判斷共享棧是否為空---/
int IsEmpty(ShareStack *s)
{
if(s->top1==0 && s->top2==Maxsize-1)
{
return TURE;
}
return FALSE;
}
/---入棧操作---/
int pushSStack(ShareStack *s,Selemtype x,int stackNum)
{
if(s->top1 == s->top2+1)
{
return FALSE;
}
switch(stackNum)
{
case 1:s->data[s->top1++] = x;break;
case 2:s->data[s->top2--] = x;break;
}
return TURE;
}
/---出棧操作---/
int PopSStack(ShareStack *s,Selemtype *x,int stackNum)
{
switch(stackNum)
{
case 1:
{
if(s->top1 == 0) return FALSE;
*x = s->data[--s->top1];
};break;
case 2:
{
if(s->top2==Maxsize-1) return FALSE;
*x = s->data[++s->top2];
};break;
}
return TURE;
}
五、程序運行結果截圖
六、遇到的問題和解決方法
問題:棧空輸出臨界重復輸出數值
解決方法:利用if語句進行先判斷后打印操作
完整代碼
點擊查看代碼
#include <stdio.h>
#include <stdlib.h>
#include "SStack.h" //自定義頭文件 內部有共享棧的定義初始化 出入棧 判斷棧空等函數
int main(){
ShareStack *s;
s = (ShareStack *)malloc(sizeof(ShareStack));
InitStack(s);
int n;
int SStackNum;
char c;
/*---判斷棧空---*/
if(IsEmpty(s))
printf("棧空\n");
else
printf("棧不空\n");
printf("入棧\n");
while(!(c = getchar() == 'F') )
{
printf("輸入入棧數字和棧序(末尾加F:退出):");
scanf("%d %d",&n,&SStackNum);
pushSStack(s,n,SStackNum);
}
printf("出棧\n");
while(!(c = getchar() == 'F') )
{
printf("輸入出棧序(末尾加F:退出):");
scanf("%d",&SStackNum);
if(PopSStack(s,&n,SStackNum))
printf("%d\n",n);
else
break;
}
/*---判斷棧空---*/
if(IsEmpty(s))
printf("棧空");
else
printf("棧不空");
}