c语言链表存储在栈区,C语言 复杂的栈(链表栈)

//复杂的栈--链表栈

#include#include

#define datatype int//定义链表栈数据类型

//定义链表栈结构

structstacklink{

datatype data;struct stacklink *pnext;

};

typedefstructstacklink StackLink;//判断栈是否为空

int isempty(StackLink *phead);//进栈

StackLink * push(StackLink *phead, datatype num);//出栈

StackLink * pop(StackLink *phead, StackLink *pout);//清空

StackLink * setempty(StackLink *phead);//遍历栈中的数据

void findall(StackLink *phead);//链表栈容量无限大,但是代价是增加链表遍历成本

voidmain(){//定义链表栈的头指针

StackLink * phead =NULL;//压栈

phead = push(phead, 1);

phead= push(phead, 2);

phead= push(phead, 3);

phead= push(phead, 4);

phead= push(phead, 5);//打印栈中的数据

findall(phead);//出栈

StackLink *pout = (StackLink *)malloc(sizeof(StackLink));

phead=pop(phead, pout);

printf("弹出的元素是%d;", pout->data);free(pout);全部出栈

//while (phead!=NULL){//StackLink *pout = malloc(sizeof(StackLink));//phead = pop(phead, pout);//printf("

弹出的元素是%d;

", pout->data);//free(pout);//}

printf("================================");//打印栈中的数据

findall(phead);

printf("================================");//清空栈内元素

phead =setempty(phead);//打印栈中的数据

findall(phead);

system("pause");

}//判断栈是否为空

int isempty(StackLink *phead){if (phead ==NULL)

{return 1;

}else{return 0;

}

}//进栈

StackLink * push(StackLink *phead, datatype num){//分配内存空间

StackLink *p = (StackLink *)malloc(sizeof(StackLink));

StackLink*p1 =phead;

p->data =num;

p->pnext =NULL;//判断栈是否为空

if(isempty(phead))

{//栈为空

phead =p;//注意:这里是给指针副本phead赋值,但是main()函数里phead的值并没有变化

//要在函数里修改一个指针的值,应该使用二级指针,但是根据代码优化原则,尽量不使用二级指针,

//因此我们将phead当做返回值返回

}else{while (p1->pnext !=NULL){

p1= p1->pnext;

}

p1->pnext =p;//这里的phead->pnext会直接影响main()函数里phead的值,因为phead->pnext本质上等于(*phead).pnext//修改的是phead指针指向数据的值,而不是修改phead本身

}returnphead;

}//遍历栈中的数据

void findall(StackLink *phead){

StackLink*p =phead;while (p !=NULL){

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

p= p->pnext;

}

}//出栈

StackLink * pop(StackLink *phead, StackLink *pout){if (phead == NULL)//判断栈是否为空

{returnNULL;

}else{

pout->pnext =NULL;//不为空//出栈,每次弹出最后一个//分两种情况//1.只有一个元素,只有一个元素,只需要弹出头指针本身

if (phead->pnext ==NULL)

{//pout = phead; 错误,这样只是改变pout指向的地址,而free(phead)会彻底释放phead指向地址的内存//结果就是pout也为NULL

pout->data = phead->data;//注意:链表栈删除必须释放内存

free(phead);

phead=NULL;//这个改变形参phead的值,所以只能返回phead,而有任何地方修改pout的值

returnphead;

}//2.多个元素,找到倒数第二个元素

else{

StackLink*p =phead;while (phead->pnext->pnext !=NULL){

phead= phead->pnext;

}

pout->data = phead->pnext->data;//删除栈中最后一个元素

free(phead->pnext);

phead->pnext =NULL;returnp;

}

}

}//清空

StackLink * setempty(StackLink *phead){//清空的思路是,1,2,3,4,5通过头指针找到1,将2删除,把3移到2的位置上,再删除3//不太清楚循环次数,所以用while

StackLink *p =NULL;while (phead->pnext != NULL){//当第二个元素是NULL的时候,退出循环//删除第二个//p是第三个的指针

p = phead->pnext->pnext;//开始删除第二个

free(phead->pnext);

phead->pnext =p;

}//最后删除第一个元素

free(phead);returnNULL;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值