动态栈
栈:动态栈和静态栈
->动态栈的基本内核是单链表(离散存储)(砍掉单链表的一些操作[对单链表增加一些限制条件]就可以形成栈);
->静态栈的基本内核是一维数组(连续存储)。栈的特点:数据元素遵从’先进后出’的规则
/*
********************动态栈******************
*/
# include <stdio.h>
# include <malloc.h>//包含malloc()函数的声明
# include <stdlib.h>//包含exit()函数的声明
//自定义节点结构体
typedef struct Node
{
int data;
struct Node * pNext;
}NODE, * PNODE;
//自定义栈结构体
typedef struct Stack
{
PNODE pTop;
PNODE pBottom;
}STACK, * PSTACK;
//declare function
void InitStack(PSTACK pS);
void PushStack(PSTACK pS,int val);
void TraverseStack(PSTACK pS);
int GetTop(PSTACK pS);
PNODE PopStack(PSTACK pS);
bool EmptyStack(PSTACK pS);
void GetDelTop(PSTACK pS,int * pVal);
int GetLength(PSTACK pS);
int main(void)
{
STACK S;//建立栈S
int val;
//初始化栈
InitStack(&S);
//压栈
PushStack(&S,1);
PushStack(&S,2);
PushStack(&S,3);
PushStack(&S,4);
printf("Output(traverse):");
TraverseStack(&S);//遍历栈[遍历相当于指全部浏览一遍并不进行任何操作]
printf("stack length: %d\n\n",GetLength(&S));
//读栈顶元素
val = GetTop(&S);
printf("pTop value: %d\n",val);
//读取并删除栈顶元素
printf("get and delete pTop:\n");
GetDelTop(&S,&val);
printf("pTop value: %d\n",val);
printf("stack length: %d\n\n",GetLength(&S));
//出栈
printf("popstack:\n");
PopStack(&S);
printf("stack length: %d\n\n",GetLength(&S));
return 0;
}
//initialize stack
void InitStack(PSTACK pS)
{
pS->pTop = (PNODE)malloc(sizeof(NODE));//建立一个新节点(作用:让pTop和pBottom同时指向这个节点)
if(NULL == pS->pTop)
{
printf("ALLOCATION IS FAILED!\n");
exit(-1);//内存分配不成功直接退出程序
}
else
{
pS->pBottom = pS->pTop;
pS->pBottom->pNext = NULL;//初始化pBottom指针指向的节点的指针域为空(类似于单链表的头结点(它没任何作用只是便于链表操作))
}
return;
}
//push stack
void PushStack(PSTACK pS,int val)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
pNew->data = val;
pNew->pNext = pS->pTop;//链接新节点和栈顶指针
pS->pTop = pNew;//栈顶指针指向新节点
return;
}
//traverse stack
void TraverseStack(PSTACK pS)
{
PNODE p = pS->pTop;//必须新建一个指针p(指向栈顶指针指向的存储单元),不能直接操作栈顶指针因为会改变栈(遍历操作是不会改动栈的)
while(p != pS->pBottom)
{
printf("%-3d",p->data);
p = p->pNext;
}
printf("\n");
return;
}
//determine whether stack is empty or not
bool EmptyStack(PSTACK pS)
{
if(pS->pTop == pS->pBottom)//起初建立并初始化栈的时候满足其中一个条件'pS->pTop == pS->pBottom'
{
return true;
}
else
{
return false;
}
}
//get the value of pTop
int GetTop(PSTACK pS)//因为要读栈顶元素的值所以应该返回一个数据类型是'int'的值
{
if(EmptyStack(pS))
{
printf("STACK IS EMPTY!\n");
return 0;
}
else
{
return pS->pTop->data;
}
}
//pop stack
PNODE PopStack(PSTACK pS)//出栈指的是移出整个节点所以声明的数据类型是'PNODE'
{
if(EmptyStack(pS))
{
printf("STACK IS EMPTY!\n");
return NULL;
}
else
{
PNODE p = pS->pTop;
pS->pTop = pS->pTop->pNext;
free(p);//释放指针p指向的存储单元里的数据
p = NULL;//清空变量名为p的存储单元
return pS->pTop;
}
}
//get and delete pTop
void GetDelTop(PSTACK pS,int * pVal)//将获取的值存入指针pVal指向的存储单元中
{
if(EmptyStack(pS))
{
printf("STACK IS EMPTY!\n");
}
else
{
* pVal = GetTop(pS);
PopStack(pS);
}
return;
}
//get the length of stack
int GetLength(PSTACK pS)
{
int cnt = 0;//代表栈的有效长度
PNODE p = pS->pTop;//必须加一个指向‘pS->pTop’的指针p否则‘pS->pTop’会随着操作改变从而整个‘栈’会改变
if(EmptyStack(pS))
{
printf("STACK IS EMPTY!\n");
return 0;
}
else
{
while(p != pS->pBottom)
{
++cnt;
p = p->pNext;//指针指向下一个节点
}
return cnt;
}
}