栈和程序运行时的栈区有什么区别?
内存中的栈区实际上类似于数据结构中的栈。两者区别的是数据结构中的栈是解决为程序开发而设计的算法问题,而在内存中的栈区是解决内存分配的问题。不过,它们俩相同点就是遵守先进后出的规则。
为什么将递归程序转化成循环时需要用到栈?
用栈保存未完成的工作,在适当的时候从栈中取出并执行。 系统保存了工作的数据和状态,数据就是函数的局部变量, 状态就是程序指针。
如果你采用递归时 是由系统管理函数栈
而要写成非递归时必须由你自已来管理一个栈.
递归的本质就是栈
//如果递归打印一个链表的所有节点,则有以下程序,也就是逆序打印
void ReversePrint(Node* pHead)
{ if(pHead)
{
ReversePrint(Node* pHead)
print("%d",pHead->data);
}
}
栈的相关题目
遍历字符串,遇到一个字符:
1.如果该括号是左括号 ( [ {,则入栈
2.如果是右括号 } ] ),则检测该括号是否与栈顶括号匹配
匹配前需要先判断栈中是否存在元素,如果有,则用当前括号与栈顶的括号比较,如果匹配,则继续遍历;如果与栈顶的括号不匹配,则直接返回false
//需要先实现一个栈
typedef int SDataType;
typedef struct Stack
{
SDataType* _array;
int _capacity;
int _top;
}Stack;
void _CheckCapacity(Stack* ps)
{
assert(ps);
if(ps->_top==ps->_capacity)
{
int newcap=ps->_capacity*2;
SDataType* pTemp=(SDataType*)malloc(sizeof(SDataType)*newcap);
if(NULL==pTemp)
{
assert(0);
return;
}
memcpy(pTemp,ps->_array,ps->_top*sizeof(SDataType));
//释放旧空间
free(ps->_array);
ps->_array=pTemp;
ps->_capacity=newcap;
}
}
void StackInit(Stack* ps)
{
assert(ps);
ps->_array=(SDataType*)malloc(sizeof(SDataType)*3);
if(NULL==ps->_array)
{
assert(0);
return;
}
ps->_capacity=3;
ps->_top=0;
}
void StackPush(Stack* ps,SDataType data)
{
assert(ps);
_CheckCapacity(ps);
ps->_array[ps->_top]=data;
ps->_top++;
}
void StackPop(Stack* ps)
{
assert(ps);
if(0==ps->_top)
return;
ps->_top--;
}
SDataType StackTop(Stack* ps)
{
assert(ps);
return ps->_array[ps->_top-1];
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
void StackDestroy(Stack* ps)
{
assert(ps);
if(ps->_array)
{
free(ps->_array);
ps->_array=NULL;
ps->_capacity=0;
ps->_top=0;
}
}
bool isValid(char * s){
if(NULL==s)
return true;
Stack st;
StackInit(&st);
for(int i=0;i<strlen(s);++i)
{
if(s[i]=='('||s[i]=='['||s[i]=='{')
{
StackPush(&st,s[i]);
}
else
{
char ch=StackTop(&st);
if((ch=='('&&s[i]==')')||(ch=='['&&s[i]==']')||(ch=='{'&&s[i]=='}'))
{
StackPop(&st);
}
else
{
return false;
}
}
}
return true;
}
用队列实现栈
使用两个队列实现入栈出栈操作
元素先全部入队列A
出队列到队列B直到队列A中只剩下一个元素,将该元素删除
再将队列B中的元素出队列到队列A直到队列B只剩下一个元素,将该元素删除,循环往复