链式栈与链式队列

链式栈

定义

链式栈(Linked Stack)是一种基于链表实现的栈(Stack)数据结构。栈是一种具有特定限制条件的线性数据结构,其中元素的插入和删除操作只能在一端进行,该端称为栈顶(Top)。链式栈通过使用链表来存储元素,每个节点包含一个数据元素和一个指向下一个节点的指针。

特点

  1. 动态大小:链式栈的大小可以根据需要进行动态调整,不受固定大小的限制。链表结构充分利用了内存空间,可以灵活地增加或删除节点,从而适应不同的数据规模。

  2. 堆内存分配:链式栈的节点是通过堆内存动态分配而成的,而不是通过数组进行连续存储。这意味着链式栈可以处理更大的数据量,不会受到栈空间大小的限制。

  3. 添加和删除操作效率高:由于链式栈采用了链表结构,插入和删除操作只需要调整节点的指针,时间复杂度为O(1)。因此,无论是入栈还是出栈操作,都能够在常数时间内完成。

代码实现

节点描述

typedef struct LNode {
	int val;
	LNode* next;
}LNode;

栈描述

typedef struct LinkStack {
	LNode* head;
	int size;
}LinkStack;

初始化

void InitStack(LinkStack* slink) {
	assert(slink != NULL);
	slink->head = NULL;
	slink->size = 0;
}

创建节点

LNode* CreatNode(int val) {
	LNode* p = (LNode*)malloc(sizeof(LNode));
	assert(p != NULL);
	p->val = val;
	p->next = NULL;
	return p;
}

判空

bool IsEmpty(LinkStack* slink) {
	return slink->size == NULL;
}

入栈

bool Push(LinkStack* slink, int val) {
	assert(slink != NULL);
	LNode* p = CreatNode(val);
	p->next = slink->head;
	slink->head = p;
	slink->size++;
	return true;
}

出栈

bool Pop(LinkStack* slink) {
	if (IsEmpty(slink)) {
		return false;
	}
	else {
		LNode* p = slink->head;
		slink->head = p->next;
		free(p);
		return true;
	}
}

获取栈顶元素

bool GetTop(LinkStack* slink,int* pval) {
	if (IsEmpty(slink)) {
		*pval = 0;
		return false;
	}
	else {
		*pval = slink->head->val;
		return true;
	}
}

获取栈中有效元素个数

int GetSize(LinkStack* slink) {
	return slink->size;
}

清空栈

void ClearStack(LinkStack* slink) {
	LNode* p = slink->head;
	while (p->next != NULL) {
		p->val = 0;
		p = p->next;
	}
}

销毁栈

void DestoryStack(LinkStack* slink) {
	while (Pop(slink));
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
typedef struct LNode {
	int val;
	LNode* next;
}LNode;
typedef struct LinkStack {
	LNode* head;
	int size;
}LinkStack;
LNode* CreatNode(int val) {
	LNode* p = (LNode*)malloc(sizeof(LNode));
	assert(p != NULL);
	p->val = val;
	p->next = NULL;
	return p;
}
void InitStack(LinkStack* slink) {
	assert(slink != NULL);
	slink->head = NULL;
	slink->size = 0;
}
bool IsEmpty(LinkStack* slink) {
	return slink->size == NULL;
}
bool Push(LinkStack* slink, int val) {
	assert(slink != NULL);
	LNode* p = CreatNode(val);
	p->next = slink->head;
	slink->head = p;
	slink->size++;
	return true;
}
bool Pop(LinkStack* slink) {
	if (IsEmpty(slink)) {
		return false;
	}
	else {
		LNode* p = slink->head;
		slink->head = p->next;
		free(p);
		return true;
	}
}
bool GetTop(LinkStack* slink,int* pval) {
	if (IsEmpty(slink)) {
		*pval = 0;
		return false;
	}
	else {
		*pval = slink->head->val;
		return true;
	}
}
int GetSize(LinkStack* slink) {
	return slink->size;
}
void ClearStack(LinkStack* slink) {
	LNode* p = slink->head;
	while (p->next != NULL) {
		p->val = 0;
		p = p->next;
	}
}
void DestoryStack(LinkStack* slink) {
	while (Pop(slink));
}

链式队列

定义

链式队列是一种队列,其元素使用链表结构存储,每个节点包含存储的数据和指向下一个节点的指针。链式队列的队首和队尾分别由链表的头节点和尾节点来表示。

特点

  1. 动态大小: 链式队列的大小(元素个数)可以根据需要动态调整,不像顺序队列有固定的容量限制。这使得链式队列可以灵活地处理不同规模的数据。

  2. 无需搬移元素: 在链式队列中进行入队和出队操作不需要搬移元素。在链表结构中,新元素的入队只需要简单地创建一个新节点,并更新队尾指针,而出队只需要将头节点移除,并更新队首指针。这使得链式队列的入队和出队操作的时间复杂度都是 O(1)。

  3. 内存动态管理: 链式队列通过动态分配和释放内存来管理队列的元素,可以更加灵活地利用内存资源,避免了静态数组可能出现的内存浪费问题。

  4. 容易扩展: 链式队列支持动态大小,当需要更多的空间时,可以很容易地添加新的节点来扩展队列。相比之下,顺序队列的扩展则需要重新分配更大的静态数组,并搬移现有元素,较为繁琐。

代码实现

节点描述

typedef struct LNode {
	int val;
	LNode* next;
}LNode;

队列描述

typedef struct LinkQueue {
	LNode* head;
	LNode* tail;
	int size;
}LinkQueue;

初始化

void InitQueue(LinkQueue* queue) {
	assert(queue!= NULL);
	queue->head = queue->tail = NULL;
	queue->size = 0;
}

创建节点

LNode* CreatLNode(int val) {
	LNode* p = (LNode*)malloc(sizeof(LNode));
	assert(p != NULL);
	p->val = val;
	p->next = NULL;
	return p;
}

判空

bool IsEmpty(LinkQueue* queue) {
	return queue->size == 0;
}

入队

bool PushQueue(LinkQueue* queue, int val) {
	assert(queue != NULL);
	LNode* p = CreatLNode(val);
	if (queue->tail == NULL) {
		queue->tail = queue->head = p;
	}
	else {
		queue->tail->next = p;
		queue->tail = p;
	}
	queue->size++;
	return true;
}

出队

bool PopQueue(LinkQueue* queue) {
	if (IsEmpty(queue)) {
		return false;
	}
	else {
		if (queue->size == 1) {
			queue->tail = queue->head = NULL;
		}
		else
		{
			LNode* p = queue->head;
			queue->head = p->next;
			free(p);
		}
		queue->size--;
		return true;
	}
}

获取队首元素

bool GetHead(LinkQueue* queue, int* pval) {
	if (IsEmpty(queue)) {
		*pval = 0;
		return false;
	}
	else {
		*pval = queue->head->val;
		return true;
	}
}

获取队列中有效元素个数

int GetSize(LinkQueue* queue) {
	return queue->size;
}

清空队列

void ClearQueue(LinkQueue* queue) {
	LNode* p = queue->head;
	while (p->next != NULL) {
		p->val = 0;
		p = p->next;
	}
}

销毁队列

void DestoryQueue(LinkQueue* queue) {
	while (PopQueue(queue));
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
typedef struct LNode {
	int val;
	LNode* next;
}LNode;
typedef struct LinkQueue {
	LNode* head;
	LNode* tail;
	int size;
}LinkQueue;
LNode* CreatLNode(int val) {
	LNode* p = (LNode*)malloc(sizeof(LNode));
	assert(p != NULL);
	p->val = val;
	p->next = NULL;
	return p;
}
void InitQueue(LinkQueue* queue) {
	assert(queue!= NULL);
	queue->head = queue->tail = NULL;
	queue->size = 0;
}
bool IsEmpty(LinkQueue* queue) {
	return queue->size == 0;
}
bool PushQueue(LinkQueue* queue, int val) {
	assert(queue != NULL);
	LNode* p = CreatLNode(val);
	if (queue->tail == NULL) {
		queue->tail = queue->head = p;
	}
	else {
		queue->tail->next = p;
		queue->tail = p;
	}
	queue->size++;
	return true;
}
bool PopQueue(LinkQueue* queue) {
	if (IsEmpty(queue)) {
		return false;
	}
	else {
		if (queue->size == 1) {
			queue->tail = queue->head = NULL;
		}
		else
		{
			LNode* p = queue->head;
			queue->head = p->next;
			free(p);
		}
		queue->size--;
		return true;
	}
}
bool GetHead(LinkQueue* queue, int* pval) {
	if (IsEmpty(queue)) {
		*pval = 0;
		return false;
	}
	else {
		*pval = queue->head->val;
		return true;
	}
}
int GetSize(LinkQueue* queue) {
	return queue->size;
}
void ClearQueue(LinkQueue* queue) {
	LNode* p = queue->head;
	while (p->next != NULL) {
		p->val = 0;
		p = p->next;
	}
}
void DestoryQueue(LinkQueue* queue) {
	while (PopQueue(queue));
}

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值