C語言-棧tack順序存儲和鏈式存儲

理解棧tack

棧也是一種特殊的線性表,棧的工作原理是先進後出,因此在對棧操作時只能在棧頂操作。棧的插入操作,叫作入棧(壓棧),棧的刪除操作,叫作出棧(彈棧)。

                    

棧的順序存儲選擇尾部壓棧和彈棧時,不會涉及到數組元素的大量移動。

                   

棧的鏈式存儲選擇在鏈表頭部入棧和出棧時,減少了數組元素的大量移動

注意:在棧的鏈式存儲中結點中涉及了指針變量,因此入棧的結點都需要malloc,在出棧時需要釋放結點內存

stack棧的順序存儲

棧的順序存儲類似線性表的順序存儲

//SeqStack.h
#pragma once
typedef void SeqStack;
//創建棧
SeqStack* SeqStack_Create(int capacity);
//銷燬棧
void SeqStack_Destroy(SeqStack* stack);
//清空棧
void SeqStack_Clear(SeqStack* stack);
//壓棧
int SeqStack_Push(SeqStack* stack, void* item);
//彈棧
void* SeqStack_Pop(SeqStack* stack);
//獲取棧頂元素
void* SeqStack_Top(SeqStack* stack);
//獲取棧的大小
int SeqStack_Size(SeqStack* stack);
//獲取棧的容量
int SeqStack_Capacity(SeqStack* list);

stack棧的鏈式存儲

//LinkStack.h
#pragma once
typedef void LinkStack;
//創建鏈棧
LinkStack* LinkStack_Create();
//銷燬鏈棧
void LinkStack_Destroy(LinkStack* stack);
//清空鏈棧
void LinkStack_Clear(LinkStack* stack);
//壓棧
int LinkStack_Push(LinkStack* stack, void* item);
//彈出
void* LinkStack_Pop(LinkStack* stack);
//獲取棧頂元素
void* LinkStack_Top(LinkStack* stack);
//獲取棧的大小
int LinkStack_Size(LinkStack* stack);

入棧出棧操作分析

入棧時需要爲結點分配內存空間(鏈棧的結點包含了指向後繼結點的指針域)。同樣出棧時需要釋放爲結點分配的內存。

//LinkStack.c
#pragma warning(disable : 4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "LinkStack.h"
#include "LinkList.h"

//棧中的結點去包含鏈表結點
typedef struct tag_LinkStackNode
{
    TLinkListNode node;
    void* item;
}TLinkStackNode;
//創建鏈棧
LinkStack * LinkStack_Create()
{
    LinkStack* temp = (LinkStack*)LinkList_Creat();
    return temp;
}
//銷燬棧
void LinkStack_Destroy(LinkStack* stack)
{
    LinkStack_Clear(stack);
    LinkList_Destroy((LinkList *)stack);
    return;
}
//清空棧
void LinkStack_Clear(LinkStack* stack)
{
    if (stack == NULL)
    {
        printf(" LinkStack_Clear err:stack = NULL");
        return;
	}
    //依次從棧頂彈出結點元素
    while (LinkStack_Size(stack) > 0)
    {
        LinkStack_Pop(stack);
    }
    return;
}
//入棧
int LinkStack_Push(LinkStack* stack, void* item)
{
    TLinkStackNode* temp = NULL;
    int ret = 0;
    if (stack == NULL || item == NULL)
    {
        printf(" LinkStack_Push err: stack = NULL || item = NULL");
        return -1;
    }
    temp = (TLinkStackNode *)malloc(sizeof(TLinkStackNode));//爲結點分配內存
    if (temp == NULL)
    {
        return -2;
    }
    memset(temp, 0, sizeof(TLinkStackNode));//初始化結點
    temp->item = item;//保存結點數據
    ret = LinkList_inster(stack, (TLinkListNode*)temp, 0);//入棧
    if (ret != 0)
    {
        printf(" LinkList_inster err:%d\n", ret);
        if (temp != NULL)
        {
            free(temp);
        }
        return ret;
    }
    return ret;
}
//出棧
void * LinkStack_Pop(LinkStack* stack)
{
    TLinkStackNode* temp = NULL;
    void *item = NULL;
    if (stack == NULL)
    {
        printf(" LinkStack_Pop err:stack = NULL");
        return NULL;
    }
    temp = (TLinkStackNode *)LinkList_Delete(stack, 0);//刪除棧頂元素,並返回結點
    if (temp != NULL)
    {
        item = temp->item;//獲取結點數據
        free(temp);//釋放結點
    }
    return item;//返回結點數據
}
//獲取棧頂元素
void * LinkStack_Top(LinkStack* stack)
{
    TLinkStackNode* temp = NULL;
    if (stack == NULL)
    {
        printf(" LinkStack_Top err:stack = NULL");
        return NULL;
    }
    temp = (TLinkStackNode *)LinkList_Get(stack, 0);
    if (temp == NULL)
        return NULL;
    return temp->item;
}
//獲取棧的大小
int LinkStack_Size(LinkStack* stack)
{
    if (stack == NULL)
    {
        printf(" LinkStack_Size err:stack = NULL");
        return -1;
    }
    return LinkList_GetLength(stack);
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章