复习之前的内容
链表复习:
数据结构:
狭义:
数据结构是专门研究数据存储的问题。
数据的存储包含两方面,个体的存储,个体之间关系的存储。
广义:
数据结构既包含数据的存储也包含数据的操作
对存储数据的操作就是算法
算法:
狭义的算法是与数据的存储方式密切相关
广义的算法是与数据的存储方式无关
这就是泛型的思想
如何实现:1,通过模板;2,运算符的重载;3,通过指针 //这里需要去学习c++,不然很难理解
泛型:
利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的
数据的存储结构有几种
1,线性
连续存储(数组)
优点:存取的速度很快
缺点:插入删除元素就很慢了
实现必须知道数组的长度
插入删除元素很慢
空间通常是有限制的
需要大块连续的内存块
离散存储(链表)
优点:空间没有限制,只要内存够用
插入删除元素的速度很快,无需移动其他元素
缺点:存取速度慢
线性结构的应用 1 栈 2,队列
2,非线性
树
图
到了今天的主题,栈的操作,跟链表还是非常相似的,只是栈将链表的有些功能给限制了。
/*
栈的操作
*/
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
//节点结构体
typedef struct Node
{
int data;
struct Node * pNext;
}NODE,*PNODE;
//栈结构体
typedef struct Stack
{
PNODE pTop;
PNODE pBottom;
}STACT,*PSTACT;
//函数前置声明
void init(PSTACT); //创建一个栈
void push(PSTACT, int); //向栈中压入一个元素
void traverse(PSTACT); //遍历这个栈
bool pop(PSTACT,int *); //从栈中弹出一个元素
bool clear(PSTACT); //清空这个栈
int main(void)
{
int val; //保存弹出的数据
//创建一个栈
STACT S;
//初始化这个栈
init(&S);
//推入一个元素
printf("压入一个元素1\n");
push(&S,1);
printf("压入一个元素2\n");
push(&S,2);
printf("压入一个元素3\n");
push(&S,3);
printf("压入一个元素4\n");
push(&S,4);
printf("遍历这个栈:");
traverse(&S);
printf("弹出一个元素:");
pop(&S, &val);
traverse(&S);
printf("再弹出一个元素:");
pop(&S, &val);
traverse(&S);
printf("将整个栈清空之后\n");
clear(&S);
printf("遍历这个栈:");
traverse(&S);
return 0;
}
/*
初始化这个栈
@param PSTACT pst 栈的指针
return void
*/
void init(PSTACT pst)
{
PNODE p = (PNODE)malloc(sizeof(NODE));
if( NULL == p )
{
printf("动态内存常见失败\n");
exit(-1);
}
pst->pBottom = p;
pst->pTop = pst->pBottom;
p->pNext = NULL;
return;
}
/*
往栈中推入一个元素
@param PSTACT pst 栈的指针
@param int val 要推入元素的值
return void
*/
void push(PSTACT pst,int val)
{
PNODE p = (PNODE)malloc(sizeof(NODE));
if( NULL == p )
{
printf("动态内存常见失败\n");
exit(-1);
}
p -> data = val;
p -> pNext = pst -> pTop;
pst -> pTop = p;
return;
}
/*
判断栈是否为空
@param PSTACT pst 栈的指针
return Boolean
*/
bool is_empty(PSTACT pst)
{
if( pst->pBottom == pst->pTop )
{
return true;
}
else
{
return false;
}
}
/*
遍历这个栈
@param PSTACT pst 栈的指针
return void
*/
void traverse(PSTACT pst)
{
if( is_empty(pst) )
{
printf("栈为空!\n");
exit(-1);
}
PNODE p = pst -> pTop;
while( p != pst -> pBottom )
{
printf("%d ",p -> data);
p = p -> pNext;
}
printf("\n");
return;
}
/*
从栈中弹出一个元素
@param PSTACT pst 栈的指针
@param int * val 弹出元素的值
return Boolean
*/
bool pop(PSTACT pst , int * val)
{
if( is_empty(pst) )
{
printf("栈为空!\n");
return false;
}
PNODE p = pst -> pTop;
*val = p -> data;
pst -> pTop = p -> pNext;
free(p);
p = NULL;
return true;
}
/*
清空这个栈
@param PSTACT pst 栈的指针
return Boolean
*/
bool clear(PSTACT pst)
{
PNODE q;
if( is_empty(pst) )
{
printf("栈为空\n");
return false;
}
while(pst -> pTop != pst -> pBottom)
{
q = pst -> pTop -> pNext;
free(pst -> pTop);
pst -> pTop = q;
}
return true;
}
/*
VC++6.0 输出的结果是:
======================================
压入一个元素1
压入一个元素2
压入一个元素3
压入一个元素4
遍历这个栈:4 3 2 1
弹出一个元素:3 2 1
再弹出一个元素:2 1
将整个栈清空之后
遍历这个栈:栈为空!
======================================
总结:
栈也就是一个链表,“先进后出”不能从中间插入或删除
链表可以从头指针找到链表的头部
栈使用栈顶指针对链表进行操作
*/
学PHP的小蚂蚁 博客 http://my.oschina.net/woshixiaomayi/blog
来源:oschina
链接:https://my.oschina.net/u/1423209/blog/596354