栈与队列的实现

栈与队列

定义

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。


因为它的压栈和出栈操作我们可以抽象为尾插和尾删,因此我们可以利用数组来实现这一点,为什么不用链表呢?

这里有一些原因:

1.数组物理空间是连续的,方便使用下标随机访问

2.CPU高速缓存命中率会更高

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 栈顶的位置
	int capacity;	// 容量
}ST;

实现

初始化与销毁
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->capacity = ps->top = 0;
	ps->a = NULL;
}
入队列(尾插)与出队列(尾删)
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//是否扩容
	if (ps->capacity == ps->top)
	{
		int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		ps->a = (STDataType*)realloc(ps->a, NewCapacity * sizeof(STDataType));
		assert(ps->a);
		ps->capacity = NewCapacity;
	}

	//类似顺序表尾插
	ps->a[ps->top] = x;
	ps->top++;

}
void StackPop(ST* ps)
{
	//类似尾删
	assert(ps);
	assert(ps->top > 0);//top只是位置 其位置大于零就说明栈内还有元素
	ps->top--;//覆盖即可
}
判断是否为空
bool StackEmpty(ST* ps)
{
	assert(ps);
	if (ps->top > 0)
	{
		return false;
	}
	else
	{
		return true;
	}
}

栈内元素个数
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}
栈顶元素
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1];//top位置是没有数据的 top减一取到栈顶元素
}

队列

定义

队列(Queue)是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。


我们可以用单链表来实现队列,让数据从尾部进从头部出,即插入数据为尾插,删除数据为头删

利用单链表,队列里面有队尾入和队头出,因此定义两个结构体指针,把它俩放在一个新的结构体中方便调用

可以加哨兵位,但是意义不太大,在某种地方哨兵位置有奇效,比如:分割链表、带头双向循环等,可以防止空指针的出现。

typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;

实现

初始化与销毁
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}
void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;//定义一个cur
	while (cur)//遍历
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;//最后把两个指针都置为初始状态c
}
入队列(尾插)与出队列(头删)
void QueuePush(Queue* pq, QDataType x)//尾插
{
	assert(pq);
	QNode* newnode = (QDataType*)malloc(sizeof(QDataType));
	newnode->data = x;
	newnode->next = NULL;
	if (pq->head == NULL)//如果队列为空
	{
		//其实这个时候head和tail均为空,这里是为了意外出现
		assert(pq->tail == NULL);
		//插入新结点
		pq->head=pq->tail = newnode;
	}
	else//尾插
	{
		pq->tail->next = newnode;
		
		pq->tail = newnode;//尾就变了
	}
}
void QueuePop(Queue* pq)//头删
{
	assert(pq);
	if (pq->head->next == NULL)//如果只有一个结点
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}

	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
判断是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	//if (pq->head == NULL && pq->tail==NULL)
	//{
	//	return true;
	//}
	//else
	//{
	//	return false;
	//}
	return pq->head == NULL;//一句代码解决以上...
}
队列内数据个数
size_t QueueSize(Queue* pq)
{
	assert(pq);
	size_t count = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		count++;
		cur = cur->next;
	}
	return count;
}
取队列头与队列尾的元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	return pq->head->data;
}
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail);
	return pq->tail->data;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值