栈实现队列、链表封装

栈实现队列:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define TYPE int

//	设计顺序栈结构
typedef struct ArrayStack
{
	TYPE* ptr;	//	存储元素内存首地址	
	size_t cal;	//	栈的容量
	size_t top; //	栈顶下标 从0开始 空增栈
}ArrayStack;
/*栈功能实现*/
//	创建
ArrayStack* create_array_stack(size_t cal)
{
	//	为栈结构分配内存
	ArrayStack* stack = malloc(sizeof(ArrayStack));
	//	分配存储元素的内存
	stack->ptr = malloc(sizeof(TYPE)*cal);
	//	记录栈容量
	stack->cal = cal;
	//	记录栈顶位置,接下来要入栈的位置
	stack->top = 0;
	return stack;
}

//	销毁
void destory_array_stack(ArrayStack* stack)
{
	free(stack->ptr);
	free(stack);
}

//	栈空
bool empty_array_stack(ArrayStack* stack)
{
	return 0 == stack->top;	
}
//	栈满
bool full_array_stack(ArrayStack* stack)
{
	return stack->top >= stack->cal;	
}

//	入栈
bool push_array_stack(ArrayStack* stack,TYPE val)
{
	if(full_array_stack(stack)) return false;
	stack->ptr[stack->top++] = val;
	return true;
}

//	出栈
bool pop_array_stack(ArrayStack* stack)
{
	if(empty_array_stack(stack)) return false;
	stack->top--;
	return true;
}

//	栈顶
bool top_array_stack(ArrayStack* stack,TYPE* val)
{
	if(empty_array_stack(stack)) return false;
	*val = stack->ptr[stack->top-1];
	return true;
}
/*	使用两个栈模拟队列功能	*/
typedef struct Queue
{
	ArrayStack* s1;
	ArrayStack* s2;
}Queue;

//	创建队列
Queue* create_queue(size_t cal)
{
	Queue* queue = malloc(sizeof(Queue));
	queue->s1 = create_array_stack(cal);
	queue->s2 = create_array_stack(cal);
	return queue;
}

//	队满
bool full_queue(Queue* queue)
{
	return full_array_stack(queue->s1) && 
	full_array_stack(queue->s2);	
}

//	队空
bool empty_queue(Queue* queue)
{
	return empty_array_stack(queue->s1) &&
		empty_array_stack(queue->s2);
}

//	入队
bool push_queue(Queue* queue,TYPE val)
{
	if(full_array_stack(queue->s1))
	{
		if(!empty_array_stack(queue->s2)) return false;

		while(!empty_array_stack(queue->s1))
		{
			TYPE top = 0;
			top_array_stack(queue->s1,&top);
			pop_array_stack(queue->s1);
			push_array_stack(queue->s2,top);
		}
	}
	printf("tail:%d\n",val);	//测试
	return push_array_stack(queue->s1,val);
}

//	出队
bool pop_queue(Queue* queue)
{
	if(empty_array_stack(queue->s2))
	{
		if(empty_array_stack(queue->s1)) return false;
		while(!empty_array_stack(queue->s1))
		{
			TYPE top = 0;
			top_array_stack(queue->s1,&top);
			pop_array_stack(queue->s1);
			push_array_stack(queue->s2,top);
		}
	}
	TYPE top = 0;
	top_array_stack(queue->s2,&top);
	printf("top:%d\n",top);	//测试
	return pop_array_stack(queue->s2);
}

int main(int argc,const char* argv[])
{
	Queue* queue = create_queue(10);
	for(int i=0; i<20; i++)
	{
		push_queue(queue,i);	
	}
	while(!empty_queue(queue))
	{
		pop_queue(queue);	
	}
}
链表封装:

尾添加的效率低,对非法下标的判断下标的效率也非常低

1、单链表

​ 结点:

​ 数据域

​ 指针域

​ 例(节点):

typedef struct Node
{
    TYPE data;
    struct Node*next;
}Node;

​ 单链表数据项:

​ 头结点

​ 尾结点

​ 结点数量

例(链表)

typedef struct List
{
    Node* head; //头指针
    Node* tail; //尾指针
    size_t size;    //结点数量
}List;

2、静态链表

​ 结点:

​ 数据域

​ 游标

typedef struct Node
{
    int data;
    int i;      //游标
}

​ 静态链表的结点存储在连续的内存中,通过游标来访问下一个结点

​ 这种链表在插入删除时需要修改游标的值,而不用申请、释放结点内存就可以达到类似链式结构的效果

​ 牺牲了随机访问的功能、也没达到链表动态申请内存的效果,只是给没有指针的编程语言实现链表的一种方式,适用范围不大

​ 3、循环链表

​ 链表的最后一个结点的next不再指向NULL,而是指向头结点,这种链表称为单向循环链表,简称循环链表,它的好处是可以通过任意结点来遍历整个链表

​ 4、双向链表

​ 结点:

​ 前驱指针 prev

​ 数据域

​ 后继指针 next

typedef struct Node
{
	struct Node* prev;	//	前驱
	TYPE data;
	struct Node* next;	//	后继
}Node;

数据项:

​ 头结点

​ 结点数量

//	双向链表
typedef struct DoubleList
{
	Node* head;
	size_t size;
}DoubleList;

​ 特点:

​ 1、在任意结点都可以遍历整个链表

​ 2、相比单链表,删除、插入更直接

​ 3、已知结点位置,可以选择从前往后或从后往前遍历,提高链表访问效率

​ 5、Linux内核通用链表

​ 链表的结点不能包含万物,就让万物来包含结点

typedef struct Node
{
	struct Node* prev;
	struct Node* next;
}Node;
//	创建链表
Node* create_list(void)
{
	Node* head = malloc(sizeof(Node));
	head->next = head;
	head->prev = head;
	return head;
}

​ 6、通用链表

​ 结点:

​ void* ptr;

​ 指针域

​ 运算:常规功能+回调函数

//	重定义了函数指针类型 新类型名叫Comper 
//	定义函数指针变量 Comper cmp
//	cmp即函数指针变量
typedef int (*Comper)(const void*,const void*);

//	通用链表结点
typedef struct Node
{
	void* ptr;
	struct Node* prev;
	struct Node* next;
}Node;

//	通用链表结构
typedef struct List
{
	Node* head;
	size_t size;
}List;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值