目录
【1】栈 Stack
1》栈的定义
2》顺序栈
2》链式栈
4》顺序栈的链式栈的区别
【1】栈 Stack
1》栈的定义
栈:是只允许在一端进行插入或删除的线性表,首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。
栈顶:线性表允许进行插入删除的一端
栈底:固定的,不允许进行插入和删除的另一端
空栈:不含任何元素的空表
栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
2》顺序栈
特性
逻辑结构:线性结构
存储结构:顺序结构
操作:创空栈、入栈、出栈、判空和判满
创空:
入栈:
出栈:
代码展示:
#include <stdio.h>
#include <stdlib.h>typedef int data_t;//重定义整型
typedef struct stack//重定义栈节点结构体类型
{int maxlen;//栈的最大长度,表示数组元素个数data_t *data;//用来指向存放数据的指针相当于数组int top;//定义一个变量表示栈顶的下标
} stack_t;/*创空栈*/
stack_t *Create(int len)//len表示创建栈时的最大元素长度
{stack_t *s = (stack_t *)malloc(sizeof(stack_t));//开辟顺序栈结构体的堆区空间if (NULL == s)//容错判断{perror("malloc lost\n");return NULL;}s->data = (data_t *)malloc(sizeof(data_t) * len);//开辟一个堆区空间,让data指针指向该空间,用于存放数据,相当于数组if (NULL == s->data)//容错判断{perror("malloc lost\n");}//初始化结构体s->maxlen = len;//最大元素个数初始化为建栈的长度s->top = -1;//初始化栈顶下标为-1return s;//返回创建的栈的结构体指针
}/*判满*/
int Full(stack_t *p)
{return p->top + 1 == p->maxlen;//当栈顶元素的下标加一就是数据元素个数 等于最大元素个数时,栈满
}/*入栈*/
void Push(stack_t *p, int data)//栈的地址和要入栈的数据
{if (Full(p))//先判满,容错判断{perror("In error\n");}p->top++;//下标先加一,因为初始化时下标为-1,需要将下标加到0下标处,开始入栈,后面也是每进一个数据,栈顶下标都加一p->data[p->top] = data;//往加一后的下标位置插入数据
}/*判空*/
int Empty(stack_t *p)
{return p->top == -1;//当栈顶下标的值为-1时说明栈内没有数据,和创空栈时一样
}/*出栈*/
int Pop(stack_t *p,int top)
{if (Empty(p))//判空,容错判断{perror("Out error\n");}for(int i = top;i >= 0;i--)//for循环,从栈顶开始向下循环,依次打印栈内数据{printf("%d ",p->data[i]);}printf("\n");
}int main(int argc, char const *argv[])
{stack_t *S = Create(5);//开辟空顺序栈Push(S, 5);//调用入栈函数Push(S, 4);Push(S, 3);Push(S, 2);Push(S, 1);printf("出栈: ");Pop(S, S->top);//调用出栈函数, 出栈先进后出 1 2 3 4 5return 0;
}
运行结果:
2》链式栈
逻辑结构:线性结构
存储结构:链式存储
顺序栈和链式栈的区别:存储结构不同,实现的方式也不同,顺序栈是用顺序表实现而链式栈是用链表实现。
栈的操作:创空栈、入栈、出栈、判空
入栈:
出栈:
代码展示:
#include <stdio.h>
#include <stdlib.h>typedef int data_t;
typedef struct node
{data_t data;struct node *next;
} Node_t, *Node_p;/*创建一个空栈*/
void Create(Node_p *p) // Node_p 相当于Node_t *,所以 Node_p *p 相当于定义一个二级指针,接受一级指针的地址 p = &top
{*p = NULL; //*p = top = NULL;
}/*入栈*/
void Push(Node_p *p, int data)
{Node_p p_new = (Node_p)malloc(sizeof(Node_t)); // 开辟一个新的要入栈的节点if (NULL == p_new){perror("malloc lost\n");}p_new->data = data; // 新节点初始化p_new->next = *p;//让新节点连接到top栈顶上*p = p_new;//让top栈顶移动到新节点处,让新节点成为栈顶
}
/*判空*/
int Empty(Node_p p)
{return p == NULL;//当栈顶为空的时候,就是创空栈的时候
}/*出栈*/
void Pop(Node_p *p)
{if (Empty(*p))//判空,容错判断{perror("Empty\n");}while (*p != NULL)//当栈顶不是空,就进入循环{printf("%d ", (*p)->data);//先出栈顶的元素Node_p p_del = *p;//定义一个p_del指针指向栈顶*p = (*p)->next;//让栈顶向下移动,指向下一个节点free(p_del);//释放之前的栈顶节点p_del = NULL;//将p_del指针置空}printf("\n");
}/*栈的长度*/
int Length(Node_p p)
{int len = 0;//定义一个变量保存栈的长度while (p != NULL)//当栈顶元素不为空就进入循环{len++;//让栈的长度加一p = p->next;//栈顶指针向下移动,指向下一个节点}return len;//返回栈的长度
}int main(int argc, char const *argv[])
{Node_p top;//定义一个栈结构体类型的指针Create(&top); // top = NULL,创空栈,此时栈里只有一个控制真for (int i = 0; i < 5; i++)//循环调用入栈函数Push(&top, i);printf("栈的长度:%d\n", Length(top));//打印栈的长度printf("出栈: ");Pop(&top);//调用出栈函数,先入后出return 0;
}
运行结果:
4》顺序栈的链式栈的区别
1> 顺序栈是顺序存储,内存连续,用顺序表实现;链表是链式存储,内存不连续,用链表实现。
2> 顺序栈的长度固定,而链栈不会。
今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话请给个三连支持一下吧!