数据结构C语言版清华大学严蔚敏(学习笔记总结3,代码在下面)——栈和队列、进栈出栈、栈空、入队、出队、循环队列(前面是笔记方便理解,最下面有详细代码)

数据结构C语言版清华大学严蔚敏(学习笔记总结2,代码在下面)——串和数组、矩阵存储、压缩矩阵、转置矩阵、对称矩阵、广义表、稀疏矩阵(前面是笔记方便理解,最下面有详细代码)_玛卡巴卡的博客-CSDN博客

1、栈的顺序存储

//-----栈的顺序存储表示------
typedef struct {
    SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;

2、基本操作

//------基本操作-----------
Status InitStack(SqStack *S){
	//构造一个空栈
	(*S).base =(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
	if(!(*S).base) exit(OVERFLOW);
	(*S).top =(*S).base;
	(*S).stacksize =STACK_INIT_SIZE;
	return OK;
}

//2
Status DestroyStack(SqStack *S){
	//销毁一个栈
	free( (*S).base);//释放表
	(*S).top =NULL;
	(*S).base =NULL;
	(*S).stacksize =0;
	return OK;
}

//3,
Status ClearStack(SqStack *S){
	//设置表为空
	(*S).top =(*S).base;//指向栈底
	return OK;
}

//4
Status StackEmpty(SqStack S){
	//是否为空
	if(S.top == S.base)
		return TRUE;
	else
		return FALSE;
}

//5
int StackLength(SqStack S){
	//返回栈的长度
	 return S.top-S.base;
}
//6
Status GetTop(SqStack S,SElemType *e){
	//如栈不空,返回栈顶元素
	if(S.top == S.base) 
		return ERROR;
	*e =*(S.top-1); //返回栈顶元素
	return OK;
}
//7
Status Push(SqStack *S,SElemType e){
	//入栈操作

	//判断栈满
	if( (*S).top-(*S).base >(*S).stacksize){
		(*S).base =(SElemType *)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!(*S).base) exit(OVERFLOW);

		(*S).top =(*S).base+(*S).stacksize;//重新定位栈顶指针
		(*S).stacksize+=STACKINCREMENT;
	}
	*( (*S).top )++ =e; //先插入,栈顶指针在+1
	return OK;
}
//8
Status Pop(SqStack *S,SElemType *e){
	//出栈操作

	//判断是否为空
	if((*S).top ==(*S).base) return ERROR;

	*e= *--(*S).top;//先栈顶指针-1,在取元素
	return OK;
}
//9
 Status StackTraverse(SqStack S,Status(*visit)(SElemType))
 { // 从栈底到栈顶依次对栈中每个元素调用函数visit()
   
   while(S.top>S.base)
     visit(*S.base++);
   printf("\n");
   return OK;
 }

3、队列的链式存储结构

//-----单链队列---队列的链式存储结构
typedef struct QNode{
     QElemType data;
     struct QNode *next;
}QNode, *QueuePtr;
typedef struct {
    QueuePtr front; //队头指针
    QueuePtr rear;  //队尾指针
}LinkQueue;

4、基本操作代码

//--------基本操作-----
//1
Status InitQueue(LinkQueue *Q){
	//构造一个空队列
	(*Q).front =(QueuePtr)malloc(sizeof(QNode));//生成头结点
	if(!(*Q).front) exit(OVERFLOW);

	(*Q).front->next =NULL; //头结点的指针域指向空
	(*Q).rear =(*Q).front;

	return OK;
}
//2
Status DestroyQueue(LinkQueue *Q){
	//销毁一个队列
	while((*Q).front){ //从队头释放资源
		(*Q).rear =(*Q).front->next;
		free( (*Q).front);
		(*Q).front =(*Q).rear;
	}
	return OK;
}

//3
Status ClearQueue(LinkQueue *Q){
	QueuePtr p,q; 
	
	p =(*Q).front->next; //指向队列的第一个结点
	while(p){ //从第一个结点释放资源
		q =p->next;
		free( p);
		p =q;
	}
	(*Q).front->next=NULL;
	(*Q).rear =(*Q).front;//为空的条件
	return OK;
}
//4
Status QueueEmpty(LinkQueue Q){
	if(Q.front == Q.rear)
		return OK;
	else
		return ERROR;
}
//5
int QueueLength(LinkQueue Q){
	int j=0;
	QueuePtr p =Q.front;
	while(p !=Q.rear){ //从队头直到和队尾相同时结束
		j++;
		p =p->next;
	}
	return j;
}
//6
Status GetHead(LinkQueue Q,QElemType *e){
	//返回队头元素

   QueuePtr p;
	//判断不为空
   if(Q.front == Q.rear)
     return ERROR;

   p =Q.front->next;
   *e =p->data;
   return OK;
}

//7
/*
	算法思想:
	1,开辟一个新结点p,为新结点的数据域和指针域分别赋值
	2,将新结p链接到队尾后,即把队尾结点的指针域指向新的结点p
	3,将尾指针指向p
*/
Status EnQueue(LinkQueue *Q,QElemType e){
	//插入元素
   QueuePtr p=(QueuePtr)malloc(sizeof(QNode)); //申请结点
   if(!p)
     exit(OVERFLOW);
   p->data=e;
   p->next=NULL;
   //在队尾插入
   (*Q).rear->next=p;
   (*Q).rear=p;
   return OK;
}
//8,
/*
	算法思想:
	1,判断队列不为空
	2,使待删除p指向队头的第一个结点,在删除前还需要保存该结点的信息。
	3,根据队列的操作逻辑定义,把队头结点的指针域指向p的下一个结点。
	4,判断待删除p是否指向了队尾结点,如果指向了队尾,则把队尾指针指向队头指针
*/
Status DeQueue(LinkQueue *Q,QElemType *e){
	QueuePtr p; 
	
	if((*Q).front ==(*Q).rear) return ERROR;

	p =(*Q).front->next;//待删除结点p
	*e =p->data;
	
	(*Q).front->next =p->next;

	if((*Q).rear ==p){//特殊判断,当待删除的结点是最后一个时,需要特殊处理。
		(*Q).rear =(*Q).front;
	}
	free(p);
	return OK;
}
Status QueueTraverse(LinkQueue Q,void(*vi)(QElemType))
 { 
   QueuePtr p;
   p=Q.front->next;
   while(p)
   {
     vi(p->data);
     p=p->next;
   }
   printf("\n");
   return OK;
 }

5、非循环队列的顺序存储结构之一

#define QUEUE_INIT_SIZE 10 //初始分配量
#define QUEUE_INCREMENT 5 //分配增量
typedef struct {
    QElemType *base; //初始化时动态分配的存储空间
    int rear; //尾指针,队列不为空时,指向数组元素下一个位置(存放的是数组的下标)
    int queuesize; //当前分配的空间大小
}SQueue;

6、非循环队列的顺序存储结构之二

#define QUEUE_INIT_SIZE 10 //初始分配量
#define QUEUE_INCREMENT 5 //分配增量
typedef struct {
    QElemType *base; //初始化时动态分配的存储空间
    int front; //头指针,若队列不为空只想队头元素。
    int rear; //尾指针,队列不为空时,指向数组元素下一个位置(存放的是数组的下标)
    int queuesize; //当前分配的空间大小
}SQueue;

7、使用循环队列

 #define MAXQSIZE 100 // 最大队列长度
 typedef struct
 {
   QElemType *base; // 初始化的动态分配存储空间 
   int front; // 头指针,若队列不空,指向队列头元素 
   int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置 
 }SqQueue;

8、循环队列的顺序结构基本操作

//--------循环队列的基本操作----------
//1,初始化一个队列
Status InitQueue(SqQueue *Q)
{
	(*Q).base =(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
	if(!(*Q).base) exit(OVERFLOW);

	(*Q).front =(*Q).rear =0;
	return OK;
}

//2销毁
Status DestroyQueue(SqQueue *Q)
{	
	if((*Q).base)
		free((*Q).base);
	(*Q).front =(*Q).rear=0;
	(*Q).base =NULL;
	return OK;
}
//3清空
Status ClearQueue(SqQueue *Q)
{
	(*Q).front =(*Q).rear =0;
	return OK;
}

//4是否为空
Status QueueEmpty(SqQueue Q){
	if( Q.rear ==Q.front)
		return TRUE;
	else
		return FALSE;
}

//5队列的长度
int QueueLength(SqQueue Q)
{
	return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}

//6获取队头元素
Status GetHead(SqQueue Q,QElemType *e)
{
	//判断不为空,这里舍弃一个空间
	if( Q.rear ==Q.front)
		return ERROR;
	*e =Q.base[Q.front];
	return OK;
}

//7插入操作
/*
	算法思想:
	1,判断队列不为满,(Q.rear+1)%MAXQSIZE ==Q.front
	2,在队尾插入新元素
	3,队尾指针加1
*/
Status EnQueue(SqQueue *Q,QElemType e)
{
	if( ((*Q).rear+1)%MAXQSIZE ==(*Q).front)
		return ERROR;
	(*Q).base[(*Q).rear] =e;
	(*Q).rear =((*Q).rear+1)%MAXQSIZE;
	return OK;
}

//8删除操作
/*
	算法思想:
	1,先判断循环队列不为空。
	2,删除队头指针的数据元素,在此之前保存待删除元素的信息。
	3,队头指针加1。
*/
Status DeQueue(SqQueue *Q,QElemType *e)
{
	if((*Q).rear ==(*Q).front)
		return ERROR;
	*e =(*Q).base[(*Q).front];
	(*Q).front =((*Q).front+1)%MAXQSIZE;
	return OK;
}

//9输出
Status QueueTraverse(SqQueue Q,void(*visit)(QElemType))
{
	int i;
	i =Q.front;
	while(i!=Q.rear){
		(*visit)( Q.base[i] );
		 i=(i+1)%MAXQSIZE;
   }
   printf("\n");
   return OK;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玛卡巴卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值