数据结构——栈
目录
栈
概念与结构
栈底层结构选型
数组
链表
使用数组实现栈
编辑
初始化栈
判断栈空
入栈
出栈
取栈顶元素
栈的元素个数
销毁
栈
概念与结构
栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据遵循先进后出的原则。
压栈:栈的插入操作叫做压栈/入栈/进栈。
出栈:栈的删除操作叫做出栈。
出数据和入数据都在栈顶。
栈底层结构选型
数组
链表
那么对于数组和链表我们选择哪个比较好呢?
答案是数组。因为链表虽然动态性更强,但是每个操作都需要动态分配结点,内存开销比较大,且频繁分配/释放可能引发内存碎片。而数组尾插尾删的效率更高。
使用数组实现栈
我们就根据顺序表的结构来模拟一遍栈的结构。
typedef int STDataType;
typedef struct stack
{STDataType* arr;int top;int capacity;
}ST;
初始化栈
void STInit(ST* ps)
{assert(ps);ps->arr = NULL;ps->top = ps->capacity = 0;
}
判断栈空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
入栈
void STCheck(ST* ps)
{if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->arr, newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc failed!");exit(1);}else{ps->arr = tmp;ps->capacity = newcapacity;}}
}
void STPush(ST* ps, STDataType x)
{assert(ps);STCheck(ps);ps->arr[ps->top++] = x;
}
出栈
void STPop(ST* ps)
{assert(ps && ps->arr && !STEmpty(ps));ps->top--;
}
注意:删除的空间不能free掉,因为动态开辟的空间不能局部释放。
取栈顶元素
STDataType STTop(ST* ps)
{assert(ps && ps->arr && !STEmpty(ps));return ps->arr[ps->top-1];
}
栈的元素个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}
销毁
void STDestroy(ST* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}