数据结构-其他线性结构(栈和队列)

大纲:

  1. *掌握栈的定义、栈的存贮结构及基本操作的实现。
  2. 理解用栈实现表达式的求值,递归过程及实现。
  3. 掌握队列的定义、存贮结构及基本操作的实现。
  4. 理解串的逻辑定义及其基本操作;理解串的存贮结构。
  5. 理解数组的定义、数组的顺序存贮结构及矩阵的存贮压缩。
  6. 理解广义表的定义及存贮结构。

栈的基本概念

  1. 栈的定义

    只允许在一端进行插入或删除操作的线性表

    • 栈顶:栈允许进行插入和删除的那一端
    • 栈底:固定的,不允许进行插入和删除的另一端
    • 栈是一个后进先出的线性表
  2. 栈的基本操作

  • InitStack(&S):栈的初始化
  • StackEmpty(S):判断栈是否为空
  • Push(&S,x):进栈
  • Pop(&S,&x):出栈
  • GetTop(S,&x):读栈顶元素
  • ClearStack(&S):销毁栈

顺序栈

栈的顺序存储

#define MaxSize 50  //定义栈中元素的最大个数
typedef struct{
  Elemtype data[MaxSize];  //存放栈中元素
  int top;  //栈顶指针
}SqStack;
  • 栈空条件:S.top=-1;栈满条件:S.top=MaxSize-1;栈长:S.top+1
  • 顺序栈的基本操作相关代码
    //初始化
    void InitStack(&S){
    S.top=-1;  //初始化栈顶指针
    }
    //判栈空
    bool StackEmpty(S){
      if(S.top==-1)
        return true;
      else
        return false;
    }
    //进栈
    bool Push(SqStack &S,ElemType x){
      if(S.top==MaxSize-1)  //栈满
        return false;
      S.data[++S.top]=x;  //指针自增1,入栈
      return true;
    }
    //出栈
    bool Pop(SqStack &S,ElemType &x){
      if(S.top==-1)  //栈空
        return false;
      x=S.data[S.top--];  //出栈,指针减一
      return true;
    }
    //读栈顶元素
    bool GetTop(SqStack S,ElemType &x){
      if(S.top==-1)
        return false;
      x=S.data[S.top];
      return true;
    }
    
  • 共享栈

    利用栈底位置不变的特性,让两个栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸

    • top0=-1是0号栈为空,top1=MaxSize时1号栈为空
    • 仅当两个栈顶指针相邻时,判断为栈满

链栈

采用链式存储的栈,通常采用单链表实现,并规定所有操作在单链表的表头进行,且链栈没有头结点,Lhead指向栈顶元素。

结构体描述

typedef struct Linknode{
  ElemType data;
  struct Linknode *next;
}*LiStack;
  • 采用链式存储,便于插入、删除操作,具体步骤与单链表类似。
  • 对n个不同元素进栈,出栈序列的个数为
    卡特兰数

队列

队列的基本概念

  1. 队列的定义

    只允许在表的一段进行插入,表的另一端进行删除

    • 队头:允许删除的一端
    • 队尾:允许插入的一端
    • 空队列:不含任何元素的空表
    • 队列是一个先进先出的线性表
  2. 队列的基本操作

    • InitQueue(&Q):初始化队列
    • QueueEmpty(Q):判队列空
    • EnQueue(&Q):入队
    • DeQueue(&Q,&x):出队
    • GetHead(Q,&x):读队头元素

队列的顺序存储结构

队列的顺序存储

分配一块连续的存储单元存放队列中的元素,并设置两个指针front和rear分别指示队头元素和队尾元素的位置。

结构体描述

#define MaxSize 50
typedef struct{
  ElemType data[MaxSize];
  int front,rear;
}SqQueue;
  • 队头指针指向对头元素,队尾指针指向队尾元素的下一个位置
  • 队列判空条件:Q.front=Q.rear=0
  • 队列会出现假溢出的情况
循环队列

将顺序队列想象成一个环状空间,也就是逻辑上将存储队列元素的表看成一个环,即循环队列

  • 初始时:Q.front=Q.rear=0
  • 对首指针进1:Q.front=(Q.front+1)%MaxSize
  • 对尾指针进1:Q.rear=(Q.rear+1)%MaxSize
  • 队列长度:(Q.rear+MaxSize-Q.front)%MaxSize
  • 队满判断:一般有三种
    • 牺牲一个单元来区分队空队满,即队头指针在队尾指针的下一位置作为队满的标志
      • 队满条件:(Q.rear+1)%MaxSize==Q.front
      • 队空条件:Q.front==Q.front
      • 队列中元素的个数:(Q.rear-Q.front+MaxSize)%MaxSize
    • 类型中增设表示元素个数的数据成员size,则队空条件为Q.size=0,队满条件为Q.size=MaxSize,两种情况中都有Q.front=Q.rear
    • 类型中增设tag数据成员,区分队空还是队满。则tag等于0的情况下,因删除导致Q.front==Q.rear则为队空,tag=1的情况下,因插入导致Q.front==Q.rear则为队满
  • 循环队列的基本操作相关代码
//初始化
void InitQueue(&Q){
  Q.front=Q.rear=0;
}
//判队空
bool isEmpty(Q){
  if(Q.rear==Q.front)
    return true;
  else
    return false;
}
//入队
bool EnQueue(SqQueue &Q,ElemType x){
  if((Q.rear+1)%MaxSize==Q.front)  //队满
    return false;
  Q.data[Q.rear]=x;
  Q.rear=(Q.rear+1)%MaxSize;  //队尾指针加一取模
  return true;
}
//出队
bool DeQueue(SqQueue &Q,ElemType &x){
  if(Q.rear==Q.front)
    return false;
  x=Q.data[Q.front];
  Q.front=(Q.front+1)%MaxSize;  //队头指针加一取模
  return true;
}

队列的链式存储结构

队列的链式表示即链队列

  • 结构体描述
typedef struct{  //链式队列结点
  ElemType data;
  struct LinkNode *next;
}LinkNode;
typedef struct{  //链式队列
  LinkNode *front,*rear;  //队列的队头和队尾指针
}LinkQueue;
  • Q.front==NULL和Q.rear==NULL时,队列为空
  • 链队列通常设计成带头结点的单链表,这样插入删除操作统一
  • 链队列基本操作相关代码
//初始化
void InitQueue(LinkQueue &Q){
  Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
  Q.front->next=NULL;
}
//判队空
bool IsEmpty(LinkQueue Q){
  if(Q.front==Q.rear)
    return true;
  else
    return false;
}
//入队
void EnQueue(LinkQueue &Q,ElemType x){
  s=(LinkNode *)malloc(sizeof(LinkNode));
  s->data=x;
  s->next=NULL;
  Q.rear->next=s;
  Q.rear=s;
}
//出队
void DeQueue(LinkNode &Q,Elemtype &x){
  if(Q.front==Q.rear)
    return false;
  p=Q.front->next;
  x=P->data;
  Q.front->next=p->next;
  if(Q.rear==p)   //若原队列中只有一个结点,删除后变空
    Q.rear=Q.front;
  free(p);
  return true;
}

双端队列

双端队列是指允许两端都可以进行入队和出队操作的

  • 输出受限的双端队列:允许一端进行插入和删除,但在另一端只允许插入的双端队列
  • 输入受限的双端队列:允许一端进行插入和删除,但在另一端只允许删除的双端队列

栈和队列的应用

  1. 中缀转后缀表达式
    • 若为‘(’,入栈
    • 若为‘)’,则依次把栈中的运算符加入后缀表达式,直到出现‘(’,并从栈中删除‘(’
    • 若为‘+’,‘-’,‘*’,‘/’
      • 栈空,入栈
      • 栈顶元素为‘(’,入栈
      • 高于栈顶元素优先级,入栈
      • 否则,依次弹出栈顶运算符,直到一个优先级比他低的运算符或‘)’为止
        *遍历完成,若栈非空,依次弹出所有元素

矩阵

压缩矩阵:指多个值相同的元素只分配一个存储空间,对零元素不分配存储空间。其目的是为了节省存储空间
特殊矩阵:指具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分布有一定规律性的矩阵。常见特殊矩阵有对称矩阵、上(下)三角矩阵、对角矩阵等
特殊矩阵的压缩存储方法:找出特殊矩阵中值相同的矩阵元素的分布规律,把那些呈现规律性分布的值的多个矩阵元素压缩存储到一个存储空间中

  1. 对称矩阵
    元素下标的对应关系
    k = i * ( i - 1 ) / 2 + j - 1 ; i >= j
    k = j * ( j - 1 ) / 2 + i - 1 ; i < j
  2. 三角矩阵
    下三角矩阵元素下标的对应关系
    k = i * ( i - 1 ) / 2 + j - 1 ; i >= j
    k = n * ( n + 1 ) / 2 ; i < j
    上三角矩阵元素下标的对应关系
    k = ( i - 1 ) * ( 2n - i + 2 ) / 2 + ( j - i ) ; i <= j
    k = n * ( n + 1 ) / 2 ; i > j
  3. 三对角矩阵
    元素下标的对应关系
    k = 3 * ( i - 1 ) - 1 + j - i + 1 = 2i + j - 3
    已知k求i、j
    i = [ ( k + 1 ) / 3 + 1 ] ; j = k - 2i + 3

稀疏矩阵

矩阵元素个数远大于非零元素个数的矩阵

  • 一般采用三元组(行标,列标,值)的形式存储
  • 稀疏矩阵压缩存储后失去随机存取特性
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容