栈和队列

特点:仅在表的一端进行插入和删除的线性表。允许插入、删除的一端是栈顶,另一端是栈底。后进先出

顺序栈

定义
#define MAXSSIZE  100   
typedef  struct{
	datatype data[MAXSSIZE];
 	int top;  /*栈顶指针*/
}SeqStack; 
基本操作
1. 初始化
SeqStack *Init_SStack(){ 
	SeqStack *s; /*定义一个指向顺序栈的指针*/
  	s = malloc(sizeof(SeqStack));
  	if(s) s->top = -1;  /*空栈标志*/
  	return s;
}
2. 判空栈
int Empty_SStack(SeqStack *s){   /*判断top值是否与空栈标志相等*/
	if(s->top == -1)  return 1;
    else return 0;  
}
3. 入栈
int Push_SStack(SeqStack *s, datatype e){
	if(s->top == MAXSSIZE-1)  return 0; 
   	else{  
   		s->top++;
        s->data[s->top]=e;
        return 1;
	}
}
4. 出栈
int  Pop_SStack(SeqStack *s, datatype *e){  
	if(Empty_SStack(s))  return 0; 
	else{   
		*e = s->data[s->top];
		s->top--; 
		return 1;
	}
}
两栈共享空间

使用一个数组来存储这两个栈,其中栈1的栈底设在该数组的始端,栈2的栈底设在该数组的尾端,两个栈都从各自的端点向数组中部延伸,只有在两个栈的栈顶在数组空间的某一位置相遇时才会产生“上溢”。
栈1在入栈操作时栈顶指针top1++,出栈操作时top1–;栈2在入栈操作时栈顶指针top2–,出栈操作时top2++。

链栈

定义
 typedef struct node{ 
 	datatype data;
  	struct node *next;
}StackNode, *LinkStack;
LinkStack top ;    /*top为栈顶指针*/


链栈指针指向栈底方向

基本操作
1. 初始化
LinkStack Init_LinkStack(){
	return NULL;
}
2. 判空栈
int Empty_LinkStack(LinkStack top){
	if(top === NULL) return 1;
	else return 0;
}
3. 入栈
LinkStack Push_LinkStack(LinkStack top, datatype e){
	StackNode *s;
	s = malloc(sizeof(StackNode));
	s->data = e;
	s->next = top;
	top = s;
	return top;
}
4. 出栈
LinkStack Pop_LinkStack(LinkStack top, datatype *e){  
	StackNode  *p;
    if(top == NULL) return NULL; 
    else{ 
   		*e = top->data;
      	p = top;
      	top = top->next;
      	free (p);
      	return  top;
    }
}

栈的应用

1. 递归

当某个问题面对不同的数据规模,其解决方案类同,可考虑采用递归定义。
递归函数执行时,都遵循“后调用先返回”的原则。为了保证递归函数能正确执行,系统会设立一个“递归工作栈”,将这些活动记录保存在系统的“递归工作栈”中,每递归调用一次,就要在栈顶为其建立一个新的活动记录,一旦本次调用结束,则将当前栈顶活动记录出栈,根据获得的返回地址信息返回到本次的调用处(断点)继续执行后续程序。

/*求n的阶乘n!*/
int fac(int n){  
	if(n == 0) return 1;
    else return(n * fac(n-1));
}
2. 数制转换

所转换的8进制数是按低位到高位的顺序来产生,而数据输出时都是从高位到低位,正好与计算过程相反,具有“后进先出”的特性,所以可以将转换过程中得到的每一位8进制数都按序进栈保存,转换完毕后再依次出栈就能得到所要的转换结果。

3. 括号匹配




队列

特点:插入操作在表的一端进行,删除操作在表的另一端进行。队尾插入 ,队头删除。先进先出

顺序队

定义
define MAXQSIZE 100   
typedef struct{ 
	datatype   data[MAXQSIZE];  
     int  front , rear;  
    }SeqQue;
SeqQue  *sq;  /*定义指向队列的指针变量*/
  • 队列的数据区为:sq->data[0]……sq->data[MAXQSIZE -1]
  • 队头指针:sq->front
  • 队尾指针:sq->rear
  • 置空队:sq->front=sq->rear=-1;
  • 入队:sq->rear++; sq->data[sq->rear]=a;
  • 出队指令:sq->front++; a=sq->data[sq->front];
  • 队中元素个数:n=(sq->rear)-(sq->front);
  • 队列的移动有什么特点:整个队列向数组下标较大的方向移动→单向移动性假溢出循环队列(头尾相接的循环结构): 用"%"(取余)操作来实现。front=rear表示队满或队空情况。
sq->rear = (sq->rear+1) % MAXQSIZE; /*入队*/
sq->front = (sq->front+1) % MAXQSIZE; /*出队*/

链队

特点:一般用单链表结构来实现链队。 为单链表分别设置一个头指针和尾指针。

定义
typedef struct node{ 
	datatype data;
   	struct node *next; /*指针指向队尾*/
} QNode; 
typedef struct{ 
	QNode *front,*rear;
}LQueue;     
基本操作
1. 创建
 LQueue *Init_LQue(){  
 	LQueue *q;   /*定义一个指向链队的指针*/ 
 	QNode *p;    /*定义一个头结点*/
    q = malloc(sizeof(LQueue));  
    p = malloc(sizeof(QNode));  
    p->next = NULL;  /*这是一个带头结点的空队列*/
    q->front = q->rear=p; /*指针和队列的两种存在,p及队列是蛋糕,q是上面的奶油*/
    return q; /*得到创建的队列的指针*/
 }
2. 入队
void In_LQue(LQueue  *q , datatype  e)
  {  QNode *p;
     p=malloc(sizeof(QNode)); 
     p->data=e;   
     p->next=NULL;
     q->rear->next=p;
     q->rear=p;    
  }
3. 出队
int Out_LQue(LQueue*q, datatype *e){
	QNode *p;  
   	if(Empty_LQue(q)){  
   		printf(“队空”)return 0; /*队空,出队失败*/
  	}      
  	else{ 
  		p = q->front->next; /*指针指向队尾*/
       	q->front->next = p->next;
      	*e = p->data;  /*队头元素放e中*/
       	free(p);
       	if (q->front->next == NULL) /*只剩头结点*/
           	q->rear = q->front; 
       	return 1;
  	}
} 

队列的应用

1. 键盘输入缓冲区的问题

在多任务系统中,当程序正在执行其它任务时,用户还可以从键盘上不断键入所要输入的内容。用户键入的内容不会在屏幕上立刻显示出来,直到当前正在工作的那个进程结束为止。
队列的特性可以保证输入字符先键入、先保存、先处理的要求,而循环队列结构又能有效地限制缓冲区的大小,并可避免假溢出问题。所以键盘输入缓冲区一般都采用循环队列这种数据结构。

2. 杨辉三角问题

因为上一行用来计算过的数据以后就不需要了,为了节省存储空间,可以利用循环顺序队列打印杨辉三角。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值