电脑死机了、、、昨天的笔记凉了,今天重新梳理了一次。
数据结构
狭义:
数据结构是专门研究数据存储的问题
数据的存储包含两个方面:个体存储 + 个体关系存储
广义:
数据结构既包含了数据的存储,也包含了对数据的操作
对存储数据的操作即为算法
算法
狭义:
算法是和数据存储方式密切相关
广义:
算法和数据的存储方式无关
这就是泛型的思想
数据存储结构有几种
线性
连续存储【数组】
优点
存取速度很快
空间有限制
缺点
插入删除元素很慢(要移动其他元素)
事先必须知道数组的长度
空间有限,需要一大块连续内存
离散存储【链表】
优点
空间没有限制
插入删除元素速度很快
存储容量无限制
缺点
存取的速度很慢,需要遍历
线性结构的应用--栈
定义
一种可以实现“先进后出”的存储结构
类似于一个箱子
本质就是一个操作受限制的链表
分类
静态栈
动态栈
基本操作
创建空栈
空判断
压栈
遍历输出
出栈
清空
应用
函数调用
中断
表达式求值
内存分配
缓冲处理
迷宫
基本操作实现:
/*******************************
栈及其基本操作
*******************************/
#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);
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;
}