栈和队列(C链表实现)
2017-12-27 14:53
183 查看
栈和队列是两种很有用的数据结构,栈是先进后出(FILO),队列是先进先出(FIFO)。
在迷宫求解,括号匹配,递归这些问题里,栈的应用非常广泛,而队列在操作系统的进程排队,线程池里很有用。C中没有现成的栈和队列,这里用链表来模拟一下。设计时分别用到两个结构体,将链表节点部分和控制作用的表头分开,方便管理。
在栈的设计中,使用表头指向栈的top ,每次入栈只需将新节点指向表头,表头再指向新节点便可,出栈也是将top指向下一个节点,先前的节点释放。
对于栈来说,我们只需要管好它的栈顶就行了,但是队列的话得两头都处理,所以表头结构体加一个队尾指针。并且在队列节点中增加了一个头结点,这时为了避免每次入队的时候判断是否时第一个节点带来的多余工作,头结点中内容为空。
在迷宫求解,括号匹配,递归这些问题里,栈的应用非常广泛,而队列在操作系统的进程排队,线程池里很有用。C中没有现成的栈和队列,这里用链表来模拟一下。设计时分别用到两个结构体,将链表节点部分和控制作用的表头分开,方便管理。
在栈的设计中,使用表头指向栈的top ,每次入栈只需将新节点指向表头,表头再指向新节点便可,出栈也是将top指向下一个节点,先前的节点释放。
#include "malloc.h" #include "stdio.h" #include "assert.h" #define OK 0 #define ERRO 1 typedef int status; typedef int SdataType; typedef struct Node { SdataType data; Node * next; }Node; typedef struct Stack { Node * top; int size; }Stack; //新建Stack Stack* createStack(void) { Stack* s = (Stack*)malloc(sizeof(Stack)); assert(s); s->top = NULL; s->size = 0; return s; } //因为有size成员,所以不需要判空函数 //入栈函数 status push(Stack* s, SdataType value) { Node * p = (Node *)malloc(sizeof(Node)); assert(p); p->data = value; p->next = s->top; s->top = p; s->size++; return OK; } status pop(Stack* s, SdataType* value) { if (s->size == 0) { printf("stack empty\n"); return ERRO; } else { Node* p = s->top; *value = s->top->data; s->top = s->top->next; free(p); s->size--; return OK; } } void showStack(Stack* s) { assert(s); if (s->size == 0 ) { printf("stack empty\n"); } else { Node* p = s->top; printf("top->"); while (p->next) { printf("%d ->", p->data); p = p->next; } printf("%d ->end\n", p->data); } } status destroyStack(Stack *s) { if (s->top) { int i; Node *p = s->top; for (i = 0; i < s->size; i++) { s->top = p->next; free(p); p = s->top; } free(s); assert(s); return OK; } else { printf("stack empty\n"); return ERRO; } } int main(int argc, char **argv) { Stack* s = createStack(); push(s, 1); push(s, 2); showStack(s); destroyStack(s); }
对于栈来说,我们只需要管好它的栈顶就行了,但是队列的话得两头都处理,所以表头结构体加一个队尾指针。并且在队列节点中增加了一个头结点,这时为了避免每次入队的时候判断是否时第一个节点带来的多余工作,头结点中内容为空。
#include "malloc.h" #include "stdio.h" #include "assert.h" #define OK 0 #define ERRO 1 typedef int status; typedef int QdataType; typedef struct Node { QdataType data; Node * next; }Node; typedef struct Queue { Node * head; Node * rear; int size; }Queue; //新建Queue Queue* createStack(void) { Queue* q = (Queue*)malloc(sizeof(Queue)); assert(q); Node* p = (Node*)malloc(sizeof(Node)); //头结点,其内容为空,只是为了入队时不必判断队为空 assert(p); p->next = NULL; p->data = 0; q->head = q->rear = p; q->size = 0; return q; } //尾部入,头部出 //进队函数 status enQueue(Queue* q, QdataType value) { Node * p = (Node *)malloc(sizeof(Node)); assert(p); p->data = value; p->next = NULL; q->rear->next = p; q->rear = p; q->size++; return OK; } status deQueue(Queue* q, QdataType* value) { if (q->size == 0) { printf("queue empty\n"); return ERRO; } else { Node* p = q->head->next; *value = q->head->next->data; q->head->next = q->head->next->next; free(p); q->size--; return OK; } } void showQueue(Queue* q) { if (q->size == 0 ) { printf("queue empty\n"); } else { Node* p = q->head->next; printf("head->"); while (p->next) { printf("%d ->", p->data); p = p->next; } printf("%d ->end\n", p->data); } } status destroyQueue(Queue *q) { if (q->size) { int i; Node *p = q->head; for (i = 0; i <= q->size; i++) { q->head = p->next; free(p); p = q->head; } free(q); return OK; } else { free(q); return ERRO; } } int main(int argc, char **argv) { Queue* q = createStack(); QdataType a = 0; QdataType* data = &a; enQueue(q, 1); enQueue(q, 2); enQueue(q, 3); showQueue(q); deQueue(q,data); showQueue(q); destroyQueue(q); return OK; }
相关文章推荐
- c++链表实现队列
- 队列的链表实现
- 数据结构:C_链表队列的实现
- 基于jdk的list 和 队列 linkedList 和父亲长子兄弟链表模型 实现的 树 的前序遍历,后序遍历和层次遍历
- 算法复习(6)链表实现的队列
- 数据结构栈和队列的数组实现和链表实现的4个头文件(完全个人思路)
- 栈和队列的基本实现(数组实现和链表实现)
- 数据结构之链表、栈和队列 java代码实现
- 用链表实现队列数据结构
- 队列的实现—由链表实现
- Java用链表实现队列
- 数据结构---队列的链表实现
- 两种方法实现队列---顺序表和链表
- 队列的链表实现
- 单链表操作,队列,栈实现,以及常见字符串库函数经典实现
- C++用模板实现双链表和队列
- 双向链表实现队列与循环链表
- 链表实现队列 c语言
- 数据结构示例之用链表实现顺序队列
- 数据结构-用链表实现队列