栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构(二)—— 栈,队列,广义表

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构(二)—— 栈,队列,广义表

文章目录
  • 第2章 栈,队列,数组
    • 栈
      • 定义
      • 基本操作
      • 顺序栈
        • 定义
        • 基本操作——初始化
        • 基本操作——进栈
        • 基本操作——出栈
        • 基本操作——读取栈顶元素
      • 链栈
        • 栈的应用
          • 括号匹配
          • 表达式求值
    • 队列
      • 定义
      • 基本操作
      • 顺序队列
        • 定义
        • 基本操作——初始化
        • 基本操作——入队
        • 其他判断队空/队满条件
        • 基本操作——出队
        • 基本操作——读取队头元素
      • 链队列
        • 定义
        • 基本操作——初始化
        • 基本操作——入队
        • 基本操作——出队
      • 双端队列
      • 队列的应用
    • 矩阵的压缩存储
      • 对称矩阵
      • 上三角矩阵
      • 三对角矩阵
      • 稀疏矩阵
    • 广义表

第2章 栈,队列,数组 栈 定义

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

基本操作

InitStack(&S):初始化栈。构造一个空栈S,分配内存空间。
DestroyStack(& S):销毁栈,并释放栈S所占用的空间。
Push(&S,x):进栈,若栈S未满,则将x加入使之成为新栈顶。
Pop(&S,&x):出栈,若栈S非空,则弹出栈顶元素,并用x返回。
GetTop(S,&x):读取栈顶元素。若栈S非空,则用x返回栈顶元素。
其他常用操作:
StackEmpty(S):判断一个栈S是否为空。若S为空,则返回true,否则返回false。

顺序栈 定义
#define MaxSize 10
typedef struct {
    ElemType data[MaxSize];		//静态数组存放栈中元素
    int top;					//当前栈顶指针位置
}SqStack;

Tips:注意栈顶指针top的含义。

基本操作——初始化
//初始化
void InitStack(SqStack &S) {
    S.top = -1;
}
基本操作——进栈
bool Push(SqStack &S,ElemType x) {
    if(S.top == MaxSize -1)		//栈满
        return false;
    S.top ++;
    S.data[S.top] = x;		//进栈
    //S.data[++S.top];
    return true;
}
基本操作——出栈
bool Pop(SqStack &S,ElemType &x) {
    if(S.top == -1)		//栈空
        return false;
    x = S.data[S.top];	//出栈
    S.top --;
    //x = S.data[S.top--];
    return true;
}
基本操作——读取栈顶元素
bool GetTop(SqStack &S,ElemType &x) {
    if(S.top == -1)		//栈空
        return false;
    x = S.data[S.top];	//x记录栈顶元素
    return true;
}
链栈

栈的应用 括号匹配
bool BracketCheck(char str[],int length) {
    SqStack S;
    InitStack(S);	//初始化一个栈
    for(int i = 0;i < length;i++){
        if(str[i] == '(' || str[i] == '[' || str[i] == '{') {
            Push(S,str[i]);		//扫描到左括号,入栈
        }
        else{
            if(StackEmpty(S))	//扫描到右括号,且当前栈空,则匹配失败
        		return false;
            char topelem;
            Pop(S,topElem);		//栈顶元素出栈
            if(str[i] == ')' && topElem != '(')
                return false;
            if(str[i] == ']' && topElem != '[')
                return false;
            if(str[i] == '}' && topElem != '{')
                return false;
        }
    }
    return StackEmpty(S);	//检查完全部括号后栈空,则说明配对成功
}
表达式求值


队列 定义

只允许在一端进项插入,在另一端删除的线性表。

基本操作

InitQueue(&Q):初始化队列,构造一个空队列Q。
DestroyQueue(&Q):销毁队列。销毁并释放队列Q所占用的空间。
EnQueue(&Q,x):入队,若队列未满,将x加入,使之成为新的队尾。
DeQueue(&Q,&x):出队,若队列Q非空,删除队头元素,并用x返回。
其他常用操作:
GetHead(Q,&x):读取队头元素,若队列Q非空,则将队头元素赋给x。
QueueEmpty(Q):判断队列是否为空,若队列为空返回true,否则返回false;

顺序队列 定义
#define MaxSize 10
typedef struct {
    ElemType data[MaxSize];		//用静态数组存放队列元素
    int front,rear;				//队尾指针指向队尾元素后一个位置
}SqQueue;
基本操作——初始化
void InitQueue(SqQueue &Q) {
    Q.rear = Q.front = 0;		//队空条件
}
基本操作——入队
bppl EnQueue(SqQueue &Q) {
    if(Q.rear == Q.front)		//判断队满
    	return false;
    Q.data[Q.rear] = x;
    Q.rear = (Q.rear + 1) % MaxSize;	//模运算使存储空间在逻辑上变成了“环”
    return true;
}

其他判断队空/队满条件

(1)在不牺牲存储单元的情况下可以在结构体设置int size记录队列长度,根据长度进行判断队空和队满。
(2)

基本操作——出队
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;
}
基本操作——读取队头元素
bool GetHead(SqQueue Q,ElemType &x) {
    if(Q.rear == Q.front)
        return false;	//判断队空
    x = Q.data[Q.front];
    return true;
}

Tips:队列元素个数 = (rear + MaxSize - front) % MaxSize

链队列 定义
typedef struct LinkNode {	//链式队列结点
    ElemType data;
    struct LinkNode *next;
}LinkNode;

typedef struct {			//链式队列
    LinkNode *front,*rear;	//队列的队头和队尾指针	
}LinkQueue;
基本操作——初始化
void InitQueue(LinkQueue &Q) {
    
	Q.front = Q.rear = (LinkNode)malloc(sizeof(LinkNode));
    Q->front->next = NULL;
}


void InitQueue(LinkQueue &Q) {
	Q.front = NULL;		
    Q.rear = NULL;
}
基本操作——入队
void EnQueue(LinkQueue &Q,ElemType x) {
	LinkNode *s = (LinkNode*) malloc(sizeof(LinkNode));
    s->data = x;
    s->next = NULL;
    Q.rear->next = s;
    Q.rear = s;
}


void EnQueue(LinkQueue &Q,ElemType x) {
	LinkNode *s = (LinkNode*) malloc(sizeof(LinkNode));
    s->data = x;
    s->next = NULL;
    if(Q.front == NULL) {		//空队列插入第一个元素
        Q.front = s;
        Q.rear = s;
    }
    else{
    	Q.rear->next = s;
    	Q.rear = s;
	}
}
基本操作——出队
bool DeQueue(LinkQueue &Q,ElemType &x) {
    if(Q.front == Q.rear)		//空队
        return false;	
    LinkNode *p = Q.front->next;
    x = p->data;
    Q.front->next = p->next;
    if(Q.rear == p)		//此次是最后一个结点出队
        Q.rear = Q.front;
    free(p);
    return true;
}


bool DeQueue(LinkQueue &Q,ElemType &x) {
	if(Q.front == NULL)		//空队
        return false;
    LinkNode *p = Q.front;
    x = p->data;
    Q.front = p->next;
    if(Q.rear == p) { 		//此次是最后一个结点出队
    	Q.front = NULL;
        Q.rear = NULL;
    }
    free(p);
    return true;
}

Tips:一般不会出现队满情况。

双端队列

允许在两端插入、两端删除的线性表。(输入受限/输出受限)
Tips:在栈中合法的输出序列,在双端序列必定合法。

队列的应用
  • 树的层次遍历
  • 图的广度优先遍历
矩阵的压缩存储 对称矩阵



Q:数组大小应为多少?
A:(n + 1)* n / 2

上三角矩阵

三对角矩阵


稀疏矩阵


广义表
  • 广义表是具有n个元素的有限序列,记为LS = (a1,a2,……an)。
  • 一个广义表通常可以用一对圆括号括起来,n是它的长度。
  • ai可以是单个元素,也可以是广义表,分别叫原子和子表(子表也要用圆括号括起来)。
  • 用大写字母表示广义表的结构名,用小写字母表示原子。
  • 广义表非空时,第一个元素a1为LS的表头(head),其余元素组成的表(a2,a3,……an)是LS的表尾(tail)。
    • A = () —— A是一个空表,长度为零。
    • B = (e) —— 列表B只有一个原子e,B的长度为1。
    • C = (a,(b,c,d)) —— 列表C的长度为2,两个元素分别为原子a和子表(b,c,d)。
    • D = (A,B,C) —— 列表D的长度为3,三个元素都是列表。
    • E = (a,E) —— 这是一个递归的表,长度为2。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/971458.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号