1.栈
1.基础知识
1.
栈顶有元素是满栈,反之是空栈。
入栈向高地址移动是增,反之减。
满增栈:入栈数据时,栈顶先移,后入栈数据,且栈顶向高满增栈地址移动;出栈数据时,先数据出栈后移栈顶,且栈顶向低地址移动。
满减栈:入栈数据时,栈顶先移后入栈数据,且栈顶向低地址满减栈移动:出栈数据时,数据先出栈后移栈顶,且栈顶向高地址移动。
空增栈:入栈数据时,先入栈数据后移动栈顶,且栈顶向高地址空增栈移动;出栈数据时,先移动栈顶后出栈数据,且栈顶向低地址移动。
空减栈:入栈数据时,先入栈数据后移动栈顶,栈顶向低地址移空减栈动;出栈数据时,先移动栈顶后出栈数据,栈顶向高地址移动
2.
2 . 代码操作
代码大差不差,同单向链表,头节点类型不同。
为了区别返回值是我们需要的数据还是错误返回,采用传地址来修改主调。
.h文件
#ifndef __STACK_H__
#define __STACK_H__
typedef int data_type;
typedef struct node
{
data_type data;
struct node *pnext;
}stack_node;
typedef struct head
{
stack_node *ptop;
data_type clen;
}stack_head;
extern stack_head * create_stack();
extern int push_stack(stack_head *pstack, data_type data);
extern int stack_for_each(stack_head *pstack);
extern int pop_stack(stack_head *pstack ,data_type *pdata);
extern int get_stack_top(stack_head *pstack,data_type *ptopdata);
extern int clear_stack(stack_head *pstack,data_type *pdata);
extern void destroy_stack(stack_head *pstack,data_type *pdata);
#endif
.c文件
#include "stack.h"
#include <stdio.h>
#include<stdlib.h>
stack_head * create_stack()
{
stack_head *pstack = malloc(sizeof(stack_head));
if(NULL == pstack)
{
printf("fail malloc\n");
return NULL;
}
pstack->ptop = NULL;
pstack->clen = 0;
return pstack;
}
int is_empty_stack(stack_head *pstack)
{
if(NULL == pstack->ptop)
{
return 1;
}
return 0;
}
int push_stack(stack_head *pstack , data_type data)
{
if(NULL == pstack)
{
return -1;
}
stack_node *pinsert = malloc(sizeof(stack_node));
pinsert->pnext = NULL;
pinsert->data = data;
pinsert->pnext = pstack->ptop;
pstack->ptop = pinsert;
++pstack->clen;
return 0;
}
int stack_for_each(stack_head *pstack)
{
if(NULL == pstack)
{
return -1;
}
stack_node *p =pstack->ptop;
while(p !=NULL)
{
printf("%d ",p->data);
p = p->pnext;
}
printf("\n");
}
int pop_stack(stack_head *pstack ,data_type *pdata)
{
if(NULL == pstack)
{
return -1;
}
if(is_empty_stack(pstack))
{
return -1;
}
stack_node *p = pstack->ptop->pnext;
*pdata = pstack->ptop->data;
free(pstack->ptop);
pstack->ptop = p;
--pstack->clen;
return 0;
}
int get_stack_top(stack_head *pstack,data_type *ptopdata)
{
if(NULL == pstack)
{
return -1;
}
if(is_empty_stack(pstack))
{
return -1;
}
*ptopdata = pstack->ptop->data;
return 0;
}
int clear_stack(stack_head *pstack,data_type *pdata)
{
if(NULL == pstack)
{
return -1;
}
while(!is_empty_stack(pstack))
{
pop_stack(pstack,pdata);
}
return 0;
}
void destroy_stack(stack_head *pstack,data_type *pdata)
{
clear_stack(pstack,pdata);
free(pstack);
}
队列
头尾分别插入和释放
代码
队列的头不一样。
.h文件
#ifndef __QUEUE_H__
#define __QUEUE_H__
typedef int data_type;
typedef struct node
{
data_type data;
struct node *pnext;
}queue_node;
typedef struct queue
{
queue_node *phead;
queue_node *ptail;
data_type clen;
}queue;
extern queue * creat_queue();
extern int push_queue(queue *queue_one,data_type data);
extern int is_empty_queue(queue *queue_one);
extern int pop_queue(queue *queue_one, data_type *pdata);
extern void queue_for_each(queue *queue_one);
extern void clear_queue(queue* queue_one);
extern void destroy_queue(queue *queue_one);
extern int get_queue_head(queue *queue_one , data_type *head_data);
#endif
.c文件。
push就是尾插,分两种情况,空的和非空,因为非空和空的插入的前节点类型不同。
pop是头删。同样分两种情况。单个和非单个。
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
queue * creat_queue()
{
queue *queue_one = malloc(sizeof(queue));
if(NULL == queue_one)
{
printf("malloc fail\n");
return NULL;
}
queue_one->phead = NULL;
queue_one->ptail = NULL;
queue_one->clen = 0;
return queue_one;
}
int is_empty_queue(queue *queue_one)
{
if(NULL == queue_one->phead)
return 1;
else
return 0;
}
int push_queue(queue *queue_one , data_type data)
{
if(NULL == queue_one)
{
return -1;
}
queue_node *pinsert = malloc(sizeof(queue_node));
if(NULL == pinsert)
{
printf("malloc fail\n");
return -1;
}
pinsert->pnext = NULL;
pinsert->data = data;
if(is_empty_queue(queue_one))
{
queue_one->phead = pinsert;
queue_one->ptail = pinsert;
++queue_one->clen;
return 0;
}
else
{
queue_one->ptail->pnext = pinsert;
queue_one->ptail = pinsert;
++queue_one->clen;
return 0;
}
}
void queue_for_each(queue *queue_one)
{
if(NULL == queue_one)
{
return;
}
queue_node *p =queue_one->phead;
while(p != NULL)
{
printf("%d ",p->data);
p = p->pnext;
}
printf("\n");
}
int pop_queue(queue *queue_one, data_type *pdata)
{
if(NULL == queue_one || NULL == pdata)
{
return -1;
}
if(is_empty_queue(queue_one))
{
return -1;
}
if(queue_one->phead->pnext == NULL)//只有一个元素
{
*pdata = queue_one->phead->data;
free(queue_one->phead);
queue_one->ptail = queue_one->phead = NULL;
--queue_one->clen;
return 0;
}
else
{
*pdata = queue_one->phead->data;
queue_node *pdel = queue_one->phead;
queue_one->phead = pdel->pnext;
--queue_one->clen;
free(pdel);
return 0;
}
}
int get_queue_head(queue *queue_one , data_type *head_data)
{
if(NULL == queue_one || NULL == head_data)
{
return -1;
}
if(is_empty_queue(queue_one))
{
return -1;
}
*head_data = queue_one->phead->data;
return 0;
}
void clear_queue(queue *queue_one)
{
if(NULL == queue_one )
{
return ;
}
data_type data;
while(!is_empty_queue(queue_one))
{
pop_queue(queue_one,&data);
}
}
void destroy_queue(queue *queue_one)
{
clear_queue(queue_one);
free(queue_one);
}
二叉树
完全二叉树 :在满二叉树的基础上顺序的增加节点。
满一定是完全。