数据结构 3之 栈与队列

本文详细介绍了栈和队列的两种主要实现方式——顺序结构和链式结构,包括链栈、链队列、顺序栈和顺序队列的初始化、入栈/入队、出栈/出队等操作。讨论了它们的内存管理、判空判满策略,并给出了C语言的实现示例。此外,还提到了循环队列的概念及其应用。
摘要由CSDN通过智能技术生成

stack



链栈 / 链队列 没有 size限制,顺序栈 / 顺序队列有 size限制。
链系出入需要free,malloc,顺序系则是需要出判空,入判满。
如果有设置标志位 或 实时size,那么每一次出入操作完之后都要及时更新。
链栈的指针方向是从栈顶指向栈底。
链队列的指针方向是从队头指向队尾。



分为 顺序栈 和 链栈
只能在表尾 / 栈顶进行操作
表尾 ============================ 表头
top ============================ base
栈顶 ============================ 栈底
数组[n] ========================== 数组[0]

  • 顺序栈
    top指向当前栈顶元素的下一个位置。
    恶趣味
#define STACK_INIT_SIZE	100
#define STACKINCREMENT 	10

typedef struct
{
	SElemType *base;
	SElemType *top;
	int stacksize;          // 最大size,而top指向实时值
} SqStack;

Status InitStack(SqStack &s)
{
	s.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if(!s.base)
	{
		return ERROR;
	}
	s.top = s.base;
	s.stacksize = STACK_INIT_SIZE;
	return OK;
}

Status GetTop(SqStack s,SElemType &e)
{
	if(s.top == s.base)
	{
		return FALSE;
	}
	e = *(s.top - 1);
	return OK;
}

Status Push(SqStack &s,SElemType e)
{
	if(s.top - s.base >= s.stacksize)
	{
		s.base = (SElemType *)realloc(sizeof(SElemType) * (NEW_SIZE))
		if(!s.base)
		{
			return ERROR;
		}
		s.top = s.base + s.size;	//s.top此时绝对位置一定要更新!!!
		s.size = NEW_SIZE;		//s.top此时绝对位置一定要更新!!!
	}	
	*(s.top) = e;
	s.top++;
	return OK;
}

Status Pop(SqStack &s,SElemType &e)
{
	if(s.top == s.base)
	{
		return ERROR;
	}
	e = *(s.top - 1);
	s.top--;
	return OK;
}
  • 链栈
    s.top ------------------------------------------------> s.base

大神

top指向栈顶,出栈入栈操作栈顶元素即可。
链的方向是从栈顶指向栈底。

typedef struct NodeType
{
	ElemType data;
	NodeType *next;
} NodeType,*LinkType;

typedef struct
{
	LinkType top;
	int size;
} Stack;

void InitStack(Stack &s)
{
	s.top = NULL;
	s.size = 0;
}

void DestroyStack(Stack &s)
{
	LinkType p;
	while(s.top)
	{
		p = s.top;
		s.top = s.top->next;
		free(p);
		s.size--;
	}
	free(&s);
}

void ClearStack(Stack &s)
{
	LinkType p;
	while(s.top)
	{
		p = s.top;
		s.top = p->next;
		free(p);
		s.size--;
	}
}

Status StackEmpty(Stack s)
{
	if(s.size)
	{
		return FALSE;
	}
	else
	{
		return TRUE;
	}
//也可以通过 ---- s.top是否为NULL ----来判空
}

Status Push(Stack &s,ElemType e)
{
	LinkType p;
	p = (LinkType)malloc(sizeof(NodeType));
	if(!p)
	{
		return ERROR;
	}
	p->data = e;
	p->next = s.top;
	s.top = p;
	s.size++;
	return OK;
}

Status Pop(Stack &s,ElemType &e)
{
	LinkType p;
	if(s.size == 0 || s.top == NULL)
	{
		return ERROR;
	}
	p = s.top;
	e = p->data;
	s.top = p->next;
	free(p);
	s.size--;
	return OK;
}

void StackTraverse(Stack &s,Status (*Visit)(ElemType e))
{
	LinkType p;
	p = s.top;
	while(p)
	{
		Visit(p->data);
		p = p->next;
	}
}	

队列

队列:分为链队列和顺序队列
先进先出
队头出,队尾进
阿达

  • 链队列

地方

存在头节点,即 q.front -> next 存放第一个元素。
q.rear 指向队尾元素,而不是指向队尾元素的下一个位置。

typedef struct QNode
{
	QElemType data;
	struct QNode *next;
} QNode,*QueuePtr;

typedef struct
{
	QueuePtr front;
	QueuePtr rear;
} LinkQueue;

Status InitQueue(LinkQueue &q)
{
	QueuePtr tmp;
	tmp = (QueuePtr)malloc(sizeof(QNode));
	if(!tmp)
	{
		return ERROR;
	}
	q.front = tmp;
	q.rear = tmp;
	q.front->next = NULL;
	return OK;
}

Status DestroyQueue(LinkQueue &q)
{
	while(q.front)
	{
		q.rear = q.front->next;
		free(q.front);
		q.front = q.rear;
	}
	return OK;
}

Status EnQueue(LinkQueue &q,QElemType e)
{
	QueuePtr tmp;
	tmp = (QueuePtr)malloc(sizeof(QNode));
	if(!tmp)
	{
		return ERROR;
	}
	tmp->data = e;
	tmp->next = q.rear->next;
	q.rear->next = tmp;
	q.rear = tmp;
	return OK;
}

Status DeQueue_1(LinkQueue &q,QElemType &e)
{
	// 不带头结点,即q.front 指向第一个队列元素
	if(q.front == NULL && q.rear == NULL)
	{
		return ERROR;
	}
	e = q.front->data;
	tmp = q.front->next;
	free(q.front);
	q.front = tmp;
	if(!tmp)
	{
		q.rear = NULL;
	}
	return OK;	
}

Status DeQueue_2(LinkQueue &q,QElemType &e)
{
	//带有头节点,q.front->next 指向队列里面第一个元素
	if(q.front == q.rear)
	{
		return ERROR;
	}
	p = q.front->next;
	e = p->data;
	q.front->next = p->next;
	if(q.rear == p)
	{
		q.rear = q.front;
	}
	free(p);
	return OK;
}
  • 循环队列
    利用取余实现数组的循环
    可以设置判满标志位,也可以设置在顺序队列中空出一位来判满
    下面采用的是在顺序队列中空出一位来判断
    注意判满条件,判空条件。采用tag标志位时还要及时更新tag。如果有size也要及时更新。
#define MAXQSIZE 100
typedef struct
{
	QElemType *base;
	int front;
	int rear;
}SqQueue;

Status InitQueue(SqQueue &q)
{
	q.base = (QElemType *)malloc(sizeof(QElemType ) * MAXQSIZE);
	if(!q.base)
	{
		return ERROR;
	}
	q.front = 0;
	q.rear = 0;
	return OK;
}

int QueueLength(SqQueue q)
{
	return ((q.rear - q.front + MAXQSIZE) % MAXQSIZE);
}

Status EnQueue(SqQueue &q,QElemType e)
{
	if((q.rear + 1) % MAXQSIZE == q.front)
	{
		return ERROR;
	}
	*(q.rear) = e;
	q.rear = (q.rear + 1) % MAXQSIZE;
	return OK;
}

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值