您的位置:首页 > 理论基础 > 数据结构算法

从小白开始自学数据结构——第四、五天【栈及其基本操作】

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: