数据结构
狭义:
数据结构是专门研究数据存储的问题
数据的存储包含两方面:个体的存储+个体关系的存储
广义:
数据结构既包括数据的存储也包括数据的操作
对存储数据的操作就是算法
算法
狭义:
算法是和数据的存储方式密切相关
广义:
算法和数据的存储方式无关
这就是泛型思想
数据的存储方式有几种
线性
连续存储【数组】
优点
存取速度很快
缺点
事先需要知道数组的长度
插入删除元素很慢
空间通常有限制
需要大块连续的内存块
离散存储【链表】
优点
空间没有限制
插入删除元素很快
缺点
存取速度很慢
线性结构的应用–栈
线性结构的应用–队列
对于栈的学习
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
//定义节点
typedef struct Node
{
int data;
struct Node * pNext;
} NODE, * PNODE;
//定义栈
typedef struct Stack
{
PNODE pTop;
PNODE pBottom;
} STACK, * PSTACK;
//声明函数
void init(PSTACK);
void push(PSTACK,int);
bool empty(PSTACK);
void traverse(PSTACK);
bool pop(PSTACK);
void clear(PSTACK);
//主函数
int main(void)
{
STACK S;
int val;
/*测试初始化栈及压栈函数*/
init(&S);
push(&S, 1);
push(&S, 2);
push(&S, 3);
push(&S, 4);
push(&S, 5);
traverse(&S);
/*测试出栈*/
pop(&S);
traverse(&S);
//测试清空栈
clear(&S);
traverse(&S);
}
//栈的初始化 ,形参是指针变量,所以传参的时候,要把数据的地址传进来
void init(PSTACK pS)
{
//注意这里是给栈里的单个节点分配内存,而不是给整个栈
//不要写成 (PSTACK)malloc(sizeof(STACK)) 冒傻气
pS->pTop = (PNODE)malloc(sizeof(NODE));
if(NULL == pS->pTop)
{
printf("n内存分配失败");
exit(-1);
}
else
{
pS->pBottom = pS->pTop;
//由于现在 pS->pBottom = pS->pTop,
//所以写成 pS->pBottom->pNext = NULL 也是可以的
pS->pBottom->pNext = NULL;//pBottom无实际意义,所以他指向的下一个节点是无,要设置为空
}
}
//压栈操作,top 和bottom 都是无实际意义的节点,见最后面的图
void push(PSTACK pS,int val)
{
//给压栈的数据,动态分配一块内存
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(NULL == pNew)
{
printf("n内存分配失败");
exit(-1);
}
pNew->data = val;
/*这里的理解还存在问题
问题的原因是没有理解什么是压栈,方向搞混了
是top顶指针节点,指向bottom底部指针节点
直接pTop=pNew 是因为,pTop 没有意义,可以直接赋值
*/
//下面这个地方稍微有点绕,最好画个图
pNew->pNext = pS->pTop;
pS->pTop = pNew;
}
//这是出栈,脑子干什么去了?
bool pop(PSTACK pS)
{
PNODE pTemp;//防止改变原来的栈,定义一个临时节点
if( empty(pS) )
{
printf("此栈为空");
return false;
}
else
{
pTemp->pNext = pS->pTop->pNext;
//* val = pS->pTop->data;
pS->pTop = pTemp->pNext;
free(pTemp);
pTemp = NULL;
return true;
}
}
//不用判断是否满,因为理论上是无限的
bool empty(PSTACK pS)
{
if(pS->pBottom == pS->pTop)
{
return true;
}
else
{
return false;
}
}
//遍历链表
void traverse(PSTACK pS)
{
PNODE pT;
if(empty(pS))
{
printf("空栈");
}
else
{
PNODE pTemp;
pTemp = pS->pTop;
/*错误写法 ,调试结果出来为空栈
while(pS->pBottom != pS->pTop)
{
printf(" %d", pS->pTop->data);
pS->pTop = pS->pTop->pNext;
}
*/
///*
while(pTemp != pS->pBottom)
{
printf(" %d", pTemp->data);
pTemp = pTemp->pNext;
}
//*/
printf("\n");
}
return;
}
void clear(PSTACK pS)
{
if( empty(pS) )
{
printf("空");
}
else
{
while(pS->pTop != pS->pBottom)
{
PNODE pTemp = pS->pTop;
pS->pTop = pS->pTop->pNext;
free(pTemp);
}
}
}

函数的调用,利用的就是压栈出栈的原理,递归也是
如下图

本文探讨了数据结构的狭义与广义定义,强调了数据存储与操作的重要性。在算法方面,文章阐述了算法与数据存储方式的关系,并提出了泛型思想。接着,文章对比了数组和链表两种线性存储方式的优缺点。最后,文章重点介绍了栈这种线性结构的应用,特别是在函数调用和递归中的作用。

562

被折叠的 条评论
为什么被折叠?



