堆栈课堂笔记

堆栈

存储结构

用顺序栈和链栈都可以,但用顺序栈更常见

图像

top指向的是真正的栈顶元素之上的位置

C
B
A

表示

堆栈大小(S.stackSize),栈顶指针S.top(第一个元素的上面一个地址),栈底指针S.base,栈顶指针高于栈底指针(数量小于)

顺序栈的表示

typedef struct{
    SElemType *top;
    SElemType *base;
    int stacksize;
}SqStack;

链栈的表示

typedef struct StackNode{
SElemType data;
struct stackNode* next;
}StackNode,*LinkStack;
LinkStack S;

链栈是运算受限的单链表,只能在链表头部进行操作,故没有必要附加头节点,头指针就是链栈的头节点

空栈就是栈顶指针置空(头指针数据部不是空的)

基本操作

顺序栈初始化

(1)分配空间并检查空间是否分配失败,若失败返回false

(2)设置栈底和栈顶指针

S.top=S.base

(3)设置栈大小

S.stacksize=MAXSIZE

Status InitStack(SqStack &S){
    S.base=new SElemtype[size];
    if(!S.base) return False;
    S.top=S.base;
    S.stackSize=size;
    return True;
}

计算栈的长度

S.top-S.base;

清空顺序栈

S.top=S.base

销毁顺序栈

if(S.base){
	delete S.base;

    S.stacksize=0;

	S.base=S.top=NULL;    
}

入栈

(1)判断是否栈满,若栈满返回false或分配更大的空间

if(S.top-S.base==S.stackSize)return false;

(2)元素e压入栈顶

*s.top=e

(3)栈顶指针加1

s.top++

出栈

(1)判断是否栈空

if(S.top==S.base)return false;

(2)获取栈顶元素e

e=*(S.top-1)

(3)栈顶指针减1

S.top–

或者:e=*(–S.top)

获取栈顶元素

1)判断是否栈空,空则返回错误

if(S.top==S.base)return false;

(2)获取栈顶元素e

e=*(S.top-1)

应用

数制转换
void conversion(){
    InitStack(S);
    scanf("%d",&N);
    while(N){
        Push(S,N%8);
        N=N/8;
    }
    while(!StackEmpty(S)){
        Pop(S,e);
        printf("%d",e);
    }
}
void conversion(int n){
    if(n==0) return;
    else{
        concersion(n/2);
        cout<<n%2;
    }
}
栈与递归
时间效率

与递归树的深度成正比 O(n)

空间效率

与递归树的节点数(调用次数)成正比 O(2^n)

汉诺塔
#include<iostream.h>
int c=0;//第几个步骤
void move(char c,int n,char z){ //把C上编号为n的盘子移动到Z上
    cout<<++c<<","<<n<<","<<x<<","<<z<<endl;
}
void Hanoi(int n,char A,char B,char C){//用B作为过渡,把A上n个盘子移动到C上
    if(n==1)move(A,1,c);
    else{
        Hanoi(n-1,A,C,B);
        move(A,n,C);
        Hanoi(n-1,B,A,C);
    }
}
求解迷宫

要解决的问题:迷宫的数据结构,试探方向,栈的设计,防止重复到达某点,避免发生死循环

迷宫的数据结构:二维数组

方向:后退为0,上前为1,左边是2,右边是3

栈的设计:

struct{

int direction;

int[][] position;

bool markprint=True;//能否走得通

}

队列

表示

顺序表示

#define MAXQSIZE 100
Typedef struct{
    QElemType* base;
    int front;
    int rear;
}SqQueue;

数据元素

Q.front,Q.rear,front大小低于rear,rear指向的是最后一个元素的下一个

基本操作

空队标志:front=rear;

入队:base[rear++]=x;

出队:x=base[front++];

出队

x=base[front++]

入队

base[rear++]=x;

存在的问题【使用顺序表】

真溢出,假溢出

解决办法:

M是尾结点减去头节点,即整个数组的空间

入队:base[rear]=x;rear=(rear+1)%M;

出队:x=base[front];front=(front+1)%M;

判断队空队满:少用一个元素空间

队空:front==rear;

队满:(rear+1)%M==front

栈和队列区别

都是线性表,只是运算规则不一样,栈是后进先出,队列是先进先出

注意

头指针就是head,仅仅是一个指针,指向头节点,如图
在这里插入图片描述

头节点是为了操作的统一与方便而设立的,放在第一个元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等)。

首元结点也就是第一个元素的结点,它是头结点后边的第一个结点。

单链表也可以没有头结点。如果没有头结点的话,那么单链表就会变成这样:

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值