数据结构:栈和队列

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

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

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

栈的出入顺序遵从------后入先出的原则。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;
}
相关推荐
yi0116 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
禾小西9 小时前
Redis 数据结构:快速的 Redis 有哪些慢操作?
数据结构·数据库·redis
H.莓飛9 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有10 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
chenbingjie_c11 小时前
C++ STL 适配器:stack & queue,从 vector/list 到 deque 深度解析
数据结构·c++
垆边人似月.14 小时前
华为OD算法题:查找众数及中位数
数据结构·算法·leetcode
CoderYanger14 小时前
一轮复习——F.动态规划模型总结(入门篇)
java·开发语言·数据结构·算法·leetcode·职场和发展·动态规划
一只旭宝15 小时前
数据结构与算法复习手册:从写过,到讲清楚
开发语言·数据结构·c++·算法
All for pursuit.16 小时前
【动态规划-1】121.买卖股票的最佳时机
数据结构·c++·算法·leetcode·动态规划
Logic10117 小时前
C语言/数据结构位运算题解:异或XOR找出优秀项目组中的“独特编号“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质