資料結構---用順序表實現棧的基本操作
阿新 • • 發佈:2019-01-27
順序表實現棧
順序棧:棧的順序儲存結構,是利用一組地址連續的儲存單元依次存放自棧底到棧頂的資料元素,同時附設指標top指示棧頂元素在順序 棧中的位置。
棧在資料結構中也是一個比較重要的結構,它有一個重要的特性是:先進後出。先入棧的元素最後出棧。具體結構如下:
在順序棧中有三個元素,一個是儲存資料的陣列。還有一個用於儲存當前順序棧的有效大小。另外一個就是這個順序棧的容量。當前最大能儲存多少個元素。
typedef struct SeqStack
{
DataType *data;
size_t size;
size_t capacity;
}SeqStack ;
為了可以使寫的這個順序棧還能被其它使用,就可以將當前棧儲存的元素重定義一下,在以後需要儲存其它型別的資料時可以方便修改。
typedef char DataType;
接下來就看一看具體的實現:
初始化順序棧,先預設當前棧為可以儲存三個元素的棧。
//初始化
void SeqStackInit(SeqStack *s)
{
assert(s);
s->size = 0;
s->capacity = 3;
//初始化當前陣列有三個元素
s->data = (DataType*)malloc(sizeof(DataType )*3);
}
銷燬順序棧,只需將當前的size與capacity置零,並將儲存的陣列釋放掉,一定記得要釋放,因為陣列的是我們人為開闢的空間,不釋放會造成記憶體洩漏。
//銷燬
void SeqStackDestroy(SeqStack *s)
{
assert(s);
if(s->data == NULL)
return;
s->size = 0;
s->capacity = 0;
free(s->data);
s->data = NULL;
s = NULL;
}
擴容是為了入棧的時候空間不夠,需要將當前順序棧擴容到可以儲存得下當前的元素。
//擴容
SeqStack* Expand(SeqStack *s)
{
DataType *tmp = (DataType*)malloc(2*s->capacity);
memmove(tmp,s->data,s->size);
free(s->data);
s->data = tmp;
s->capacity = (s->capacity) * 2;
return s;
}
入棧操作,一定記得是在陣列的頭部插入。將size加1。再把當data從當前位置向後移動一個元素的大小。
//入棧
void SeqStackPush(SeqStack *s,DataType data)
{
assert(s);
if(s->data == NULL)
return;
if(s->size >= s->capacity)
s = Expand(s);
memmove(s->data + 1,s->data,s->size);
s->size++;
s->data[0] = data;
}
順序棧的出棧操作,將當前的data向前移動一個元素大小的位置。出棧時是後入棧的元素先出棧。即從棧頂元素開始出棧。
//出棧
void SeqStackPop(SeqStack *s)
{
assert(s);
if(s->data == NULL)
return;
memmove(s->data,s->data + 1,s->size-1);
s->size--;
}
取棧頂元素(即最後入棧的元素),陣列第一個元素。
//取棧頂元素
DataType SeqStackTop(SeqStack s)
{
assert(s.data);
return *(s.data);
}
列印順序棧,這個就是為了測試功能時,方便檢視當前順序棧的儲存情況。
//列印順序棧
void Print(SeqStack *s)
{
size_t size = 1;
DataType *tmp = s->data;
while(size <= s->size)
{
printf("%c ",*tmp++);
size++;
}
printf("\n");
}
最後來看一下順序棧的測試程式碼:
#define TESTHEAD printf("------------------------%s--------------------------\n",__FUNCTION__)
void testPush()
{
SeqStack s;
SeqStackInit(&s);
SeqStackPush(&s,'a');
SeqStackPush(&s,'b');
SeqStackPush(&s,'c');
SeqStackPush(&s,'d');
SeqStackPush(&s,'e');
Print(&s);
}
void testPop()
{
SeqStack s;
SeqStackInit(&s);
SeqStackPush(&s,'a');
SeqStackPush(&s,'b');
SeqStackPush(&s,'c');
SeqStackPush(&s,'d');
SeqStackPush(&s,'e');
Print(&s);
SeqStackPop(&s);
Print(&s);
SeqStackPop(&s);
Print(&s);
SeqStackPop(&s);
Print(&s);
SeqStackPop(&s);
Print(&s);
SeqStackPop(&s);
Print(&s);
}
void testTop()
{
SeqStack s;
SeqStackInit(&s);
SeqStackPush(&s,'a');
SeqStackPush(&s,'b');
SeqStackPush(&s,'c');
SeqStackPush(&s,'d');
SeqStackPush(&s,'e');
Print(&s);
printf("棧頂元素:%c \n",SeqStackTop(s));
}
void testDestroy()
{
SeqStack s;
SeqStackInit(&s);
SeqStackPush(&s,'a');
SeqStackPush(&s,'b');
SeqStackPush(&s,'c');
SeqStackPush(&s,'d');
SeqStackPush(&s,'e');
Print(&s);
SeqStackDestroy(&s);
printf("expect NULL actual %p\n",s.data);
}
程式碼測試結果: