从小白开始自学数据结构——第四、五天【栈及其基本操作】
2018-01-22 18:37
381 查看
电脑死机了、、、昨天的笔记凉了,今天重新梳理了一次。
数据结构
狭义:
数据结构是专门研究数据存储的问题
数据的存储包含两个方面:个体存储 + 个体关系存储
算法
狭义:
算法是和数据存储方式密切相关
广义:
算法和数据的存储方式无关
这就是泛型的思想
数据存储结构有几种
线性
连续存储【数组】
优点
存取速度很快
空间有限制
缺点
插入删除元素很慢(要移动其他元素)
事先必须知道数组的长度
空间有限,需要一大块连续内存
基本操作实现:
数据结构
狭义:
数据结构是专门研究数据存储的问题
数据的存储包含两个方面:个体存储 + 个体关系存储
广义: 数据结构既包含了数据的存储,也包含了对数据的操作 对存储数据的操作即为算法
算法
狭义:
算法是和数据存储方式密切相关
广义:
算法和数据的存储方式无关
这就是泛型的思想
数据存储结构有几种
线性
连续存储【数组】
优点
存取速度很快
空间有限制
缺点
插入删除元素很慢(要移动其他元素)
事先必须知道数组的长度
空间有限,需要一大块连续内存
离散存储【链表】 优点 空间没有限制 插入删除元素速度很快 存储容量无限制 缺点 存取的速度很慢,需要遍历 线性结构的应用--栈 定义 一种可以实现“先进后出”的存储结构 类似于一个箱子 本质就是一个操作受限制的链表 分类 静态栈 动态栈 基本操作 创建空栈 空判断 压栈 遍历输出 出栈 清空 应用 函数调用 中断 表达式求值 内存分配 缓冲处理 迷宫
基本操作实现:
/******************************* 栈及其基本操作 *******************************/ #include <stdio.h> #include <stdlib.h> #include <malloc.h> struct LinkList { int date; struct LinkList * next; }; struct Stack { struct LinkList * pBottom; struct LinkList * pTop; }; void creat_stack (struct Stack *); //创建空栈 bool is_empty (struct Stack *); //空判断 void push_stack (struct Stack * ,int ); //压栈 void traverse_stack (struct Stack *); //遍历输出 bool pop_stack (struct Stack * ,int *); //这个有返回值是因为出栈可能失败,即栈为空的时候 void clear_stack (struct Stack *); //清空 int main () { int val; struct Stack S; creat_stack (&S); push_stack(&S, 99999); push_stack(&S, 1); push_stack(&S, 3); push_stack(&S, 1); push_stack(&S, -56); traverse_stack(&S);//输出是倒过来的,因为第一个元素被压到最下面了,从上面出栈,就是倒过来的 pop_stack(&S, &val); traverse_stack(&S); printf ("出栈的元素是%d\n", val); clear_stack (&S); pop_stack(&S, &val); 4000 traverse_stack(&S); return 0; } void creat_stack (struct Stack * p) { /*创建空链表 判断链表创建是否成功 头结点数据域为空 底指向头结点 头指向头结点*/ struct LinkList * pHead = (struct LinkList *)malloc(sizeof(struct LinkList)); if (!pHead) { printf ("创建失败\n"); exit(1); } pHead->date = NULL; pHead->next = NULL; p->pTop = pHead; p->pBottom = pHead; return; } bool is_empty (struct Stack * p) { if (p->pTop == p->pBottom ) { return true; } else return false; } void push_stack (struct Stack * p, int val) { /*创建一个新的结点 判断新结点是否创建成功 新结点指向原来结点 将pTop指向新结点*/ struct LinkList * pNew = (struct LinkList *)malloc(sizeof(struct LinkList)); if (!pNew) { printf ("创建失败\n"); exit(1); } pNew->date = val; pNew->next = NULL; pNew->next=p->pTop; //p->pTop ->next = pNew;是把原来那个结点当做了尾,然后新建一个指向尾 p->pTop = pNew; return; } void traverse_stack (struct Stack * p) { if ( is_empty(p) ==true ) { printf ("空栈\n"); return; } int i=0; struct LinkList * q; q = p->pTop; while (q->next) { i++; printf ("栈中第%d个元素为:%d \n", i,q->date); q = q->next; } return; } bool pop_stack (struct Stack * p,int * val) { /*判断栈是否为空 不为空则把栈顶的值返回给val 释放其空间 返回true */ struct LinkList * q=p->pTop ; //struct Stack * q; if ( is_empty(p) == true) { printf ("空栈\n"); return false; } *val = q->date; // *val = p->pTop->date; //q = p; p->pTop = q->next; //p->pTop = p->pTop ->next ; free (q); //free(q->pTop); 注释的这一块是错误的,因为p->pTop是一个结点,struct Stack * q是一个栈 return true; } //感觉这个就是彻头彻尾的一个不能插入不能删除中间的链表,栈顶就是头指针指向首结点,栈底就是一个指向尾结点的指针 void clear_stack (struct Stack * p) { struct LinkList * r; struct LinkList * q=p->pTop; if ( is_empty(p) == 1) { printf ("本来就是空的\n"); return; } else while (q != p->pBottom ) { r = q->next; free (q); q=r; } p->pTop =p->pBottom ; return; }
相关文章推荐
- 从c小白开始自学数据结构——第三天【链表的基本操作】
- 从小白开始自学数据结构——第十二天【图及其基本概念和邻接表的定义】
- 从小白开始自学数据结构——第九天【树的基本概念和定义】
- 从c小白开始自学数据结构——第一天【数组及其简单算法】
- Java数据结构与算法之数据结构-逻辑结构-线性结构(9)------Java线性结构概念及其基本操作
- 数据结构:实验四栈和队列的基本操作实现及其应用
- [数据结构] 二叉树的建立及其基本操作
- 从小白开始自学数据结构——树的遍历
- 数据结构类型定义及基本操作汇总(二)-- 二叉树及其遍历
- [数据结构]堆的基本概念及其操作
- 数据结构 线性链表的创立及其基本操作初始化、遍历、销毁、判空、求表长、删除、插入等
- 基本数据结构——堆(Heap)的基本概念及其操作
- 从小白开始自学数据结构——第六天【队列】
- 从小白开始自学数据结构——第八天【串】
- 数据结构――堆的基本概念及其操作
- 从小白开始自学数据结构——第十三天【简单选择排序】
- 从c小白开始自学数据结构——第二天【链表开始】
- 从小白开始自学数据结构——第十一天【线索二叉树】
- 实验一线性表的基本操作实现及其应用
- 数据结构实验一线性表的基本操作实现及其应用