数据结构——栈和队列

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

n个不同元素进栈,出栈元素不同排列的个数为Cn2n/n+1

顺序栈

//顺序栈的定义
typedef struct{
ElemType data[MaxSize];
int top;//栈顶指针,指向栈顶元素,返回数组下标压入4各元素该指针就是4
}SqStack;

//判断栈空
bool StackEmpty(SqStack S){
if(S.top==-1)
    return true;
else
     return false;
}

//初始化
void InitStack(SqStack &S){
 S.top=-1;
}

 //新元素入栈
bool Push(SqStack &S ,ElemType x){
if(S.top==MaxSize-1)//栈满
S.top=S.top+1;//
S.data[S.top]=x;//S.data[++S.top]=x;
return true;
}

//出栈操作
bool Push(SqStack &S ,ElemType &x){
if(S.top==-1)//栈空
    return false;
x=S.data[S.top];//
S.top=S.top-1;//x=S.data[S.top--];
return true;
}

//读栈顶元素
bool Push(SqStack &S ,ElemType &x){
if(S.top==-1)//栈空
    return false;
x=S.data[S.top];//x记录栈顶元素
return true;
}
 
void testStack(){
SqStack S;//声明一个顺序栈
InitStack(S);
}

链栈

队列

队列是只允许在一端进行插入,在另一端删除的线性表

!注意

rear在队尾元素下一位:先赋值再移动指针

rear指向队尾元素:先移动指针再赋值,在初始化时front指向0位置,rear指向n-1位置

顺序存储

//队列的顺序实现
typedef struct{
ElemType data[MaxSize];
int front,rear;
}SqQueue;

//判空
bool QueueEmpty(SqQueue Q){
if(Q.rear==Q.front)
    return true;
else
     return false;
}
//入队
bool QueueEmpty(SqQueue &Q,ElemType x){
if((Q.rear+1)%MaxSize==Q.front)//队满条件:队尾指针的再下一个位置是队头
    return false;
Q.data[Q.rear]=x;//x插入对尾
Q.rear=(Q.rear+1)%MaxSize;//让rear指针循环往复
return true;
}
//
bool QueueEmpty(SqQueue &Q,ElemType &x){
if(Q.rear==Q.front)//队满条件:队尾指针的再下一个位置是队头
    return false;
x=Q.data[Q.rear];//x插入对尾
Q.rear=(Q.rear+1)%MaxSize;//让rear指针循环往复
return true;
}

链式存储

//队列的链式实现
typedef struct{  //链式队列结点
  ElemType data;
  struct LinkNode *next;
}LinkNode;

typedef struct{   //链式队列
    LinkNode *front,*rear;
}LinkNodeQueue;

//初始化 带头节点
void InitQueue(LinkQueue &Q){
    Q.fronr=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
    Q,front->next=NULL;
}
//判空 Q.front==Q.rear

//初始化 不带头节点
void InitQueue(LinkQueue &Q){
    Q,front=NULL;
    Q.rear=NULL;
}
//判空 Q.front==NULL

//入队(带头节点)
void EnQueue(LinkNodeQueue &Q,ElemType x){
    LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
    s->data=x;
    s->next=NULL;//插入到队尾,所以连接NULL
    Q,rear->next=s;
    Q.rear=s;//rear指向新的表尾节点
}

//入队(不带头节点)
void EnQueue(LinkNodeQueue &Q,ElemType x){
    LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
    s->data=x;
    s->next=NULL;//插入到队尾,所以连接NULL
    if(Q.front == NULL){  //在空队中插入第一个元素
        Q.front=s;//修改对头队尾指针
        Q.rear=s;
    }else{
    Q,rear->next=s;
    Q.rear=s;//rear指向新的表尾节点
    }
}
//出队(带头节点)
bool DeQueue(LinkNodeQueue &Q,ElemType &x){
 if(Q.front==Q.rear)
     return false;
 LinkNode *p=Q.front->next;//指向头结点的后面一个节点即要删除的节点
 x=p->data;//x返回队头元素
 Q.front->next=p->next;
 if(Q.rear==p)//此次是最后一个节点出队
     Q.rear=Q.front;
 free(p);
 return true;
}
//出队(不带头节点)
bool DeQueue(LinkNodeQueue &Q,ElemType &x){
 if(Q.front==Q.rear)
     return false;
 LinkNode *p=Q.front;//指向头结点的后面一个节点即要删除的节点
 x=p->data;//x返回队头元素
 Q.fron=p->next;
 if(Q.rear==p)//此次是最后一个节点出队
    Q,front=NULL;
    Q.rear=NULL;
 free(p);
 return true;
}

 队列的应用:树的层次遍历、图的广度遍历,多个进程抢占系统资源时先来先服务 eg:数据缓冲区

特殊矩阵的压缩存储

栈在表达式求值中的应用

栈在递归中的应用

适合用递归算法解决:可以把原始问题转换为属性相同,但规模较小的问题

实现递归算法需要注意:(1)递归表达式(2)递归出口

每进入一层递归,就将递归调用所需信息压入栈顶

每退出一层递归,就从栈顶弹出相应信息

缺点:效率低,太多层递归可能会导致栈溢出;可能包含很多重复计算

//计算正整数 n!
int factoral(int n){
  if(n==0 || n==1)
      return 1;
  else
      return n*factoral(n-1);
}
int main(){
     int x=factoral(10);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值