一、栈
1.栈的定义
二、顺序栈
1.顺序栈的定义
注意:书上关于顺序栈top是指针类型,但是我们这里使用 int 类型,但含义都是一样的
2.顺序栈代码实现
.h头文件声明
#pragma once
typedef int ELEM_TYPE;
typedef struct Stack {
ELEM_TYPE* base;//存储空间基址(用来接收malloc返回在堆上申请的连续空间块的起始地址)
int top;//当前有效长度,且可以表示下一个待插入位置的下标
int stacksize;//当前总空间大小(以格子数为单位)
}Stack, *Pstack;
//初始化
void Init_stack(struct Stack *st);
//入栈
bool Push(struct Stack* st,ELEM_TYPE val);
//出栈
bool Pop(struct Stack* st);
//获取栈顶元素值
ELEM_TYPE Top(struct Stack* st);
//判空
bool Is_full(struct Stack* st);
//判满
bool Is_empty(struct Stack* st);
//扩容*2
void Inc(struct Stack* st);
//搜索
int Search(struct Stack* st, ELEM_TYPE val);
//清空
void Clear(struct Stack* st);
//销毁
void Destory(struct Stack* st);
//打印
void Show(struct Stack* st);
//获取有效值个数
int Get_length(struct Stack* st);
.cpp功能实现代码
#include<stdio.h>
#include<stdlib.h>
#include"Stack.h"
#include <cassert>
#define STACK_INIT_SIZE 100
//初始化
void Init_stack(struct Stack* st) {
assert(st != NULL);
st->base = (ELEM_TYPE*)malloc(STACK_INIT_SIZE * sizeof(ELEM_TYPE));
assert(st->base != NULL);
st->top = 0; //即代表下一个合适的插入位置下标为0,也代表当前有效位置为0
st->stacksize = STACK_INIT_SIZE;
}
//入栈(队尾插入)
bool Push(struct Stack* st, ELEM_TYPE val) {
//0.安全性处理
assert(st!=NULL);//保证顺序表的头结点存在
//1.如果站还有空间,则将之val插入到top指向的格子里面
if (Is_full(st)) {
Inc(st);
}
st->base[st->top] = val;
st->top++;
return true;
}
//出栈(队尾删除)
bool Pop(struct Stack* st) {
assert(st != NULL);
if (Is_empty(st)) {
return false;
}
st->top--;
return true;
}
//获取栈顶元素值
ELEM_TYPE Top(struct Stack* st) {
assert(st != NULL);
if (Is_empty(st)) {
return NULL;
}
ELEM_TYPE val = st->base[st->top-1];
return val;
}
//判空
bool Is_full(struct Stack* st) {
assert(st != NULL);
if (st->top == 0) {
return true;
}
return false;
}
//判满
bool Is_empty(struct Stack* st) {
assert(st != NULL);
//当前有效格子数等于当前总格子数,则满
if (st->top == st->stacksize) {
return true;
}
return false;
}
//扩容*2
void Inc(struct Stack* st) {
assert(st != NULL);
ELEM_TYPE *tmp = (ELEM_TYPE*)realloc(st->base,2 * STACK_INIT_SIZE * sizeof(ELEM_TYPE));
if (tmp == NULL) {
printf("error\n");
return;
}
st->base=tmp;
assert(st->base != NULL);
//扩容成功,有效长度不变,总长度变为两倍
st->stacksize= 2 * STACK_INIT_SIZE;
}
//搜索
int Search(struct Stack* st, ELEM_TYPE val) {
assert(st != NULL);
for (int i = 0; i <st->top; i++) {
if (val == st->base[i]) {
return i;
}
}
return -1;
}
//清空
void Clear(struct Stack* st) {
assert(st != NULL);
/*while (st->top != 0) {
st->top--;
}*/
st->top = 0;
}
//销毁
void Destory(struct Stack* st) {
assert(st != NULL);
free(st->base);
st->stacksize = st->top = 0;
}
//打印
void Show(struct Stack* st) {
assert(st!= NULL);
for (int i = 0; i < st->top; i++) {
printf("%d", st->base[i]);
}
printf("\n");
}
//获取有效值个数
int Get_length(struct Stack* st) {
assert(st != NULL);
int count = 0;
for (int i = 0; i < st->top; i++) {
count++;
}
return count;
}
main 测试代码
int main() {
struct Stack head;
Init_stack(&head);
for (int i = 1; i <= 10; i++) {
Push(&head,i);
}
Show(&head);
Pop(&head);
Show(&head);
ELEM_TYPE n= Top(&head);
printf("%d\n", n);
int a=Search(&head, 5);
printf("%d\n", a);
for (int i = 11; i <= 100; i++) {
Push(&head,i);
}
Show(&head);
Inc(&head);
for (int i = 0; i <= 10; i++) {
Push(&head,i);
}
Show(&head);
}
3.顺序栈的常见形态
三、链栈
1.链栈的定义
这里要注意,链栈一定是头插和头删,因为时间复杂度为O(1),而尾插时间复杂度为O(n),我们不选择
头部插入:入栈
头部删除:出栈
2.代码实现
.h头文件
#pragma once
typedef int ELEM_TYPE;
typedef struct LStack {
//数据域
ELEM_TYPE data;
//指针域
struct LStack* next;
}Lstack,Pstack;
//链式操作实现
//初始化
void Init_LStack(struct LStack* pstack);
//入栈(相当于单链表的头插)
bool push(struct LStack* pstack, ELEM_TYPE val);
//出栈(相当于单链表头删)
bool Pop(struct LStack* pstack);
//获取栈顶元素值 //不能删除
ELEM_TYPE Top(struct LStack* pstack);
//判空
bool Is_Empty(struct LStack* pstack);
//搜索
struct LStack* reserch(struct LStack* pstack, ELEM_TYPE val);
//清空
void Clear(struct LStack* pstack);
//销毁1
void Destory1(struct LStack* pstack);
//销毁2
void Destory2(struct LStack* pstack);
//打印
void Show(struct LStack* pstack);
//获取有效值个数
int Get_length(struct LStack* pstack);
.cpp功能代码实现
#include "list_stack.h"
#include<stdio.h>
#include<stdlib.h>
#include <cassert>
//初始化
void Init_LStack(struct LStack* pstack) {
assert(pstack != NULL);
pstack->next = NULL;
}
//入栈(相当于单链表的头插)
bool push(struct LStack* pstack, ELEM_TYPE val) {
assert(pstack != NULL);
struct LStack* snewnode = (struct LStack*)malloc(sizeof(LStack));
snewnode->data=val;
snewnode->next = pstack->next;
pstack->next = snewnode;
return true;
}
//出栈(相当于单链表头删)
bool Pop(struct LStack* pstack) {
assert(pstack != NULL);
struct LStack* p = pstack->next;
pstack->next = p->next;
free(p);
return true;
}
//获取栈顶元素值 //不能删除
ELEM_TYPE Top(struct LStack* pstack) {
assert(pstack != NULL);
struct LStack* p = pstack->next;
ELEM_TYPE temp = p->data;
return temp;
}
//判空
bool Is_Empty(struct LStack* pstack) {
assert(pstack != NULL);
if (pstack->next = NULL) {
return true;
}
return false;
}
//搜索
struct LStack* reserch(struct LStack* pstack, ELEM_TYPE val) {
assert(pstack != NULL);
struct LStack* p = pstack->next;
for (; p != NULL; p=p->next) {
if (val == p->data) {
return p;
}
}
return NULL;
}
//清空
void Clear(struct LStack* pstack) {
assert(pstack != NULL);
Destory1(pstack);
}
//销毁1
void Destory1(struct LStack* pstack) {
assert(pstack != NULL);
struct LStack* p = pstack->next;
for (; p!= NULL;p=p->next) {
Pop(p);
}
}
//销毁2
void Destory2(struct LStack* pstack) {
assert(pstack != NULL);
struct LStack* p = pstack->next;
struct LStack* q = p;
pstack->next = NULL;
while (p != NULL) {
q = p->next;
free(p);
p = q;
}
}
//打印
void Show(struct LStack* pstack) {
assert(pstack != NULL);
struct LStack* p = pstack->next;
for (; p != NULL; p = p->next) {
printf("%d ", p->data);
}
printf("\n");
}
//获取有效值个数
int Get_length(struct LStack* pstack) {
assert(pstack != NULL);
int count = 0;
struct LStack* p = pstack->next;
for (; p != NULL; p = p->next) {
count++;
}
return count;
}
.main测试代码
int main() {
struct LStack head;
Init_LStack(&head);
for (int i = 1; i <= 10; i++) {
push(&head,i);
}
Show(&head);
Pop(&head);
Show(&head);
ELEM_TYPE res= Top(&head);
printf("%d", res);
}