C语言以链式的方式实现,栈的链式实现(C语言描述)

栈本质上是一个线性表,只不过对线性表的操作进行了限制,只可以在表的一端进行操作(插入、删除元素)。栈是一种是一种实现数据“先进后出”的存储结构,分为静态栈和动态栈,静态栈就是以数组的方式存储数据,动态栈是以链表的方式存储数据;对栈的操作算法,常用的就是压栈和出;下面将以链式的方式创建栈,并对用c语言实现栈的压栈和出栈的算法:

1.栈的创建

在创建一个数据结构之前,必须知道这种数据结构由哪些参数组成,栈的本质既然是个链表,它必然由很多节点组成;为了实现“先进后出”这种数据结构,我们需要引进两个参数,一个是栈顶指针(pTop),始终指向栈顶元素。一个参数是栈底指针(pBottom),始终指向栈底元素。我们知道为了方便描述链表的各种操作,引进了头节点的概念,即为每个链表前面加一个头节点,但并存放有效数据;同样,为了实现栈的操作,我们同样需要一个不存放任何有效数据的节点,并且栈底指针始终指向该节点;

typedefintelementype;

//定义一个节点

typedefstructNode

{

elementype data;

structNode *pNext;

}NODE,*PNODE;//

//构造一个栈

typedefstructstack

{

PNODE pTop; //栈顶指针

PNODE pBottom;//栈底指针

}STACK,*PSTACK;

其中,使用了typedef关键词,typedef只是给一个数据类型提供一个别名;因此这里的NODE=struct Node ,PNODE=struct Node *;同样,STACK=struct stack ,PSTACK=struct Node *;

此时,数据类型构造出来了,接下来要创建一个空栈,这样我们才能进行栈的操作,创建栈,无非就是分配内存,内存分配有三种方式,静态存储区,栈,堆;

//创建一个空栈,里面没有任何有效数据;

voidCreate_Stack(PSTACK S)

{

S->pBottom=(structNode *)malloc(sizeof(structNode));

if(NULL==S->pBottom)

{

printf("Memory allocation failure");

exit(-1);

}

S->pTop=S->pBottom;

S->pTop->data=0;

S->pTop->pNext=NULL;  //防止出现野指针

}

0818b9ca8b590ca3270a3433284dd417.png

图1 空栈示意图

2.压栈算法

0818b9ca8b590ca3270a3433284dd417.png

图2 压栈算法示意图

压栈的伪算法:

(1).创建一个节点p,并修改节点的指针域使其指向栈顶数据元素;p->pNext=pTop;

(2)修改栈顶指针,使其指向栈顶元素,pTop=p;

程序代码:

//进栈

voidPush_Stack(PSTACK S,intval)

{

PNODE p=(structNode *)malloc(sizeof(structNode));

if(NULL==p)

{

printf("Memory allocation failure");

exit(-1);

}

p->data=val;

p->pNext=S->pTop;  //让p的指针域指向上一个节点

S->pTop=p;        //让pTop指针指向栈顶元素

}

3.出栈算法

0818b9ca8b590ca3270a3433284dd417.png

图3.出栈算法示意图

出栈伪算法:

(1).先用P指针保存要删除数据的地址,用于便于释放此节点的内存,即p=pTop;

(2).修改栈顶指针的指向,使其指向栈顶元素;pTop=pTop->pNext;

附录:程序代码

#include

#include

#include

typedefstructNode

{

intdata;

structNode *pNext;

}NODE,*PNODE;

typedefstructStack

{

PNODE pTop;

PNODE pBottom;

}STACK,*PSTACK;

PSTACK create_stack();

voidpush_stack(PSTACK,int);

voidtraverse_stack(PSTACK);

boolpop_stack(PSTACK,int*);

boolis_empty(PSTACK);

voidclear_stack(PSTACK);

intmain()

{

intdata_pop;

//创建一个空的栈,pS指针指向该栈

PSTACK pS = create_stack();

//向该栈中压入数据,遍历该栈并输出栈中的数据

push_stack(pS,2);

push_stack(pS,6);

push_stack(pS,28);

traverse_stack(pS);

//从该栈中推出数据,遍历该栈并输出栈中的数据

if(pop_stack(pS,&data_pop))

printf("pop succeed,the data poped out is:%d\n",data_pop);

else

printf("pop failed\n");

traverse_stack(pS);

//清空栈,遍历该栈并输出栈中的数据

clear_stack(pS);

printf("data cleared!\n");

traverse_stack(pS);

return0;

}

//创建一个空栈,并返回指向该栈的指针

PSTACK create_stack()

{

PSTACK pS = (PSTACK)malloc(sizeof(STACK));

pS->pTop = (PNODE)malloc(sizeof(NODE));

if(NULL==pS || NULL==pS->pTop)

{

printf("malloc failed");

exit(-1);

}

else

{

pS->pBottom = pS->pTop;

pS->pBottom->pNext = NULL;

}

returnpS;

}

//判断该栈是否为空

boolis_empty(PSTACK pS)

{

if(pS->pTop == pS->pBottom)

returntrue;

else

returnfalse;

}

//向pS指针指向的栈中压入数据val

voidpush_stack(PSTACK pS,intval)

{

PNODE pNew = (PNODE)malloc(sizeof(NODE));

if(NULL==pNew)

{

printf("malloc failed");

exit(-1);

}

else

{

pNew->data = val;

pNew->pNext = pS->pTop;

pS->pTop = pNew;

}

return;

}

//从栈中推出数据,并将推出的数据保存在pData指针所指向的位置

boolpop_stack(PSTACK pS,int*pData)

{

if(is_empty(pS))

returnfalse;

else

{

PNODE p = pS->pTop;

*pData = p->data;

pS->pTop = p->pNext;

free(p);

p = NULL;

returntrue;

}

}

//遍历栈,并自栈顶向栈底输出栈中的数据

voidtraverse_stack(PSTACK pS)

{

PNODE pCurrent = pS->pTop;

printf("Now datas int the stack are:\n");

while(pCurrent != pS->pBottom)

{

printf("%d ",pCurrent->data);

pCurrent = pCurrent->pNext;

}

printf("\n");

return;

}

//清空栈,即将其还原为空栈

voidclear_stack(PSTACK pS)

{

if(is_empty(pS))

return;

PNODE p =NULL;

while(pS->pTop != pS->pBottom)

{

p = pS->pTop;

pS->pTop = p->pNext;

free(p);

p = NULL;

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值