//复杂的栈--链表栈
#include<stdio.h>
#include<stdlib.h> #define datatype int//定义链表栈数据类型
//定义链表栈结构
struct stacklink{
datatype data;
struct stacklink *pnext;
}; typedef struct stacklink 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); //链表栈容量无限大,但是代价是增加链表遍历成本 void main(){
//定义链表栈的头指针
StackLink * phead = NULL;
//压栈
phead = push(phead, );
phead = push(phead, );
phead = push(phead, );
phead = push(phead, );
phead = push(phead, );
//打印栈中的数据
findall(phead);
//出栈
StackLink *pout = (StackLink *)malloc(sizeof(StackLink));
phead = pop(phead, pout);
printf("\n弹出的元素是%d;\n", pout->data);
free(pout);
////全部出栈
//while (phead!=NULL){
// StackLink *pout = malloc(sizeof(StackLink));
// phead = pop(phead, pout);
// printf("\n弹出的元素是%d;\n", pout->data);
// free(pout);
//}
printf("\n================================\n");
//打印栈中的数据
findall(phead);
printf("\n================================\n");
//清空栈内元素
phead = setempty(phead);
//打印栈中的数据
findall(phead);
system("pause");
} //判断栈是否为空
int isempty(StackLink *phead){
if (phead == NULL)
{
return ;
}
else{
return ;
}
} //进栈
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本身
}
return phead;
} //遍历栈中的数据
void findall(StackLink *phead){
StackLink *p = phead;
while (p != NULL){
printf("%d\n", p->data);
p = p->pnext;
}
} //出栈
StackLink * pop(StackLink *phead, StackLink *pout){
if (phead == NULL)//判断栈是否为空
{
return NULL;
}
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的值
return phead;
}
//2.多个元素,找到倒数第二个元素
else{
StackLink *p = phead;
while (phead->pnext->pnext != NULL){
phead = phead->pnext;
}
pout->data = phead->pnext->data;
//删除栈中最后一个元素
free(phead->pnext);
phead->pnext = NULL;
return p;
} }
} //清空
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);
return NULL;
}

C语言 复杂的栈(链表栈)的更多相关文章

  1. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

  2. c语言编程之栈(链表实现)

    用链表实现栈,完成了出栈入栈功能. #include"stdio.h" typedef int element; //define a struct descirbe a stac ...

  3. C语言中的堆与栈20160604

    首先声明这里说的是C语言中的堆与栈,并不是数据结构中的!一.前言介绍:C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件是静态区域由代码段和数据段(由二部分部分组成:只读数据 段,未初始化数 ...

  4. C语言实现顺序栈以及栈的特点

    什么是栈? 同顺序表和链表一样,栈也是用来存储逻辑关系为 "一对一" 数据的线性存储结构,如下图所示. 从上图我们看到,栈存储结构与之前所学的线性存储结构有所差异,这缘于栈对数据 ...

  5. C语言学习笔记——堆和栈——未整理

    C语言笔记     栈区     栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出.出入栈是由C语言编译器自动分配 ...

  6. 【转】C语言堆栈入门——堆和栈的区别

    @2019-04-25 [小记] C语言堆栈入门——堆和栈的区别

  7. C语言实现链栈的初始化&进栈&出栈&读取栈顶元素

    /*链表实现栈的一系列操作*/ #include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 typede ...

  8. C语言数据结构基础学习笔记——栈和队列

    之前我们学过了普通的线性表,接下来我们来了解一下两种特殊的线性表——栈和队列. 栈是只允许在一端进行插入或删除的线性表. 栈的顺序存储结构也叫作顺序栈,对于栈顶指针top,当栈为空栈时,top=-1: ...

  9. java——链表、链表栈 LinkedListStack、链表队列 LinkedListQueue

    LikedList: package Date_pacage; public class LinkedList<E> { public static void main(String[] ...

随机推荐

  1. 浅谈DES加密算法

    一.DES加密算法介绍 1.要求密钥必须是8个字节,即64bit长度 2.因为密钥是byte[8] , 代表字符串也可以是非可见的字节,可以与Base64编码算法一起使用 3.加密.解密都需要通过字节 ...

  2. IOS杂笔- 7(类方法load与initialize的区别 浅析)

    在介绍两种类方法之前,NSObject Class Reference里对这两个方法说明: +(void)initialize The runtime sends initialize to each ...

  3. iOS 自定义进度条

    自定义条形进度条(iOS) ViewController.m文件 #import "ViewController.h" @interface ViewController () @ ...

  4. 数据库性能调优——sql语句优化(转载及整理) —— 篇2

    下面是在网上搜集的一些个人认为比较正确的调优方案,如有错误望指出,定虚心改正 (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE 的解析器按照从右到左的顺序处理FROM子句中 ...

  5. C# Ftp文件处理

    1.创建文件夹 /// <summary> /// ftp创建文件夹(只能创建单层目录) /// </summary> /// <param name="Uri ...

  6. jQuery最佳实践(不断更新中...)

    1. 处理cdn失效 <script type="text/javascript" src="http://xxx.com/jquery.min.js " ...

  7. 新手在sae部署程序容易忽略的一个细节

    从来没用过这类云空间服务,尝了下鲜试用一下sae,但是部署的时候发现问题了,各种404..各种无奈啊..虽然百度无数篇介绍,但是都千篇一律没什么启发.. 但是巧在我部署的应用有个欢迎页面,点击链接的时 ...

  8. CentOS 6.5部署安装Memcached

    1. Yum安装Memcache 查找memcached yum  search  memcached 该命令可以查询yum库中有关memcached的安装包信息,以下是搜寻结果截图: 安装 memc ...

  9. 【C#】1.算法温故而知新 - 简单的桶排序

    该算法的时间复杂度是O(M+N),M为桶的个数,N为待排序的个数 缺点: 1.不适用于小数 2.当数值过多,太浪费空间,比如数值范围为0~99999,那需申请100000个变量,也就是要写成a[100 ...

  10. 移动web页面使用的字体的思考

    前言 记得做PC端页面的时候,字体一般设置为微软雅黑,现在做起移动端页面来了,设计师们一般都还把字体设置为微软雅黑字体,但是做出来后,测试的时候发现页面中的字体不是微软雅黑,怎么办? 后来了解到的手机 ...