浅谈栈与队列(C语言)

Posted 王不患吖吖吖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈栈与队列(C语言)相关的知识,希望对你有一定的参考价值。

栈的定义

栈同样是一种线性表,它的特性是插入元素必须从后面插入,删除元素也是从后面删除,进行数据删除和插入的一端称为栈顶,另一端是栈底。
压栈—就是插入元素
出栈—就是删除元素

它可以用数组实现也可以用链表实现


但是用数组实现更好,因为链表的插入和删除要进行遍历,而数组可以进行随机访问,从而时间复杂度更低。

栈的实现

前置

栈的元素需要表明容量,还有栈顶

typedef int SDType;
typedef struct Srack
{
	SDType* a;
	int top;
	int capacity;

}ST;

初始化栈

把元素置为空,栈顶在下标为0的位置

void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

栈的销毁

不再赘述

void StackDestrory(ST* ps)
{
	assert(ps);
	free(ps);
	ps=NULL;
	ps->capacity = ps->top = 0;
}

栈的插入

先判空,如果容量满了,进行增容,把栈顶元素进行赋值,再把栈顶指针加一

void StackPush(ST* ps, SDType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SDType* tmp = (SDType)realloc(ps->capacity, sizeof(SDType) * newCapacity);
		if (tmp == NULL)
		{
			printf("Realloc fail!\\n");
		}
		else
		{
			ps->a = tmp;
			ps->capacity = newCapacity;
		}
	}
	ps->a[ps->top] = x;
	ps->top++;
}

出栈的操作

栈顶指针减一即可

void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;

}

取栈顶元素

先进行判空,不空的话直接取出栈顶指针指向的元素

SDType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps -> a[ps->top - 1];
}

栈的大小

int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

判断栈是否为空

bool StackEmpty(ST* ps)
{
	return ps->top == 0;
}

队列的定义

队列只允许在一段进行插入操作,一段进行删除操作,在队尾进行插入,在队头进行删除

队列的基本操作

队列的初始化

我们在进行基本操作的时候要用到头指针和尾指针

void QueueInit(Queue* pq)
{
	assert(pq != NULL);
	pq->head = NULL;
	pq->tail = NULL;


}

队列的销毁

将临时指针cur被赋值为head,保存下一个,遍历进行删除,最后把头指针和尾指针进行free

void QueueDestroy(Queue* pq)
{
	assert(pq != NULL);
	QueueNode* cur = pq->head;
	QueueNode* next = cur->next;
	while (cur)
	{
		free(cur);
		cur = next;
		next = next->next;
	}
	pq->head = pq->tail = NULL;
}

队列的插入

队列只能从队尾查,如果开始的时候队头和队尾重合,那就直接进行插入,
如果不,那就找到尾,在尾后边进行插入

void QueuePush(Queue* pq,QDataType x)
{
	assert(pq);
	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
	newNode->data = x;
	newNode->next = NULL;
	if (pq->head == NULL)
	{
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}
}

队列的删除

很简单,删除队尾头元素,先保存下一个,再把队头复制给新的

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	QueueNode* NewHead = pq->head->next;
	free(pq->head);
	pq->head = NewHead;
	if (pq->head == NULL)
	{
		pq->tail = NULL;
	}
}

队列的判空

是否队头指向空

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

取出队头元素

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}

取出队尾元素

先判空

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;

}

队列的大小

直接遍历就行

int QueueSize(Queue* pq)
{
	assert(pq);
	int n = 0;
	QueueNode* cur = pq->head;
	while (cur)
	{
		cur = cur->next;
		n++;
	}
	return n;
}

点个赞把

以上是关于浅谈栈与队列(C语言)的主要内容,如果未能解决你的问题,请参考以下文章

浅谈栈与队列(C语言)

浅谈栈与队列(C语言)

浅谈栈帧(一)

浅谈栈

算法 - 栈与队列(C 语言实现)

浅谈栈帧