数据结构:栈和队列

栈:一种特殊的线性表,只能从固定的一端入数据和出数据。一般把出入数据的一端叫栈顶,另一端叫栈底。

压栈:把数据放入栈中,叫压栈/入栈/进栈。 压栈在栈顶。

出栈:把数据移除栈中,叫出栈。出栈也在栈顶。

栈的出入顺序遵从------后入先出的原则。LIFO(last in first out)。

上图压栈按照1234的顺序连续放,出的时候是4321。

栈的实现:

栈一般用链表和顺序表实现。不过一般用顺序表。因为插入删除都是从尾部操作,如果用链表,删尾要遍历,有点麻烦。顺序表就很方便插入删除了。

写一个栈主要实现栈的以下功能:

1.初始化和销毁栈

2.往栈中插入数据

3.从栈顶取出并删除数据

4.栈是否为空的判断

5.栈顶的数据是什么

6.栈中有效个数有多少

下面是stack.c文件,具体实现栈的各个功能。其他测试代码和头文件就不放了。

cpp 复制代码
void StackInit(Stack* ps)
{
	ps->_a = NULL;
	ps->_capacity = ps->_top = 0;
}

void StackPush(Stack* ps, STDataType data)
{
	assert(ps);
	if (ps->_capacity == ps->_top)
	{
		int newcapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
		STDataType* ptr = (STDataType*)malloc(sizeof(STDataType) * newcapacity);
		if (ptr == NULL)
		{
			perror("StackPush:malloc failed");
			exit(1);
		}
		ps->_a = ptr;
		ps->_capacity = newcapacity;
	}

	ps->_a[ps->_top] = data;
	ps->_top++;
}

void StackPop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	printf("%d\n", ps->_a[ps->_top - 1]);
	ps->_top--;
}

bool StackEmpty(Stack* ps)
{
	return ps->_top == NULL;
}

// 获取栈顶元素 
STDataType StackTop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps->_a[ps->_top - 1];
}


// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{
	return ps->_top;
}


// 销毁栈 
void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->_a);
	ps->_a = NULL;
	ps->_capacity = ps->_top = 0;
}

队列:一种特殊的线性表,只能从固定的一端入数据,从另一端出数据。遵循先入先出(FIFO)的原则。一般把出数据的一端叫队头,入数据的一端叫队尾。

队列要频繁的头删尾插,如果用顺序表,就要在删除时,不断地挪动后面的数。效率有点低。所以一般用链表实现。

理解原理以后,实现也很简单。

cpp 复制代码
void QueueInit(Queue* q)
{
	assert(q);
	q->_front = q->_rear = NULL;
}

void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* ptr = (QNode*)malloc(sizeof(QNode));


	ptr->_data = data;
	ptr->_next = NULL;

	if (q->_front == NULL)
	{
		q->_front = ptr;
		q->_rear = q->_front;
	}
	else
	{
		q->_rear->_next = ptr;
		q->_rear = q->_rear->_next;
	}
}

void QueuePop(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	printf("%d ", q->_front->_data);
	QNode* p = q->_front;
	q->_front = q->_front->_next;
	free(p);
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{
	return q->_front == NULL ? 1 : 0;
}

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	return q->_front->_data;
}

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));

	return q->_rear->_data;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
	assert(q);
	int count = 0;
	QNode* cur = q->_front;
	while (cur)
	{
		count++;
		cur = cur->_next;
	}
	return count;
}

// 销毁队列 
void QueueDestroy(Queue* q)
{
	assert(q);
	QNode* cur = q->_front;
	while (cur)
	{
		QNode* next = cur->_next;
		free(cur);
		cur = next;
	}
	q->_front = q->_rear = NULL;
}
相关推荐
刘马想放假3 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠4 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦10 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠11 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾11 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres82111 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q12 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒12 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
WL学习笔记12 天前
单项不带头不循环链表
数据结构·链表
小糯米60112 天前
JS 数组
数据结构·算法·排序算法