1. 程式人生 > >資料結構---用順序表實現棧的基本操作

資料結構---用順序表實現棧的基本操作

順序表實現棧

   順序棧:棧的順序儲存結構,是利用一組地址連續的儲存單元依次存放自棧底到棧頂的資料元素,同時附設指標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);
}

   程式碼測試結果:
測試結果