系统栈 程序运行中使用的栈,由操作系统维护
栈区:1,保存局部变量
2,函数的形参的返回值
3,函数的调用关系 函数中调用函数时会把调用函数的下一条指定的首地址保存在栈区。 (保护现场和恢复现场)。
特点:先进后出,后进先出
数据结构中的栈
只允许从一端进行数据的插入和删除的线性的存储结构
特点:先进后出,后进先出 FILO
由自己开辟空间,维护
表尾称为栈顶,表头端称为栈底 。不含元素的空表称为空栈。栈的修改是按后进先出的原则进行的
满栈、空栈:栈顶所在位置是否存有元素
增栈:栈顶向内存高地址移动。
减栈:栈顶向内存低地址移动。
顺序栈:指利用顺序存储结构实现的栈(数组)
链式栈:指采用链式存储结构实现的栈
以链表表头做栈顶
定义节点及栈对象:
typedef int DataType;
typedef struct snode
{
DataType data;
struct snode *pnext;
}SNode_t;
typedef struct stack
{
SNode_t *ptop;
int clen;
}Stack_t;
链式栈的操作
1. 创建栈
2. 入栈
3. 出栈
4. 清空栈
5. 判空
6. 获取栈顶元素
7.销毁栈
Stack_t *create_stack() //创建
{
Stack_t *pslink = malloc(sizeof(Stack_t));
if(pslink == NULL)
{
perror("malloc fail");
return NULL;
}
pslink->ptop = NULL;
pslink->clen = 0;
return pslink;
}
int is_empty_stack(Stack_t *pslink) //判空
{
return pslink->ptop == NULL;
}
int push_stack(Stack_t *pslink,DataType data) //入栈
{
SNode_t *pnode = malloc(sizeof(SNode_t));
if(pnode == NULL)
{
perror("malloc fail");
return -1;
}
pnode->data = data;
pnode->pnext = pslink->ptop;
pslink->ptop = pnode;
pslink->clen++;
return 0;
}
void print_stack(Stack_t *pslink) // 遍历
{
SNode_t *p = pslink->ptop;
while(p != NULL)
{
printf("%d ",p->data);
p = p->pnext;
}
printf("\n");
}
int pop_stack(Stack_t *pslink,DataType *data) //出栈
{
if(!is_empty_stack(pslink))
{
SNode_t *p = pslink->ptop;
pslink->ptop = p->pnext;
if(data != NULL)
{
*data = p->data;
}
free(p);
}
pslink->clen--;
return 1;
}
int get_stack_top(Stack_t *pslink,DataType *data) //获取栈顶元素
{
if(!is_empty_stack(pslink))
{
if(pslink != NULL)
{
*data = pslink->ptop->data;
return 1;
}
}
return 0;
}
void clear_stack(Stack_t *pslink) //清空栈
{
while(!is_empty_stack(pslink))
{
pop_stack(pslink,NULL);
}
}
void destroy_stack(Stack_t *pslink) //销毁栈
{
clear_stack(pslink);
free(pslink);
}
队列:先进先出,后进后出 FIFO
允许从一端插入数据, 另一端删除数据的线性存储结构
允许插入的一端称为队尾,允许删除的一端则称为队头
顺序队列,存在假溢出,可以使用循环队列解决
链式队列:链队是指采用链式存储结构实现的队列。 通常链队用单链表来表
示。 选择链表表头做对头,表尾做队尾。
注意链表对象中pfront指向对头,prear指向队尾
定义节点及链表对象
typedef int QDataType;
typedef struct qnode
{
QDataType data;
struct qnode *pnext;
}Queue_Node_t;
typedef struct queue
{
Queue_Node_t *pfront;
Queue_Node_t *prear;
int clen;
pthread_mutex_t mutex;
}Queue_t;
l链式队列的操作:
1. 创建队列
2. 入队
3. 出队
4. 判空
5. 清空
6. 获取对头元素
7. 销毁
Queue_t *create_queue() //创建队列
{
Queue_t *pqueue = malloc(sizeof(Queue_t));
if(pqueue == NULL)
{
perror("malloc fail");
return NULL;
}
pqueue->pfront = NULL;
pqueue->prear = NULL;
pqueue->clen = 0;
pthread_mutex_init(&(pqueue->mutex),NULL);
return pqueue;
}
int is_empty_queue(Queue_t *pqueue) //判空
{
return pqueue->pfront == NULL;
}
int push_queue(Queue_t *pqueue,QDataType data) //入队
{
Queue_Node_t *pnode = malloc(sizeof(Queue_Node_t));
if(pnode == NULL)
{
perror("malloc fail");
return -1;
}
pnode->data = data;
pnode->pnext = NULL;
if(!is_empty_queue(pqueue))
{
pqueue->prear->pnext = pnode;
pqueue->prear = pnode;
}
else
{
pqueue->prear = pnode;
pqueue->pfront = pnode;
}
pqueue->clen++;
return 1;
}
int pop_queue(Queue_t *pqueue,QDataType *data) //出队
{
if(!is_empty_queue(pqueue))
{
Queue_Node_t *p = pqueue->pfront;
pqueue->pfront = p->pnext;
if(data != NULL)
{
*data = p->data;
}
if(p->pnext == NULL)
{
pqueue->prear = NULL;
}
free(p);
}
pqueue->clen--;
return 1;
}
void print_queue(Queue_t *pqueue) //遍历
{
Queue_Node_t *p = pqueue->pfront;
while(p != NULL)
{
printf("%d ",p->data);
p = p->pnext;
}
printf("\n");
}
int get_queue_front(Queue_t *pqueue,QDataType *data) //获取队头元素
{
if(!is_empty_queue(pqueue))
{
if(data != NULL)
{
*data = pqueue->pfront->data;
}
}
return 1;
}
void clear_queue(Queue_t *pqueue) //清空
{
while(!is_empty_queue(pqueue))
{
pop_queue(pqueue,NULL);
}
}
void destroy_queue(Queue_t *pqueue) //销毁
{
clear_queue(pqueue);
free(pqueue);
}