数据结构总结笔记2:栈、队列

一、考试内容:

1,栈的定义,逻辑结构和常用运算;

特点:后进先出,先进后出

栈(Stack):是限定只在表尾进行插入和删除操作的线性表。

栈顶(top):表尾端,进行插入和删除操作的一端。

栈底(bottom):表头一端,即不进行操作的一端。

空栈:不含任何元素的栈。

常用运算:

ADT Stack {

    数据对象:

    数据关系: 约定an端为栈顶,a1端为栈底。

    基本操作:

        InitStack(&S)操作结果:构造一个空栈S

       DestroyStack(&S)  初始条件:栈S已经存在。  操作结果:栈S被销毁。

       ClearStack(&S)    初始条件:栈S已经存在。  操作结果:将S清为空栈。

       StackEmpty(S) 初始条件:栈S已经存在。 操作结果:若栈S为空栈,在返回true,否则返回false。

       StackLength(S) 初始条件:栈S已经存在。 操作结果:返回S的元素个数,即栈的长度。

       GetTop(S,&e) 初始条件:栈S已经存在且非空。 

              操作结果:用e返回S的栈顶元素(栈顶元素不删除,top指针不改变) 。

       Push(&S,e)  初始条件:栈S已经存在。 操作结果:插入元素e为新的栈顶元素。

       Pop(&S,&e) 初始条件:栈S已经存在且非空。操作结果:删除S的栈顶元素,并用e返回其值。

       StackTraverse(S,visit())初始条件:栈S已经存在且非空。

          操作结果:从栈底到栈顶依次对S的每个数据元素调用函数visit()。一旦visit()失败,则操作失败。

} ADT Stack

2,栈的存储结构

 两种:顺序存储结构和链表存储结构。 

顺序栈:栈的顺序存储结构,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素;同时附设指针top指向栈顶元素在顺序栈中的位置。

#define STACK_INIT_SIZE  100  //存储空间初始分配量

#define STACKINCREMENT  10  //存储空间分配增量

typedef  struct {

   SElemType    *base;            

   //在栈构造之前和销毁之后,base的值为NULL

   SElemType    *top; //栈顶指针

   int  stacksize;

//当前已分配的存储空间,以元素为单位。

} SqStack

 

 

初值指向栈底,即top==base可作为栈的标记;   每当插入新的栈顶元素时,指针top增1

删除栈顶元素时,指针top减1,因此,非空栈中的栈顶指针始终在栈顶元素的下一个位置上。

顺序栈基本运算:

初始化:

InitStack  S.base=(SElemType *)malloc(STACK_INIT_SIZE *sizeof(SElemType));//分配栈的存储区、赋基址

         if (!S.base) exit (OVERFLOW);     //存储分配失败

         S.top=S.base;   //栈顶指针初值

         S.stacksize=STACK_INIT_SIZE;  //栈大小初值

入栈:

Push  S.base=(SElemType*)realloc(S.base, (S.stacksize+STACKINCREMENT)*sizeof(SElemType));//栈满处理

S.top=S.base+S.stacksize;     //能与下一句互调吗?       

      S.stacksize+=STACKINCREMENT;

出栈:Pop  e=*--S.top;//含义?   

取栈顶元素:  GetTop  e=*(S.top-1); //含义?

栈的链式存储结构:链式栈

*链式栈无栈满问题,空间可扩充

*插入与删除仅在栈顶处执行

*链式栈的栈顶在链头     //无表头结点的单链表

typedef struct node {
    sElemtype data;        //结点
    struct node *next;        //链指针
} StackNode;


typedef struct {
    StackNode *top;           //栈顶指针
} LinkStack;

入栈:

p->data = x;  
p->next = S->top;       //前插
S->top = p;

取栈顶:  x = S->top->data;
出栈:

 p = S->top;
 S->top = p->next;
 x = p->data;
 free (p);

 

 

3,栈的实际应用;

数制转换;括弧匹配的检验;行编辑程序;表达式求值;递归

 

4,栈与递归的关系;

递归定义:若一个对象部分地包含它自己,  或用它自己给自己定义,  则称这个对象是递归的;

递归的三种情况:  定义是递归的(函数);数据结构是递归的(二叉树、广义表);问题的解法是递归的;(hanoi塔)

递归时要实现的规则是:“后调用先返回”,此时的内存管理实行“栈式管理”。

栈式管理:    系统将整个程序运行时所需的数据空间安排在一个中,每当调用一个函数时,就为函数中使用的参数、局部变量等在栈顶分配一个存储区,每当从一个函数退出时,就释放它的存储区,从栈顶将其删除,则当前正运行的函数的数据区必在栈顶。为了保证递归函数正确执行,系统需设立一个“递归工作栈”,作为整个递归函数运行期间使用的数据存储区。   这个栈同样可以是顺序栈也可以是链式栈。

5,队列的定义及存储结构;

定义:只允许在表的一端进行插入,而在另一端删除元素的线性表。  特点:先进先出、后进后出

队尾(rear):在队列中,允许插入的一端叫队尾。     队头(front):允许删除的一端称为队头。

顺序存储结构:

用一组地址连续的存储单元依次存放从队列头到队列尾的元素。

指针:front:指示队头元素的位置   ;rear:指示队尾元素的位置。

初始化建空队列时,令front=rear=0

插入新的队尾元素,尾指针增1,rear = rear + 1

删除队头元素,头指针增1, front = front + 1

非空队列中:

头指针始终指向队列头元素,

尾指针始终指向队列尾元素的下一个位置。

循环队列:解决假溢出问题。   

等式q.rear=q.front无法判别队列空间是“空”还是“满”。为了区分队空和队满:

①另设一个标志位以区别队列是“空”还是“满”;  ②少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置上”作为队列呈现“满”状态的标志。通过求模运算来实现指针的变化。

队满条件:(rear+1) % maxsize == front;  队空条件:front == rear; 队列初始化:front = rear = 0;

队头指针进1:入队  front = (front+1) %maxsize;      队尾指针进1: 出队 rear = (rear+1) % maxsize;

求队长:(rear-front+maxsize)%maxsize

循环队列的类型定义

#define  MAXQSIZE  100      //队列最大长度

typedef  struct {

   QElemType   *base;      //初始化的动态分配存储空间

   int    front;  //头指针,若队列不空,指向队列头元素

   int    rear;  //尾指针,若队列不空,指向队列尾元素的下一个位置。

} SqQueue;

链队列:队列的链式表示

链队列中,有两个分别指示队头和队尾的指针。队头指针指向头结点,队列尾的指针指示队尾。 

无队满问题,但有队空问题。空的链队列的判决条件队头指针和队尾指针均指向头结点

链式队列的定义(单链队列)

typedef struct QNode {
   QElemType  data;
   Struct  QNode  *next;
}QNode,*QueuePtr;

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

初始化:  Q.front→next=null;  

入队:    Q.rear→next=p;  //队尾最后一个元素和其连上

            Q.rear=p;   //修改队尾指针

出队:   p=Q.front→next;  e=p→data;     //获得待删结点

        Q.front→next=p→next; //不修改队头指针,修改头结点的指针

6,队列的应用。

OS中:1)解决计算机主机与外设不匹配的问题;2)解决由于多用户引起的资源竞争问题;

3)离散事件的模拟----模拟实际应用中的各种排队现象; 4)用于处理程序中具有先进先出特征的过程;

 

二、考试要求:

了解栈和队列的逻辑结构定义,

栈和队列是操作受限的线性表。只能在表的首尾部两端进行数学运行。

栈:只能在表尾进行插入、删除;队列:在表尾插入表头删除

 

掌握栈和队列运算特点,掌握栈和递归的关系,(简答)

掌握栈和队列的顺序存储结构。

 

算法实现方面要求,可以熟练利用栈和队列的顺序存储结构解决实际的问题,如:走迷宫问题、表达式括号匹配问题等。

发布了38 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_40165004/article/details/93159228