栈和队列

栈的顺序存储

  • 利用数组模拟出 栈的陷阱后出的数据结构

栈的设计

栈的结构体

#define MAX 1024
struct SStack
{
	// 栈中数组
	void* data[MAX];
	
	// 栈大小
	int m_Size;
};
typedef void* SeqStack;

初始化栈

SeqStack init_SeqStack()
{
	struct SStack* myStack = malloc(sizeof(struct SStack));
	if (myStack == NULL)
	{
		return NULL;
	}

	memset(myStack->data, 0, sizeof(void*) * MAX);
	myStack->m_Size = 0;

	return myStack;
}

入栈

void push_SeqStack(SeqStack stack, void* data)
{
	// 本质 数组尾插
	if (stack == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	struct SStack* myStack = stack;

	// 判断栈是否满
	if (myStack->m_Size == MAX)
	{
		return;
	}

	// 数组尾插
	myStack->data[myStack->m_Size] = data;

	// 更新数组大小
	myStack->m_Size++;
}

出栈

void pop_SeqStack(SeqStack stack)
{
	// 本质 数组尾删
	if (stack == NULL)
	{
		return;
	}

	struct SStack* myStack = stack;

	if (myStack->m_Size == 0)
	{
		return;
	}

	// 数组尾删
	myStack->data[myStack->m_Size] = NULL;
	// 更新栈大小
	myStack->m_Size--;
}

返回栈顶

void* top_SeqStack(SeqStack stack)
{
	// 本质 返回数组中最后一个元素
	if (stack == NULL)
	{
		return;
	}

	struct SStack* myStack = stack;

	if (myStack->m_Size == 0)
	{
		return;
	}

	return myStack->data[myStack->m_Size - 1];
}

返回栈大小

int size_SeqStack(SeqStack stack)
{

	if (stack == NULL)
	{
		return -1;
	}
	struct SStack* myStack = stack;

	return myStack->m_Size;
}

判断栈是否为空

int isEmpty_SeqStack(SeqStack stack)
{
	if (stack == NULL)
	{
		return -1; // 传入空指针, 返回真, 也是空
	}
	struct SStack* myStack = stack;

	return myStack->m_Size == 0;
}

销毁栈

void destroy_SeqStack(SeqStack stack)
{
	if (stack == NULL)
	{
		return;
	}
	free(stack);
	stack = NULL;
}

测试

struct Person
{
	char name[64];
	int age;
};

// 测试栈
void test01()
{
	// 创建栈
	SeqStack myStack = init_SeqStack();

	// 创建数据
	struct Person p1 = { "aaa",18 };
	struct Person p2 = { "bbb",19 };
	struct Person p3 = { "ccc",16 };
	struct Person p4 = { "ddd",13 };
	struct Person p5 = { "eee",14 };
	struct Person p6 = { "fff",20 };

	// 入栈
	push_SeqStack(myStack, &p1);
	push_SeqStack(myStack, &p2);
	push_SeqStack(myStack, &p3);
	push_SeqStack(myStack, &p4);
	push_SeqStack(myStack, &p5);
	push_SeqStack(myStack, &p6);

	printf("栈的大小: %d\n", size_SeqStack(myStack));
	while (isEmpty_SeqStack(myStack) == 0) // 栈不为空, 开始查看栈顶元素, 并且出栈
	{
		struct Person* pTop = top_SeqStack(myStack);
		printf("name: %s, age: %d\n", pTop->name, pTop->age);
		// 出栈
		pop_SeqStack(myStack);
		printf("栈的大小: %d\n", size_SeqStack(myStack));
	}

	destroy_SeqStack(myStack);
}

栈的链式存储

设计

  • 链表头节点 做栈顶, 用于进出数据

节点结构体

// 节点结构体
struct LinkNode
{
	// 只维护指针域
	struct LinkNode* next;
};

栈的结构体

// 栈结构体
struct LStack
{
	// 头节点
	struct LinkNode pHeader;
	// 栈大小
	int m_Size;
};
typedef void* LinkStack;

初始化栈

LinkStack init_LinkStack()
{
	struct LStack * myStack = malloc(sizeof(struct LStack));

	if (myStack == NULL)
	{
		return NULL;
	}
	myStack->pHeader.next = NULL;
	myStack->m_Size = 0;

	return myStack;
}

入栈

void push_LinkStack(LinkStack stack, void* data)
{
	// 本质 链表头插
	if (stack == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}

	struct LStack* myStack = stack;

	// 取出用户数据前四个字节
	struct LinkNode* myNode = data;

	myNode->next = myStack->pHeader.next;
	myStack->pHeader.next = myNode;

	myStack->m_Size++;
}

出栈

void pop_LinkStack(LinkStack stack)
{
	// 本质 链表头删
	if (stack == NULL)
	{
		return;
	}

	struct LStack* myStack = stack;

	if (myStack->m_Size == 0)
	{
		return;
	}

	// 创建指向第一个节点的指针
	struct LinkNode* pFirst = myStack->pHeader.next;
	// 更新节点指向
	myStack->pHeader.next = pFirst->next;
	// 更新栈大小
	myStack->m_Size--;
}

返回栈顶

void* top_LinkStack(LinkStack stack)
{
	if (stack == NULL)
	{
		return;
	}
	struct LStack* myStack = stack;

	if (myStack->m_Size == 0)
	{
		return;
	}

	return myStack->pHeader.next;
}

返回栈大小

int size_LinkStack(LinkStack stack)
{
	if (stack == NULL)
	{
		return -1;
	}
	struct LStack* myStack = stack;

	return myStack->m_Size;
}

判断栈是否为空

int isEmpty_LinkStack(LinkStack stack)
{
	if (stack == NULL)
	{
		return -1;
	}
	struct LStack* myStack = stack;

	return myStack->m_Size == 0;
}

销毁栈

void destroy_LinkStack(LinkStack stack)
{
	if (stack == NULL)
	{
		return ;
	}

	free(stack); 
	stack = NULL;
}

测试

struct Person
{
	char* a;
	char name[64];
	int age;
};

// 测试栈
void test01()
{
	// 创建栈
	LinkStack myStack = init_LinkStack();

	// 创建数据
	struct Person p1 = {NULL, "aaa",18 };
	struct Person p2 = {NULL, "bbb",19 };
	struct Person p3 = {NULL, "ccc",16 };
	struct Person p4 = {NULL, "ddd",13 };
	struct Person p5 = {NULL, "eee",14 };
	struct Person p6 = {NULL, "fff",20 };

	// 入栈
	push_LinkStack(myStack, &p1);
	push_LinkStack(myStack, &p2);
	push_LinkStack(myStack, &p3);
	push_LinkStack(myStack, &p4);
	push_LinkStack(myStack, &p5);
	push_LinkStack(myStack, &p6);

	printf("栈的大小: %d\n", size_LinkStack(myStack));
	while (isEmpty_LinkStack(myStack) == 0) // 栈不为空, 开始查看栈顶元素, 并且出栈
	{
		struct Person* pTop = top_LinkStack(myStack);
		printf("LinkStack name: %s, age: %d\n", pTop->name, pTop->age);
		// 出栈
		pop_LinkStack(myStack);
		printf("栈的大小: %d\n", size_LinkStack(myStack));
	}

	destroy_LinkStack(myStack);
}

队列的顺序存储

  • 利用数组模拟出队列

设计

初始化队列

SeqQueue init_SeqQueue()
{
	// 动态数组 初始化
	struct dynamicArray* array  = init_dynamicArray(MAX);

	return array;
}

入队

void push_SeqQueue(SeqQueue queue, void* data)
{
	// 本质 尾插
	if (queue == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}

	struct dynamicArray* array = queue;

	if (array->m_Size == MAX)
	{
		return;
	}

	// 动态数组 插入数据
	insert_dynamicArray(array, data, array->m_Size);

}

出队

void pop_SeqQueue(SeqQueue queue)
{
	// 本质 头删
	if (queue == NULL)
	{
		return;
	}
	struct dynamicArray* array = queue;

	if (array->m_Size == 0)
	{
		return;
	}
	// 动态数组 按指定位置删除数据
	removeByPos_dynamicArray(array, 0);
}

返回队头

void* front_SeqQueue(SeqQueue queue)
{
	if (queue == NULL)
	{
		return NULL;
	}
	struct dynamicArray* array = queue;
	
	return array->pAddr[0];
}

返回队尾

void* back_SeqQueue(SeqQueue queue)
{
	if (queue == NULL)
	{
		return NULL;
	}
	struct dynamicArray* array = queue;

	return array->pAddr[array->m_Size-1];
}

返回队列大小

int size_SeqQueue(SeqQueue queue)
{
	if (queue == NULL)
	{
		return -1;
	}
	struct dynamicArray* array = queue;

	return array->m_Size;
}

判断队列是否为空

int isEmpty_SeqQueue(SeqQueue queue)
{
	if (queue == NULL)
	{
		return -1;
	}
	struct dynamicArray* array = queue;
	
	return array->m_Size == 0;
}

销毁队列

void destroy_SeqQueue(SeqQueue queue)
{
	if (queue == NULL)
	{
		return ;
	}

	// 动态数组 销毁数组
	destroy_dynamicArray(queue);
}

测试

// 测试队列
struct Person
{
	char name[64];
	int age;
};

void test01()
{
	// 初始化队列
	SeqQueue queue = init_SeqQueue();

	// 创建数据
	struct Person p1 = { "aaa",10 };
	struct Person p2 = { "bbb",11 };
	struct Person p3 = { "ccc",12 };
	struct Person p4 = { "ddd",13 };
	struct Person p5 = { "eee",14 };

	// 入队
	push_SeqQueue(queue, &p1);
	push_SeqQueue(queue, &p2);
	push_SeqQueue(queue, &p3);
	push_SeqQueue(queue, &p4);
	push_SeqQueue(queue, &p5);

	// 通过循环查看队头 队尾 执行出队
	while (isEmpty_SeqQueue(queue) == 0) // 不为空
	{
		struct Person * pFront  = front_SeqQueue(queue);
		printf(" Front name: %s, age: %d\n", pFront->name, pFront->age);

		struct Person* pBack = back_SeqQueue(queue);
		printf(" Back name: %s, age: %d\n", pBack->name, pBack->age);

		// 出队
		pop_SeqQueue(queue);

		//printf("size: %d\n", size_SeqQueue(queue));
	}

	// 销毁队列

	destroy_SeqQueue(queue);
}

队列的链式存储

  • 利用链表模拟队列

设计

// 节点结构体
struct LinkNode
{
	struct LinkNode* next;
};
// 队列结构体
struct LQueue
{
	// 头节点
	struct LinkNode pHeader;
	// 队列大小
	int m_Size;
	// 尾节点指针
	struct LinkNode* pTail;
};

typedef void* LinkQueue;

初始化

LinkQueue init_LinkQueue()
{
	struct LQueue* queue = malloc(sizeof(struct LQueue));
	if (queue == NULL)
	{
		return NULL;
	}

	queue->pHeader.next = NULL;
	queue->m_Size = 0;
	queue->pTail = &queue->pHeader;

	return queue;
}

入队

void push_LinkQueue(LinkQueue queue, void* data)
{ 
	// 本质 尾插
	if (queue == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	// 还原队列的真实结构体
	struct LQueue* myQueue = queue;

	// 用户数据前4个字节取出
	struct LinkNode* myNode = data;

	// 更改指针指向
	myQueue->pTail->next = myNode;
	myNode->next = NULL;
	myQueue->pTail = myNode;

	// 更新队列大小
	myQueue->m_Size++;
}

出队

void pop_LinkQueue(LinkQueue queue)
{
	// 本质 头删
	if (queue == NULL)
	{
		return;
	}
	// 还原队列的真实结构体
	struct LQueue* myQueue = queue;

	if (myQueue->m_Size == 0)
	{
		return;
	}

	// 如果只有1个节点, 更新尾节点的位置
	if (myQueue->m_Size == 1)
	{
		myQueue->pHeader.next = NULL;
		myQueue->pTail = &(myQueue->pHeader);
		myQueue->m_Size--;
		return;
	}

	// 记录第一个有数据的节点
	struct LinkNode* pFirt = myQueue->pHeader.next;

	// 更改指针指向
	myQueue->pHeader.next = pFirt->next;


	// 更新队列大小
	myQueue->m_Size--;
}

返回队头元素

void* front_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return NULL;
	}
	// 还原队列的真实结构体
	struct LQueue* myQueue = queue;

	if (myQueue->m_Size == 0)
	{
		return NULL;
	}

	return myQueue->pHeader.next;
}

返回队尾元素

void* back_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return NULL;
	}
	// 还原队列的真实结构体
	struct LQueue* myQueue = queue;

	if (myQueue->m_Size == 0)
	{
		return NULL;
	}

	return myQueue->pTail;
}

返回队列大小

int size_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return -1;
	}
	// 还原队列的真实结构体
	struct LQueue* myQueue = queue;

	return myQueue->m_Size;
}

判断队列是否为空

int isEmpty_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return -1;
	}
	// 还原队列的真实结构体
	struct LQueue* myQueue = queue;

	return myQueue->m_Size == 0;
}

销毁队列

void destroy_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return;
	}
	free(queue);
	queue = NULL;
}

测试

// 测试队列
struct Person
{
	char* a;
	char name[64];
	int age;
};

void test01()
{
	// 初始化队列
	LinkQueue queue = init_LinkQueue();

	// 创建数据
	struct Person p1 = { NULL,"aaa",10 };
	struct Person p2 = { NULL,"bbb",11 };
	struct Person p3 = { NULL,"ccc",12 };
	struct Person p4 = { NULL,"ddd",13 };
	struct Person p5 = { NULL,"eee",14 };

	// 入队
	push_LinkQueue(queue, &p1);
	push_LinkQueue(queue, &p2);
	push_LinkQueue(queue, &p3);
	push_LinkQueue(queue, &p4);
	push_LinkQueue(queue, &p5);

	// 通过循环查看队头 队尾 执行出队
	while (isEmpty_LinkQueue(queue) == 0) // 不为空
	{
		struct Person* pFront = front_LinkQueue(queue);
		printf(" Front name: %s, age: %d\n", pFront->name, pFront->age);

		struct Person* pBack = back_LinkQueue(queue);
		printf(" Back name: %s, age: %d\n", pBack->name, pBack->age);

		// 出队
		pop_LinkQueue(queue);

		printf("size: %d\n", size_LinkQueue(queue));
	}

	// 销毁队列

	destroy_LinkQueue(queue);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值