欢迎来到代码驿站!

C代码

当前位置:首页 > 软件编程 > C代码

C语言超详细讲解栈与队列实现实例

时间:2022-06-03 11:10:03|栏目:C代码|点击:

1.思考-1

为什么栈用数组来模拟比用链表来模拟更优一些?

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低,时间复杂度为O(n)。

2.栈基本操作的实现

2.1 初始化栈

void StackInit(stack*ps)
{
	assert(ps);
	ps->_a = (StackDate*)malloc(sizeof(StackDate) * 4);
	ps->_top = 0;
	ps->_capacity = 4;
}

2.2 入栈

void StackPush(stack*ps, StackDate x)
{
	assert(ps);
	if (ps->_top == ps->_capacity)
	{
		stack*tmp = (StackDate*)realloc(ps, sizeof(StackDate)*(ps->_capacity) * 2);
		if (NULL == tmp)
		{
			printf("realloc failed\n");
			exit(-1);
		}
		ps = tmp;
		ps->_capacity *= 2;
	}
	ps->_a[ps->_top] = x;
	ps->_top++;
}

2.3 出栈

void StackPop(stack*ps)
{
	assert(ps);
	assert(!StackIsEmpty(ps));
	--ps->_top;
}

注意: 出栈并不是真正意义上的删除数据,而是将_top向后挪动了一个位置。

2.4 获取栈顶数据

StackDate StackTop(stack*ps)
{
	assert(ps);
	assert(!StackIsEmpty(ps));
	return ps->_a[ps->_top - 1];
}

2.5 获取栈中有效元素个数

int StackSize(stack*ps)
{
	assert(ps);
	return ps->_top;
}

2.6 判断栈是否为空

bool StackIsEmpty(stack*ps)
{
	assert(ps);
	return ps->_top == 0;
}

2.7 销毁栈

void StackDestory(stack*ps)
{
	assert(ps);
	free(ps->_a);
	ps->_a = NULL;
	ps->_top = ps->_capacity = 0;
}

3.测试

3.1 测试

void test()
{
	//插入数据
	stack  st;
	StackInit(&st);
	StackPush(&st,1);
	StackPush(&st,2);
	StackPush(&st,3);
	StackPush(&st,4);
	while (!StackIsEmpty(&st))
	{
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");


	//获取栈顶数据
	StackPush(&st, 1);
	StackPush(&st, 2);
	printf("%d ", StackTop(&st));
	printf("\n");

	
	//栈中有效数据个数
	printf("%d ", StackSize(&st));

	
	//销毁栈
	StackDestory(&st);
}

3.2 测试结果

4.思考-2

为什么队列用链表模拟比数组模拟更加合适?

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价小。

5.队列的基本操作实现

5.1 初始化队列

void QueueInit(Queue*pq)
{
	assert(pq);
	pq->_head = pq->_tail = NULL;
}

5.2 队尾入队列

void QueuePush(Queue*pq, QueueDate x)
{
	assert(pq);
	QueueNode*newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (NULL == newnode)
	{
		printf("malloc failed\n");
		exit(-1);
	}
	newnode->next = NULL;
	newnode->val = x;
	if (NULL == pq->_tail)
	{
		pq->_head = pq->_tail = newnode;
	}
	else
	{
		pq->_tail->next = newnode;
		pq->_tail = newnode;
	}
}

5.3 队头出队列

void QueuePop(Queue*pq)
{
	assert(pq);
	assert(!QueueIsEmpty(pq));
	if (NULL == pq->_head->next)
	{
		free(pq->_head);
		pq->_head = pq->_tail = NULL;
		
	}
	else
	{
		QueueNode*next = pq->_head->next;
		free(pq->_head);
		pq->_head = next;
	}
}

代码分析:

5.4 队列中有效元素的个数

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

5.5 判断队列是否为空

bool QueueIsEmpty(Queue*pq)
{
	assert(pq);
	return pq->_head == NULL;
}

5.6 获取队头数据

QueueDate QueueFront(Queue*pq)
{
	assert(pq);
	assert(!QueueIsEmpty(pq));
	return pq->_head->val;
}

5.7 获取队尾的数据

QueueDate QueueBack(Queue*pq)
{
	assert(pq);
	assert(!QueueIsEmpty(pq));
	return pq->_tail->val;
}

5.8 销毁队列

void QueueDestory(Queue*pq)
{
	assert(pq);
	while (pq->_head)
	{
		if (pq->_head == pq->_tail)
		{
			free(pq->_head);
			pq->_head = pq->_tail = NULL;
		}
		else
		{
			QueueNode*next = pq->_head->next;
			free(pq->_head);
			pq->_head = next;
		}
	}
}

注意: 和队头出队列一样分析。

6.测试

6.1 测试

void test1()
{
	//插入数据
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);


	//有效数据的个数
	printf("%d ", QueueSize(&q));
	printf("\n");


	//获取队头数据
	printf("%d",QueueFront(&q));
	printf("\n");


	//获取队尾数据
	printf("%d",QueueBack(&q));
	printf("\n");


	//出队
	QueuePop(&q);
	while (!QueueIsEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");


	//销毁
	QueueDestory(&q);
	printf("\n");
}

6.2 测试结果

今天数据结构栈与队列的相关知识点就分享到这里了,感谢你的浏览,如果对你有帮助的话,可以给个关注,顺便来个赞。

上一篇:c++回溯法解决1到9之间插入加减或空使运算结果为100

栏    目:C代码

下一篇:没有了

本文标题:C语言超详细讲解栈与队列实现实例

本文地址:http://www.codeinn.net/misctech/203662.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有