数据结构:栈和队列

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

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

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

栈的出入顺序遵从------后入先出的原则。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;
}
相关推荐
努力努力再努力wz6 分钟前
【Linux网络系列】:网络+网络编程(UDPsocket+TCPsocket)
java·linux·c语言·开发语言·数据结构·c++·centos
又是忙碌的一天7 分钟前
八大排序之:冒泡排序、快速排序和堆排序
数据结构·算法·排序算法
hkhkhkhkh1238 分钟前
Linux 内核三大核心结构体详解(驱动开发视角)
linux·数据结构·驱动开发·字符设备
一直都在57225 分钟前
数据结构入门:哈希表和树结构
数据结构·算法·散列表
Lv11770081 小时前
Visual Studio 中的 ArrayList数组 和 List数组
数据结构·笔记·c#·list·visual studio
王璐WL1 小时前
【数据结构】栈和队列及相关算法题
数据结构·算法
LYFlied1 小时前
【每日算法】LeetCode138. 随机链表的复制
数据结构·算法·leetcode·链表
zore_c1 小时前
【C语言手撕算法】LeetCode-142. 环形链表 II(C语言)
c语言·数据结构·算法·leetcode·链表·推荐算法
hnjzsyjyj7 小时前
东方博宜OJ 2190:树的重心 ← 邻接表 or 链式前向星
数据结构·链式前向星·树的重心
ChoSeitaku9 小时前
NO15数据结构选择题考点|线性表|栈和队列|串
数据结构