目录
一、栈
栈是一种受到限制的线性数据结构
栈顶是操作数据的一端
栈底不能进行数据操作
操作数据的顺序: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;
}
三、总结
只要单向链表和结构体搞明白,理解这些就简单一些
