小蚂蚁学习数据结构(5)——线性结构——栈的操作演示

左心房为你撑大大i 提交于 2019-12-05 02:34:30

复习之前的内容

链表复习:

    数据结构:

        狭义:

            数据结构是专门研究数据存储的问题。

            数据的存储包含两方面,个体的存储,个体之间关系的存储。

        广义:

            数据结构既包含数据的存储也包含数据的操作

            对存储数据的操作就是算法

算法:

    狭义的算法是与数据的存储方式密切相关

    广义的算法是与数据的存储方式无关

    这就是泛型的思想

    如何实现: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



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!