顺序表的表头插入和删除时间复杂度为O(n)
表尾插入删除的时间复杂度为O(1)
栈:仅限制在表尾进行插入和删除线性表
表尾称为栈顶,另一端称为栈底
通过顺序表来实现
ps ->top 下标
顺序栈
#pragma once
#define INIT_SIZE 10
typedef int ElemType;
//顺序栈 代码实现和顺序表很像
typedef struct Stack
{
ElemType* base; //栈的底部 // 用来承接malloc申请的空间
int top; //栈顶指针,1.有效数据的个数,2.下一个插入位置的下标
int stacksize; //栈的大小,保存当前栈总共有多少空间
}Stack,*PStack;
//初始化
void Init_Stack(PStack ps);
//入栈、压栈push
bool Push(PStack ps,ElemType val); //rtval是一个输出参数(C语言讲到),当想从函数中多带数据出来,使用它)
//出栈,弹栈pop(获取顶部元素并删除)使用pop可以多带几个数据出来,而return一次只能带出来一个数据
bool pop(PStack ps, ElemType* rtval);
//获取栈顶元素top
bool Top(PStack ps, ElemType* rtval);
//获取有效数据个数
int GetLength(PStack ps);
//判空,盘满
bool Isempty(PStack ps);
bool IsFull(PStack ps);
//扩容
static void Inc(PStack ps);
//清空 房子有人,把人清空
void Clear(PStack ps);
//销毁 人清空,房子也烧了
void Destory(PStack ps);
//打印
void Show(PStack ps);
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include "mystack.h"
//初始化
void Init_Stack(PStack ps)
{
assert(ps != nullptr);
if (nullptr == ps) return;
//成员初始化
ps->base = (ElemType*)malloc(sizeof(ElemType)*INIT_SIZE);
ps->stacksize = INIT_SIZE;
ps->top = 0;
}
//入栈、压栈push
bool Push(PStack ps,ElemType val) //rtval是一个输出参数(C语言讲到),当想从函数中多带数据出来,使用它)
{
assert(ps != nullptr);
//判断栈是否满了
//满了扩容,未满插入
if (IsFull(ps))
{
Inc(ps);
}
ps->base[ps->top] = val;
//ps->base[ps->top++] = val;
ps->top ++;
return true;
}
//出栈,弹栈pop(获取顶部元素并删除)使用pop可以多带几个数据出来,而return一次只能带出来一个数据
bool pop(PStack ps, ElemType* rtval)
{
assert(ps != nullptr);
if (Isempty(ps)) //判断是否为空
{
return false;
}
*rtval = ps->base[--ps->top];
return true;
}
//获取栈顶元素top
bool Top(PStack ps, ElemType* rtval)
{
assert(ps != nullptr);
if (Isempty(ps)) //判断是否为空
{
return false;
}
*rtval = ps->base[ps->top-1];
return true;
}
//获取有效数据个数
int GetLength(PStack ps)
{
assert(ps != nullptr);
return ps->top;
}
//判空,盘满
bool Isempty(PStack ps)
{
//assert
return ps->top == 0;
}
bool IsFull(PStack ps)
{
return ps->top == ps->stacksize;//有效元素的个数如果等于空间的总个数,则已满
}
//扩容
static void Inc(PStack ps)
{
ps->base = (ElemType*)realloc(ps->base, sizeof(ElemType) * ps->stacksize * 2);//扩容当前空间总个数的2倍
assert(ps->base != nullptr);
ps->stacksize *= 2;//总大小*2;
}
//清空 房子有人,把人清空
void Clear(PStack ps)
{
//assert
ps->top = 0;
}
//销毁 人清空,房子也烧了
void Destory(PStack ps)
{
Clear(ps);
free(ps->base);
ps->base = nullptr;
}
//打印函数
void Show(PStack ps)
{
//assert
for (int i = 0; i < ps->top; i++)
{
printf("%d ", ps->base[i]);
}
printf("\n");
}
链栈
#include<limits.h>
#include<assert.h>
typedef int ELEMTYPE;
typedef struct LStack
{
ELEMTYPE data;
struct LStack* next;
}LStack,*PLStack;
#include "lstack.h"
void Init_Stack(PLStack ps)
{
//assert
ps->next = nullptr;
}
//入栈/压栈
bool push(PLStack ps, ELEMTYPE val)
{
//assert
LStack* s = (LStack*)malloc(sizeof(LStack));
//assert
s->data = val;
s->next = ps->next;
ps->next = s;
return true;
}
//出栈、弹栈
bool pop(PLStack ps, ELEMTYPE* rtval)
{
assert(ps != nullptr );
if (IsEmpty(ps))
{
return false;
}
*rtval = ps->next->data;
LStack* p = ps->next;
ps->next = p->next;
free(p);
p = nullptr;
return true;
}
//获取顶部元素
bool top(PLStack ps, ELEMTYPE* rtval)
{
//assert
if (IsEmpty(ps))
{
return false;
}
*rtval = ps->next->data;
return true;
}
//获取数据个数
int GetLength(PLStack ps)
{
LStack* p = ps->next;
int length = 0;
for (; p != nullptr; p = p->next)
{
++length;
}
return length;
}
//判空
bool IsEmpty(PLStack ps)
{
return ps->next == nullptr;
}
//不需要判满
//不需要扩容
//清空
void clear(PLStack ps)
{
destory(ps);
}
//摧毁
void destory(PLStack ps)
{
while (ps->next != nullptr)
{
LStack* p = ps->next;
ps->next = p->next;
free(p);
p = nullptr;
}
}
//打印
void show(PLStack ps)
{
LStack* p = ps->next;
for (; p != nullptr; p = p->next)
{
printf("%d ", p->data);
}
printf("\n");
}
- 测试
int main()
{
LStack ls;
Init_Stack(&ls);
for (int i = 0; i < 10; i++)
{
push(&ls, i);
}
show(&ls);
int tmp;//接收 rtval的值
top(&ls, &tmp);
printf("%d", tmp);
int tmp2;
pop(&ls, &tmp2); //删掉的数据位19
printf("%d\n", tmp2);
show(&ls);
printf("length =%d\n", GetLength(&ls));
clear(&ls);
printf("length =%d\n", GetLength(&ls));
destory(&ls);
return 0;
}