数据结构与算法2

栈 队列 串

1.栈(stack)

1.1 栈的定义和特点

  • 栈是一个特殊的线性表,仅在表尾进行插入和删除
  • 后进先出的线性表(LIFO结构)

表尾(an端)称为栈顶TOP;表头(a1端)称为栈底BASE

  • 入栈:插入元素到TOP
  • 出栈:从TOP删除最后一个元素

同线性表相同,为一对一关系

  • 存储结构:顺序栈、链栈

    • 栈的顺序存储:顺序栈
    • 栈的链式存储:链栈
  • 上溢(overflow):栈已经满,继续压入值

  • 下溢(underflow):栈已经空,继续弹出值

上溢是一种错误,使问题处理无法进行
下溢使一种结束条件,问题处理结束

1.2 顺序栈的表示

#define MAXSIZE 100
typedef struct{
  int *base;    //栈底
  int *top;     //栈顶
  int stacksize;  //栈可用的最大容量
}SqStack;

1.3 顺序栈的实现

1.3.1 顺序栈的初始化

void InitStack(SqStack &S){    //构建一个空顺序栈
  S.base = new int[MAXSIZE];
  if(!S.base)  return;    //存储分配失败
  S.top = S.base;    
  S.stacksize = MAXSIZE;
}

1.3.2 顺序栈判断栈是否为空

bool StackEmpty(SqStack S){  //若栈顶等于栈底,则顺序栈为空
  if(S.top == S.base)  return true;
  else   return false;
}

1.3.3 求顺序栈长度

int StackLength(SqStack S){
  return S.top - S.base;
}

1.3.4 清空顺序栈

void ClearStack(SqStack &S){
  if(S.base)  S.top = S.base;
}

1.3.5 销毁顺序栈

void DestoryStack(SqStack &S){
  if(S.base){
    delete S.base;
    S.stacksize = 0;
    S.base = S.top = NULL;
  }
}

1.3.6 顺序栈的入栈

void Push(SqStack &S, int e){
  if(S.top - S.base == S.stacksize)    return;  //栈满
  *S.top++ = e;    //等价于*S.top = e;  S.top++;
}

1.3.7 顺序栈的出栈

void Pop(SqStack &S, int &e){
  if(S.top == S.base) return;
  e = *--S.top;    //同上述
}

1.4 栈链的表示

  • 运算受限的单链表,只能在链表头部进行操作
  • 链表的头指针就是栈顶,不需要头结点
  • 插入删除仅在栈顶
typedef struct StackNode{
  int data;
  struct StackNode *next;
}StackNode, *LinkStackPtr;
typedef struct LinkStack{
 LinkStackPtr top;
`int count;
}LinkStack;

1.5 栈链的实现

1.5.1 栈链的初始化

void InitStack(LinkStack *&S){
  S->top = NULL;
  S->count = 0;
}

1.5.2 判断栈链是否为空

bool StackEmpty(LinkStack *S){
  if(S->top == NULL)  return true;
  else           return false; 
}

1.5.3 栈链的入栈

void Push(LinkStack *&S, int e){
  LinkStackPtr p = new StackNode;    //生成新节点
  p->data = e;
  p->next = S->top;
  S->top = p;
  S->count++;
}

1.5.4 栈链的出栈

void Pop(LinkStack *&S, int &e){
  if(S->top == NULL)  return;  
  e = S->top->data;   //出栈的元素值
  LinkStackPtr p = S->top;
  S->top = S->top->next;
  delete p;
  S->count--;
}

1.5.5 取栈顶元素

int GetTop(LinkStack *S){
  if(S->top == NULL)  return;
  return S->data;
}

2.队列(queue)

2.1 队列的定义和特点

  • 队列是一种先进先出(FIFO)的线性表
  • 在表尾插入,表头删除(头删尾插
  • 表尾为an端(队尾),表头为a1端(队头)

同线性表相同,为一对一关系

  • 存储结构:顺序队、链队

循环顺序队列更常见

2.2 顺序队的表示(包括循环队列操作,自行区分)

#define MAXQSIZE 100 //最大队列长度
typedef define{
  int *base;  //初始化动态分配原始空间
  int front;  //头指针
  int rear;  //尾指针    尾指针指向元素的下一个位置
}SqQueue;

2.3 顺序队的实现

常见问题:假上溢
解决方法:引入循环队列 实现方式:使用模运算

  1. 插入元素: Q.base[Q.rear] = x; Q.rear=(Q.rear+1) % MAXQSIZE;
  2. 删除元素: x = Q.base[s.front]; Q.front = (Q.front+1) % MAXQSIZE;

2.3.1 顺序队的初始化

void Init(sqQueue &q){
  q.base = new int(MAXQSIZE);    //为顺序队分配空间
  if(!q.base)  return;
  q.front = q.rear = 0;    //表示队空
}

2.3.2 销毁顺序队

void Destory(sqQueue &q){
  delete q.base;
  q.base = NULL;
}

2.3.3 返回顺序队长

int SqLength(SqQueue q){
  if(q.rear >= q.front)
    return q.rear-q.front+1
  else
    return MAXQSIZE-q.front+q.rear+1;
}

2.3.4 顺序队入队

void EnterSq(sqQueue &q, int e){
  if((q.rear+1)%MAXQSIZE == q.front)  return;
  q.base[q.rear] = e;
  q.rear = (q.rear+1)%MAXQSIZE;
}

2.3.5 顺序队出队

void DeleteSq(sqQueue &q, int &e){
  e = q.base[q.front];
  q.front = (q.front+1)%MAXQSIZE;
}

2.4 队列的链式存储结构

  • 实质是线性表的单链表
  • 只能尾进头出
  • 简称为链队列

对头指针指向链队列头结点 队尾指针指向链队列终端节点

空队列时,front和rear都指向头结点

2.5 链队列的表示

typedef struct QNode{    //结点结构
  int data;
  struct QNode *next;
}QNode,*QueuePtr;
typedef struct{      //队列的链式结构
  QueuePtr front, rear;    //队头队尾指针
}LinkQueue;

2.6 链队列的实现

2.6.1 链队列的入队

void EnQueue(LinkQueue *&Q, int e){
  QueuePtr s = new QNode;
  if(!s)    //存储失败
    return;
  s->data = e;
  s->next = NULL;
  Q->rear->next = s;
  Q->rear = s;
}

2.6.2 链队列的出队

void DeQueue(LinkQueue *&Q, int &e){
  QueuePtr p;
  if(Q->front == Q->rear)    //注意判断队列是否为空
    return;
  p = Q->front->next;
  e = p->data;
  Q->front->next = p->next;
  if(Q->rear == p)
    Q.rear = Q->front;
  delete p;
}

3. 串(string)

3.1 串的定义和特点

  • 串是由零个或多个字符组成的有限序列,又名叫字符串
  • 一般记为 s = "a1a2...an" (n >= 0)
  • n为串的长度
  • 零个字符的串称空串

3.2 串的比较

有两个串s="a1a2...an", t="b1b2...bm"

1. n < m, 且ai=bi(i=1,2,3...,n) 则s<t
2. 存在某个k<=min(m,n),使得ai=bi(i=1,2,3,...,k-1) 则s<t

3.3 串的模式匹配

  • 暴力匹配法
  • KMP算法

总结

  • 栈是限定仅在尾表进行插入删除的线性表
  • 队列是只允许在一端进行插入操作,而在另一端进行删除操作

程杰. 大话数据结构[M]. 北京:清华大学出版社, 2011:25.

posted @   cherishviki  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示