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

目录

一、栈

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;
}

三、总结

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

相关推荐
西岸行者2 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
琢磨先生David2 天前
Day1:基础入门·两数之和(LeetCode 1)
数据结构·算法·leetcode
悠哉悠哉愿意2 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
qq_454245032 天前
基于组件与行为的树状节点系统
数据结构·c#
超级大福宝2 天前
N皇后问题:经典回溯算法的一些分析
数据结构·c++·算法·leetcode
别催小唐敲代码2 天前
嵌入式学习路线
学习
岛雨QA2 天前
常用十种算法「Java数据结构与算法学习笔记13」
数据结构·算法
weiabc2 天前
printf(“%lf“, ys) 和 cout << ys 输出的浮点数格式存在细微差异
数据结构·c++·算法
wefg12 天前
【算法】单调栈和单调队列
数据结构·算法
岛雨QA2 天前
图「Java数据结构与算法学习笔记12」
数据结构·算法