永发信息网

描述如何用单向链表表示一个堆栈

答案:1  悬赏:60  手机版
解决时间 2021-03-24 06:46
描述如何用单向链表表示一个堆栈
最佳答案
单向链表实现堆栈
要求:
1 使用C语言;
2 使用单向链表;
3 接口规范,通用性强;
解:
1 链表元素的类型确定
为了最终确定这两个函数的调用模型,你还需要知道进出堆栈的数据是属于哪种类型的。也就是说,你得声明一个struct结构作为链表元素的数据类型。
如果没有特殊要求,应该考虑使用无类型指针来实现一个通用的解决方案。基于无类型指针的struct结构和函数调用模型如下所示:
[cpp] view plain copy
typedef struct elementT
{
struct elementT*next;
void *data;
}element;
2 push(压入)和pop(弹出)
push(压入)和pop(弹出)例程是每一种堆栈实现方案中都不可缺少的。
2.1 push例程设计过程
首先,把某堆栈作为一个输入参数传递给这个函数;
其次,把将被压入堆栈的某项数据传递给push函数。
要想把某个堆栈作为一个输入参数,最简单的办法莫过于在函数调用过程中传递一个指向该堆栈的指针。
因为堆栈将被实现为一个单向链表,所以这个指向堆栈的指针就将是一个指向该链表第一个元素的指针。
除这个指向堆栈的指针外,你还需要把那个将被压入堆栈的数据安排为push函数的第二个输入参数。
2.2 pop函数设计过程
pop函数看上去有一个指向某堆栈的指针作为其输入参数就已经足够了。但仔细想下,它还需要把从堆栈上弹出的数据值返回给它的调用者。
大致得到pop和push函数的原型如下:
void push(element *stack,void*data); //标红的地方有错误,随后解释
void pop(element *stack,void **data);

注:在C语言里,你对传递给子函数作为其输入参数的某个指针所做出的修改时无法反映到其父函数里。要解决这一问题,你就必须把一个指针的指针传递给被调用例程作为参数。
为了对其父函数中的堆栈指针做出修改,必须把一个指向堆栈指针的指针传递给例程push和pop作为输入参数。只有这样,你才能保证父函数中的堆栈指针正确地指向链表的头元素。考虑了这一因素的Push和pop调用模型如下。
void Push(element **stack,void*data);
void Pop(element **stack,void **data);

3 考虑出错处理
push里要为链表中的新元素动态地分配内存。内存分配是一项可能会失败的操作,所以在编写push例程的时候必须要检查这个内存分配操作是否成功。还需要把push操作是否成功通知给它的调用者。采用返回值表示push操作是否成功。
pop要注意,不能对一个空堆栈进行弹出操作。所以它应该设置一个错误代码,当对空堆栈操作时,返回错误代码,那么弹出的数据放哪儿呢?放在输出参数里。
4 创建与删除堆栈
创建堆栈和删除堆栈两个函数原型:
int CreateStack(element**stack);
int DeleteStack(element**stack);
push函数为新元素分配内存,检查内存分配操作是否失败,对新元素进行赋值,把新元素放到堆栈的栈顶,最后对堆栈指针做出调整。如下所示:
[cpp] view plain copy
int push(element **stack, void *data)
{
element *elem;
elem = (element *)malloc(sizeof(element));
if(!elem)
renturn 0;

elem->data = data;
elem->next = *stack;
*stack = elem;

return 1;
}

pop函数先检查堆栈是否为空,然后取回栈顶元素中的数据值,对堆栈指针做出调整,在释放原堆栈元素所占用的内存。如下所示:
[cpp] view plain copy
int pop(element **stack, void **data)
{
element*elem;
if(!(elem= *stack))
return 0;

*data= elem->data;
*stack= elem->next;
free(elem);

return 1;
}

// CreateStack函数将堆栈指针设为NULL,并返回一个表示操作成功的1
[cpp] view plain copy
int CreateStack(element **stack)
{
*stack = NULL;
return 1;
}
DeleteStack函数可以用反复调用pop函数的办法来实现,但一边遍历堆栈数据结构一边是否个链表元素的办法将更有效率。在释放当前元素的时候,你需要使用一个临时指针来保存指向下一个元素的指针。这一点千万不要忘了。
[cpp] view plain copy
int DeleteStack(element **stack)
{
element *next;
while(*stack)
{
next= (*stack)->next;
free(*stack);
*stack= next;
}

return1;
}
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
周大生新世界汇美百货专柜这个地址在什么地方
求解alpha版本的游戏和平常游戏的区别
用字怎么做图片
兔子有苦胆吗
It was he does makes his students enthus
验房发现地面高低差超过2公分怎么办
现在为什么满世界都是骗子。
诚信质量机械标语,尼尔机械纪元怎么嘲讽 嘲讽
爱唯欧为什么算作小型车?
谁有2015年7月六号之前那个手机迅雷版本apk
广君特味酱炖馆在什么地方啊,我要过去处理事
作文 关于达州凤凰山的调查报告
通天炽天使和六翼天使高达怎样
自贴墙纸怎么撕下来,如何把贴在墙上的墙纸撕
想在喜欢的人生日那天表白的情书
推荐资讯
小红家新买了一辆轿车,她看到爸爸往汽车发动
沙洋县新型农村合作医疗管委会办公室我想知道
Food is very important. Everyone needs to
新木乃伊经典语句,北京青年经典台词“几个心
上海世博会部分场馆及摆设物如下图.其中属于
浪琴机械表只要维修就必须换防水圈吗
隋朝的杨坚是北朝时哪个政权的外戚?A.北齐B.
有关牵手的情话,和牵手有关的一句情话,简短
乐昌含笑实生苗和断头苗如何区分
求作文心意 是关于我为爸爸妈妈做得事 的作文
消防不过关处罚金太高不开了 罚金不交会有什
清代桃核可以检测出来吗
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?