数据结构的学习(四)---栈和队列

目录

一、栈

1.顺序栈:

结构体:

相关算法:

2.链式栈:

结构体:

相关算法:

二、队列

1.顺序队列:

结构体:

相关算法:

2.链式队列:

结构体:

相关算法:

三、总结


一、栈

栈是一种受到限制的线性数据结构

栈顶是操作数据的一端

栈底不能进行数据操作

操作数据的顺序:FILO(first in last out)

1.顺序栈:

用数组(顺序表)来实现

结构体:

复制代码
#ifndef _STACK_H_
#define _STACK_H_ 

//要处理的 数据类型
typedef int data_t;


//栈标签 ---代表一个栈 
typedef struct seqstack
{
	data_t *stack; //开辟栈空间 
	int top;  //top 栈顶 -栈针 
	int max;  //栈空间容量的上限 
}seqstack_t;

//创建 
seqstack_t * create_stack(int len);
//入栈 
int push(seqstack_t *pstack,data_t d);
//出栈 
int pop(seqstack_t *pstack,data_t *d);
//获取栈顶元素:
data_t get_top_element(seqstack_t *pstack);
//6.栈的大小 //此时栈中有效数据的个数
int get_stack_size(seqstack_t *pstack);
//销毁
int seqstack_destroy(seqstack_t **ppstack);
#endif 

相关算法:

1.创建栈

2.入栈出栈

3.获取栈顶元素

4.获取栈的容量(栈能存放的最大元素个数)

5.获取栈的大小(此时栈中有效数据的个数)

复制代码
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>

//创建 
seqstack_t * create_stack(int len)
{
	//栈结构 
	seqstack_t * pstack = malloc(sizeof(seqstack_t));
	if (pstack == NULL)
	{
		return NULL;
	}

   //栈的空间 
	pstack->stack = malloc(sizeof(data_t) * len);
	if (pstack->stack == NULL)
	{
		return NULL;
	}

	//栈针 --设置成 -1 
	pstack->top = -1;
	pstack->max = len; 

   return pstack;
}
int is_full(seqstack_t *pstack)
{
	if (pstack == NULL)
	{
		return -1;
	}
	return pstack->top == pstack->max-1; //是否到到了容量的上限 
}
//入栈 
int push(seqstack_t *pstack,data_t d)
{ 
	if (pstack == NULL)
	{
		return -1;
	}

	if (is_full(pstack) == 1)
	{
		return 1;
	}

	pstack->top ++;
	pstack->stack[pstack->top] = d;
	return 0;	
}
int is_empty(seqstack_t *pstack)
{
	if (pstack == NULL)
	{
		return -1;
	}
	return pstack->top == -1;
}
//出栈 
int pop(seqstack_t *pstack,data_t *d)
{ 
	if (pstack == NULL)
	{
		return -1;
	}

	if (is_empty(pstack) == 1)
	{
		return 1;
	}

	*d = pstack->stack[pstack->top];
	pstack->top --;
	return 0;	
}

//获取栈顶元素:
data_t get_top_element(seqstack_t *pstack)
{

	if (pstack == NULL)
	{
		return -1;
	}

	if (is_empty(pstack) == 1)
	{
		return 1;
	}

	return pstack->stack[pstack->top];
}
//6.栈的大小 //此时栈中有效数据的个数
//top?
int get_stack_size(seqstack_t *pstack)
{
	if (pstack == NULL)
	{
		return -1;
	}
	return pstack->top + 1;
}

//销毁
int seqstack_destroy(seqstack_t **ppstack)
{
	if (ppstack == NULL || *ppstack  == NULL)
	{
		return -1;
	}

	seqstack_t *q = *ppstack;
	free(q->stack);
	free(q);
	*ppstack = NULL; 
	return 0;
}

2.链式栈:

用链表来实现

结构体:

复制代码
#ifndef _LINKSTAK_H_ 
#define _LINKSTAK_H_ 

typedef int data_t;

typedef struct stack
{
	data_t data;
	struct stack *next;
}snode_t;

//1.创建链表 
snode_t *create_linkstack(void);
int pop(snode_t *pstack,data_t *data);
int push(snode_t *pstack,data_t data);
data_t get_top_element(snode_t *pstack);
int get_stack_size(snode_t *pstack);
int linkstack_destroy(snode_t ** ppstack);
#endif 

相关算法:

1.创建栈

2.入栈出栈

3.获取栈顶元素

4.获取栈的容量---链式不考虑容量

4.获取栈的大小(此时栈中有效数据的个数)

复制代码
#include <stdio.h>
#include <stdlib.h>
#include "linkstack.h"


 
//创建空栈 
snode_t *create_linkstack(void)
{
	snode_t *head = malloc(sizeof(snode_t));
	if (head == NULL)
	{
		printf("malloc fail");
		return NULL;
	}
	head->next = NULL; // 

	return head;
}
//2.头插 
int push(snode_t *pstack,data_t data)
{
	if (pstack == NULL)
	{
		return -1;
	}

	//1.创建新节点 
	snode_t *p_new = malloc(sizeof(snode_t));
	if (p_new == NULL)
	{
		printf("%s: malloc fail\n",__func__);
		return -1;
	}
	p_new->data = data;
	//2.链接链表  
    p_new->next = pstack->next;
    pstack->next = p_new;

	return 0;
}


int is_empty(snode_t *pstack)
{
	if (pstack == NULL)
		return -1;

	return pstack->next == NULL;
}

int pop(snode_t *pstack,data_t *data)
{
	if (pstack == NULL)
	{
		return -1;
	}
	//判断链表是否为空
	if (is_empty(pstack) == 1)
	{
		printf("%s:linkstack empty!\n",__func__);
		return -1;
	}
	//  step1.有一个指针变量 指向首节点 phead->pnext
	snode_t *p = pstack->next;
	//  step2.让头节点指向p->pnext 
	pstack->next = p->next;
	//  step3.释放 p所在的节点 
	//        free(p);
	
	*data = p->data;
	
	free(p);

	return 0;
}

data_t get_top_element(snode_t *pstack)
{

	if (pstack == NULL)
	{
		return -1;
	}
	//判断链表是否为空
	if (is_empty(pstack) == 1)
	{
		printf("%s:linkstack empty!\n",__func__);
		return -1;
	}

	return pstack->next->data;

}

int get_stack_size(snode_t *pstack)
{
	if (pstack == NULL)
	{
		return -1;
	}
	//判断链表是否为空
	if (is_empty(pstack) == 1)
	{
		return 0;
	}

	snode_t *p = pstack->next;
    int cnt = 0;
	while (p!=NULL)
	{
		cnt++;
		p = p->next;
	}

	return cnt;
}

int linkstack_destroy(snode_t ** ppstack)
{
	if (ppstack == NULL || *ppstack == NULL)
	{
		return  -1;
	}
	snode_t *p = (*ppstack)->next; 
	while (p!=NULL)
	{
		snode_t *ptemp = p;
		p = p->next;
		free(ptemp);
	}
	free(*ppstack);
	*ppstack=NULL; //防止悬空指针 
	return 0;
}

二、队列

队列也是一种受到限制的线性数据结构

队头出数据

队尾入数据

操作数据的顺序:FIFO(first in first out)

1.顺序队列:

用数组来实现

结构体:

复制代码
#ifndef _QUEUE_H_
#define _QUEUE_H_

typedef int data_t;

typedef struct queue
{
	data_t *que;
	int head;
	int tail;
	int tlen;
}queue_t;

//创建 
queue_t * create_queue(int len);
//入队
int enqueue(queue_t *pque, data_t data);
//出队
int dequeue(queue_t *pque, data_t *data);
//销毁
int queue_destroy(queue_t **ppque);

#endif 

相关算法:

1.创建队列

2.入队出队

3.销毁

注意:队列满和队列空的判断条件

复制代码
#include "queue.h"
#include <stdio.h>
#include <stdlib.h>

//创建 

queue_t * create_queue(int len)
{
	queue_t *q = malloc(sizeof(queue_t));
	if (q == NULL)
	{
		return NULL;
	}

	q->que = malloc(sizeof(data_t) * len);
	if (q->que == NULL)
	{
		return NULL;
	}

	q->head = 0;
	q->tail = 0;
	q->tlen = len;

	return q;
}

int is_full (queue_t *pque)
{
	if (pque == NULL)
	{
		return -1;
	}

	return (pque->tail+1)%pque->tlen == 0;

}
//入队
int enqueue(queue_t *pque, data_t data)
{
	if (pque == NULL)
	{
		return -1;
	}

	if (is_full(pque) == 1)
	{
		return -1;
	}

	pque->que[pque->tail] = data;
	pque->tail++;

	return 0;
}

int is_empty(queue_t *pque)
{
	if (pque == NULL)
	{
		return -1;
	}

	return pque->tail == 0 && pque->head == 0;
}
//出队
int dequeue(queue_t *pque, data_t *data)
{
	if (pque == NULL)
	{
		return -1;
	}
	if (is_empty(pque) == 1)
	{
		return -1;
	}

	*data = pque->que[pque->head];
	pque->head++;

	return 0;
}

//销毁
int queue_destroy(queue_t **ppque)
{
	if (ppque == NULL || *ppque == NULL) 
	{
		return -1;
	}

   free((*ppque)->que);//队列的空间
   free(*ppque);//队列结构
   *ppque = NULL;//悬空指针

   return 0;
}

2.链式队列:

用链表来实现

结构体:

复制代码
#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_

//数据类型 
typedef int data_t;

//节点类型 
typedef struct queue
{
	data_t data;
	struct queue *next;
}qnode_t; 
//1.创建队列  
qnode_t *create_queue(void);
//5.入队 -- 尾插
int enqueue(qnode_t *pque,data_t dt);
//出队--头删
data_t dequeue(qnode_t *pque);
int queue_destroy(qnode_t ** ppque);
#endif

相关算法:

1.创建队列

2.入队出队

3.销毁

复制代码
#include <stdio.h>
#include <stdlib.h>
#include "linkqueue.h"


//1.创建队列  
qnode_t *create_queue(void)
{
	qnode_t *head = malloc(sizeof(qnode_t));
	if (head == NULL)
	{
		printf("malloc fail");
		return NULL;
	}
	head->next = NULL; //

	return head;
}


//5.入队 -- 尾插
int enqueue(qnode_t *pque,data_t dt)
{
	if (pque == NULL)
	{
		return -1;
	}

	//1.创建新节点 并 给值 
	qnode_t *p_new = malloc(sizeof(qnode_t));
	if (p_new == NULL)
	{
		printf("%s: malloc fail\n",__func__);
		return -1;
	}
	p_new->data = dt;
	p_new->next = NULL; 

	//2.找到尾节点 
	qnode_t *p = pque;
	while (p->next!= NULL)
	{
		p = p->next;
	}
	//3.连接 
	p->next = p_new;

	return 0;
}


//3.判断链表是否为空
int is_empty(qnode_t *pque)
{
	if (pque == NULL)
	{
		return -1;
	}
	return pque->next == NULL;
}

//出队--头删
data_t dequeue(qnode_t *pque)
{ 
	if (pque == NULL)
	{
		return -1;
	}
	//判断链表是否为空
	if (is_empty(pque) == 1)
	{
		printf("%s:linkqueue empty!\n",__func__);
		return -1;
	}
	//  step1.有一个指针变量 指向首节点 phead->pnext
	qnode_t *p = pque->next;
	//  step2.让头节点指向p->pnext 
	pque->next = p->next;
	//  step3.释放 p所在的节点 
	//        free(p);

	//拿出数据 
   data_t data = p->data;

	free(p);

	return data;
}
int queue_destroy(qnode_t ** ppque)
{
	if (ppque == NULL || *ppque == NULL)
	{
		return -1;
	}
	qnode_t *p = (*ppque)->next; 

	while (p!=NULL)
	{
		qnode_t *ptemp = p;
		p = p->next;
		free(ptemp);
	}
	free(*ppque);
	*ppque=NULL; //防止悬空指针 

	return 0;
}

三、总结

只要单向链表和结构体搞明白,理解这些就简单一些

相关推荐
2501_901147832 小时前
学习笔记:单调递增数字求解的迭代优化与工程实践
linux·服务器·笔记·学习·算法
数智工坊2 小时前
【数据结构-特殊矩阵】3.5 特殊矩阵-压缩存储
数据结构·线性代数·矩阵
芝士爱知识a3 小时前
AlphaGBM 深度解析:下一代基于 AI 与蒙特卡洛的智能期权分析平台
数据结构·人工智能·python·股票·alphagbm·ai 驱动的智能期权分析·期权
兩尛3 小时前
160. 相交链表/c++
数据结构·链表
2302_813806223 小时前
【嵌入式修炼:数据结构篇】——单向链表的排序
数据结构·链表·排序算法
2302_813806223 小时前
【嵌入式修炼:数据结构篇】——树和二叉树
数据结构
苦逼IT运维3 小时前
从 0 到 1 理解 Kubernetes:一次“破坏式”学习实践(一)
linux·学习·docker·容器·kubernetes
苦藤新鸡3 小时前
56.组合总数
数据结构·算法·leetcode
菜鸟233号3 小时前
力扣647 回文子串 java实现
java·数据结构·leetcode·动态规划