系统栈 程序运行中使用的栈,由操作系统维护
栈区: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);
}