栈
- 栈的概念及结构
- 栈的实现
栈的概念及结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
注:后进先出原则是相对栈里面的数据而言的,同时在栈中的数据满足后进先出。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
栈的实现
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
注:栈的实现使用数组实现,缺点是扩容。而使用链表实现,链表的结构采用单链表是最优的(将头节点的一端作为栈顶,采用头插头删的方式实现后进先出),缺点是缓存利用率低。
栈的定义
需要用结构体创建一个栈,这个结构体需要包括栈的基本内容(栈,栈顶,栈的容量)。
typedef int STDatatype;
typedef struct Stack
{STDatatype* a;int top; //栈顶int capacity;
}ST;
栈的初始化
栈的初始化只需对栈结构体中的成员进行初始化即可。
void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->top = 0; ps->capacity = 0;
}
栈的销毁
栈的销毁需要对栈申请的空间进行释放,避免内存泄漏。
void StackDestroy(ST* ps)
{assert(ps);if (ps->a){free(ps->a);}ps->a = NULL;ps->top = 0; ps->capacity = 0;
}
栈的入栈
入栈首先要先检查栈空间是否已满,如果已满需要对栈空间进行增容。最后再将数据进行入栈。
void StackPush(ST* ps, STDatatype x)
{assert(ps);// 检查空间够不够,不够就增容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDatatype* tmp = realloc(ps->a, sizeof(STDatatype)*newcapacity);if (tmp == NULL){printf("rellaoc fail\n");exit(-1);}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}
注:top不是指向最后一个数据而是指向最后一个数据的下一个位置。如果认为top指向最后一个数据(指向栈顶的数据),top就不能初始化成0而初始化成-1。
栈的出栈
出栈让栈顶的位置向下移动一位即可。但需检测栈是否为空,若为空,则不能进行出栈操作。
void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));--ps->top;
}
栈的判空
栈的判空即对检测栈是否为空,判断栈顶的位置是否是0。若栈顶是0,则栈为空;否则栈不为空。
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
栈中数据个数
求栈中数据个数只需计算top的值(top表示的是栈顶数据的下一个位置或者栈中有效数据个数)即可。
int StackSize(ST* ps)
{assert(ps);return ps->top;
}
取栈顶的数据
获取栈顶元素,即获取栈的最上方的元素。若栈为空,则不能获取。
STDatatype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top - 1];
}