栈
栈:栈是限定仅在 “表尾” 进行插入和删除操作的“线性表"。表尾端被称为栈顶 另一端被称为栈底。没有数据称为空栈
因为在线性表的表尾不用挪动数据,时间复杂度低为O(1)。
如果是“链表”只能在“表头”,因为链表表头的时间复杂度为O(1)。
栈:弹夹;先压入的子弹凡反而最后被击发。先进后出 或 后进先出 的数据结构。
队列:
队列:"先进先出” 的数据结构,仅在一端进行插入操作 在另一端进行删除操作的线性表(受到限制的线性表)没有数据称为空队列。
分别用顺序表和链表实现一下。
队列:排队 前面的先被服务 后面的后被服务。
既可以在头部插入 尾部插入 也可以头部删除 尾部删除
#include <stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef INIT_SIZE
typedef struct Stack
{
ELEM_TYPE *base;//数据域 用来保存malloc申请的空间
int top;//栈顶指针,1.既可以表示有效数据2.指向下一个数据插入的下标。
int stacksize;//用来保存当前satack总共多少空间(扩容就在这)
}Stack,*PStack;
//顺序栈的操作:增删该查
//初始化
void Init_stack(PStack,ps)
{
//断言
assert(ps!=NULL);
if(NULL == ps)
{
return;
}
//将成员初始化
ps->base=malloc(sizeof(ELEM_TYPE)*INIT_SIZE);
ps->stacksize=INIT_SIZE;
ps->top=0;
}
//入栈 或者 压栈 push
bool Push(PStack ps,ELEM_TYPE*val)
{
//断言
assert(ps!=NULL);
if(NULL == ps)
{
return;
}
//判断栈满了没
if(IsFull(ps))
{
Inc(ps);
}
//如果满了 扩容
//如果没满 插入
ps->base[ps->top]=val;
ps->top++;
return true;
}
//出栈 或者 弹栈 pop(获取顶部数据,并且删除)
bool Pop(PStack ps,ELEM_TYPE*rtval)
{
//assert
assert(ps!=NULL)
//判断栈是否为空
if(IsEmpty(ps))
{
return false;
}
//出栈 1.获取值2.再出栈
*rtval=ps->base[ps->top-1];
ps->top--;
return true;
}
//获取顶部元素值top(获取顶部数据)
bool Top(PStack ps,ELEM_TYPE*rtval)
{
assert(ps!=NULL)
//判断栈是否为空
if(IsEmpty(ps))
{
return false;
}
*rtval=ps->base[ps->top-1];//获取top的值
return true;
}
//获取其有效数据个数
int Get_length(Pstack ps)
{
//assert
return ps->top ;
}
//判空
int IsEmpety(Pstack ps)
//判满
int IsFull(Pstack ps)
{
return ps->top == ps->stacksize;//等于总的空间个数则满
}
//扩容
static void Inc(PStack ps)
{
ps->base=(ELEM_TYPT*)realloc(ps->base,sizeof(ELE_TYPE)*ps->stacksize*2);
assert(ps-data!=NULL);
ps->stacksize *=2;
}
//清空
void Clear(PStack ps)
{
ps->top=0;
}
//销毁
void Destroy(PStack ps)
{
ps->top=0
free(ps->base);
ps->base=NULL;
}
队列的编写 .cpp 模仿单链表
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "Lstack.h"
//作业:补全代码
//初始化
void Init_stack(PLStack ps)
{
ps->next = NULL;//数据域不使用所以不用初始化;
}
//入栈(或者叫压栈 push) 头插 时间复杂度为O(1)
bool Push(PLStack ps, ELEM_TYPE val)//链栈不用判满
{
assert(ps != nullptr);
LStack* pnewnode = (LStack*)malloc(sizeof(LStack*) * 1);//1.申请新节点
assert(pnewnode != nullptr);//新节点不为空则创建成功
pnewnode->data = val;
pnewnode->next = ps->next;//2.头插(两行代码)
ps->next = pnewnode;
return true;
}
//出栈 尾删(或者叫弹栈 pop(获取顶部数据,并且删除))//rtval是一个输出参数(C语言讲到)
bool Pop(PLStack ps, ELEM_TYPE* rtval)
{
assert(ps != nullptr);
LStack* p = ps;
for (p; p->next->next != NULL; p = p->next);
*rtval = p->next->data;
LStack* q = p->next;
p->next = q->next;
//free(q);
q = nullptr;
return true;
}
//出栈 头删时(或者叫弹栈 pop(获取顶部数据,并且删除))//rtval是一个输出参数(C语言讲到)
bool Pop(PLStack ps,ELEM_TYPE*rtval)
{
//assert
if(IsEmpty(ps))
return false;//不为空则至少有一个节点
*rtval = ps->next->data;
LStack*p = ps->next;
ps->next=p->next;
free(p);
p=NULL;
return true;
}
//获取顶部元素值 top(获取顶部数据)
bool Top(PLStack ps, ELEM_TYPE* rtval)
{
assert(ps != nullptr);
LStack* p = ps;
for (p; p->next != nullptr; p = p->next);//让p跑完指向最后一个节点
*rtval = p->data;
return true;
}
//获取其有效数据个数
int Get_length(PLStack ps)
{
assert(ps != nullptr);
int count = 0;
for (LStack* p = ps; p->next != nullptr; p = p->next)//遍历
{
count++;
}
return count;
}
//清空 一间房住了一户人 清空相当于把人赶出去
void Clear(PLStack ps)
{
Destroy(ps);
}
//销毁 一间房住了一户人 销毁相当于把人赶出去还把房烧了
void Destroy(PLStack ps)//一指头删
{
assert(ps != nullptr);
while (ps->next != nullptr)
{
LStack* p = ps->next;
ps->next = p->next;
//free(p);
}
ps->next = nullptr;
}
//打印
void Show(PLStack ps)
{
assert(ps != nullptr);
for (LStack* p = ps->next; p != nullptr; p = p->next)
{
printf("%d ", p->data);
}
printf("\n");
}