《大话数据结构》读书笔记--第4章 栈和队列

4.2 栈的定义

  1. 栈定义:是限定仅在表尾进行插入和删除的线性表
  2. 允许插入和删除的一端叫栈顶,另一端叫栈底
  3. FILO
  4. 栈的插入操作进栈(压栈、入栈)
  5. 栈的删除操作出栈(弹栈)

4.3 栈的抽象数据类型

Data
Operation
   InitStact(*S);
   DestoryStack(*S);
   ClearStack(*S);
   StackEmpty(S);
   GetTop(S,*e);
   Push(*S,e); //入栈
   Pop(*S,*e);//出栈
   StackLength(S);

4.4 栈的顺序存储结构及实现

typedef int ElemType;
typedef struct{
  ElemType data[MAXSIZE];
  int top; //栈顶指针
}SqStack;

4.4.2 进栈操作

Status Push(SqStack *S,ElemType e){
  if(S->top == MAXSIZE - 1){
     return ERROR;
  }
  S->top++;
  S->data[S->top] = e;
  return OK;
}

4.4.3 出栈操作

Status Pop(SqStack *S,ElemType *e){
  if(S->top == -1){
     return ERROR;
  }
  *e = S->data[S->top];
  S->top--;
  return OK;
}

4.5 两栈共享空间

typedef struct{
  ElemType data[MAXSIZE];
  int top1; //栈1栈顶指针
  int top2; //栈2栈顶指针
}SqDoubleStack;
//入栈操作
//stackNum 判断 栈1 还是 栈2
Status Push(SqDoubleStack *S,ElemType e,int stackNum){
  it(S->top1 + 1 == S->top2){
     return ERROR;
  }
  if(stackNum == 1){
    S->data[++S->top1] = e;
  }else if {
    S->data[--S->top2] = e;
  }
}

//出栈操作
Status Pop(SqDoubleStack *S,ElemType *e,int stackNum){
  if(stackNum == 1){
      if(S->top1==-1){
        return ERROR; 
      }
      *e = S->data[S->top1--];
       
  } else if {
      if(S->top2==MAXSIZE){
        return ERROR; 
      }
      *e = S->datap[S->top2++];
  }

  it(S->top1 + 1 == S->top2){
     return ERROR;
  }
  if(stackNum == 1){
    S->data[++S->top1] = e;
  }else if {
    S->data[--S->top2] = e;
  }
}

4.6 栈的链式存储结构及实现

4.6.1 栈的链式存储结构

  1. 简称链表。
  2. 空栈:top = NULL;
//栈结点
typedef struct StackNode{
   ElemType data; //元素
   struct StackNode *next; //结点指针
}StackNode,*LinkStackPtr;

typedef struct LinkStack{
  LinkStackPtr top;
  int count;
}LinkStack;

4.6.2 进栈操作

//入栈
Status Push(LinkStact *S,ElemType e){
   LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));
   s->data = e; 
   s->next = S->top; //把栈顶元素赋值给新结点直接后继元素
   S->top = s; //将新新结点 s 赋值给 栈顶元素;
   S->count++; //长度+1
   return OK
}
//出栈
Status Pop(LinkStack *S,ElemType *e){
  ListStackPtr p;
  if(StackEmpty(*s)){
    return ERROR;
  }
  *e = S->top->data;
  p=S->top; //将栈顶元素赋值给p;
  S->top = S->top->next; //栈顶元素指针下移一位
  free(p); //释放p结点
  S->count--; //长度-1
  return OK;
}
  1. 如果栈的使用哦过程中元素变化不可预料,使用链栈,反之只用顺序栈。

4.7 栈的作用

4.8 栈的应用–递归

4.8.1 菲波那切数列

int Fbi(int i){
   if(i < 2){
     return i == 0 ? 0 : 1;
   } else{
     return Fbi(i-1) + Fbi(i+2);
   }
}

4.8.2 递归定义

  1. 直接调用自己或通过一系列调用语句间接调用自己函数,称为递归函数。

4.9 栈的应用-四则运算表达式求值

4.9.1 后缀(逆波兰)表达法定义

中缀表达式:9 + (3-1) * 3 + 10 / 2
后缀表达式:9 3 1 - 3 * 10 2 / +
所有的符号都是在运算数字后面出现

4.9.2 后缀表达式计算结果

  1. 从左到右,遇到数字就进栈,遇到符号,就将处于栈顶的两个数字出栈,进行运算,运算结果进栈。

4.9.3 中缀表达式转后缀表达式

1.从左到右,数字输出,符号,判断栈顶符号优先级,是右括号或优先级低于栈顶符号,这栈顶元素依次出栈并输出,并将当前符号出栈。

4.10 队列的定义

  1. 只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
  2. 先进先出(FIFO)
  3. 允许插入一端叫队尾,允许删除一端叫对头
ADT
Data
Operation
  InitQueue(*Q);
  DestroyQueue(*Q);
  ClrearQueue(*Q);
  QueueEmpty(Q);
  GetHead(Q,*e);
  EnQueue(*Q,e); //插入
  DeQueue(*Q,*e); //删除
  QueueLength(Q);

4.12 循环队列

| | | a3| a4 | a5 |
     font          rear
假溢出     

4.12.2 循环队列定义

  1. 队列的这种头尾相接的顺序存储结构称为循环队列
  2. 问题
当 fron == rear 队列满了还是空队列
1.设置标志位 flag
2.设置一个空闲单元
  1. 队列满(rear + 1)% QueueSize == front
  2. 计算队列长度:(rear - front + QueueSize) % QueueSize
//结构
typedef int QElemType;
typedef struct{
  QElemType data[MAXSIZE];
  int font;
  int rear;
}SqQueue;

//初始化
Status InitQueue(SqQueue *Q){
   Q->font = 0;
   Q->rear = 0;
   return OK;
}
//长度
int QueueLength(SqQueue Q){
  retutn (Q.rear - Q.font + MAXSIZE) % MAXSIZE;
}
//插入
Status EnQueue(SqQueue *Q,QElemType e){
  if((Q->rear + 1) % MAXSIZE == Q->front){
     return ERROR;
  } else {
    Q->data[Q->rear] = e;
    Q->rear = (Q->rear + 1) % MAXSIZE; //rear 移动一位
    return OK;
  }
}
//删除
Status DeQueue(SqQueue *Q,QElemType *e){
   if(Q->front == Q->rear){
      return ERROR;
   }else{
      *e = Q->data[Q->front];
      Q->front = (Q->front + 1) % MAXSIZE;//font 向后移动一位
   }
}

4.13 队列链式存储结构及实现

  1. 其实就是线性表的单链表,尾进头出,链队列。
    在这里插入图片描述
//结构
typedef int QElemType;
typedef struct QNode{
  QElemType data;
  struct QNode *next;
}QNode,*QueuePtr ;

typedef struct {
  QueuePtr front,rear; //对头、队尾指针
}LinkQueue;

//入队
Status Enqueue(LinkQueue *Q,QElemType e){
  QueuePtr s = (QueuePtr) malloc(sizeof(QNode));
  if(!s){
     exit(OVERFLOW);
  }
  s->data = e;
  s->next = NULL;
  Q->rear->next = s;
  Q->rear=s; //后移
  return OK;
}
//出队
Status DeQueue(LinkQueue *Q,QElemType *e){
   QueuePtr p;
   if(Q->front == Q->rear){
     return ERROE;
   }
   p = Q->font->next;
   *e = p->data;
   Q->front->next = p->next;
   if(Q->rear == p){ //如果对头是队尾,删除后将rear指向头结点
      Q->rear = Q->front; 
   }
   free(p);
   return OK;
}
发布了40 篇原创文章 · 获赞 14 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_44947117/article/details/104181048