- 栈与队列的区别
- 动态栈
- 链式队列
- 循环队列
区别
1 队列先进先出,栈先进后出(栈类似于箱子)
2 对插入和删除操作的限定不同
栈是限定只能在表的一端进行插入和删除操作的线性表
队列是限定只能在表的一端进行插入,在另一端进行删除操作的线性表
3 遍历数据速度不同
栈只能从头部取数据,也就最先放入的需要遍历整个栈最后才能取出来,而且在遍历数据的时候还得为数据开辟临时空间,保持数据在遍历前后的一致性。
队列则不同,它基于地址指针进行遍历,而且可以从头或尾部开始遍历,但不能同时遍历,无需开辟临时空间,因为在遍历的过程中不影像数据结构,速度要快的多。
动态栈算法演示图
动态栈的实现
#include链式队列#include typedef struct Node { int data; struct Node *next; }NODE, *PNODE; typedef struct Stack { PNODE pTop; PNODE pBottom; }STACK, *PSTACK; void init(PSTACK S) { S->pTop = (PNODE)malloc(sizeof(NODE)); if(S->pTop == NULL){ printf("动态分配失败n"); exit(-1); }else{ S->pBottom = S->pTop; S->pTop->next = NULL; } } void push(PSTACK S,int a) { PNODE new = (PNODE)malloc(sizeof(NODE)); new->data = a; new->next = S->pTop; S->pTop = new; } int pop(PSTACK S) { int data=0; if (S->pTop == S->pBottom) { return 0; }else{ PNODE r = S->pTop; data = r->data; S->pTop = r->next; free(r); r = NULL; return data; } } void print(PSTACK S) { PNODE p = S->pTop; if (S->pTop == S->pBottom) { printf("空栈n"); return; } while(p != S->pBottom) { printf("%d ",p->data); p=p->next; } putchar('n'); } void clear(PSTACK S) { if (S->pTop == S->pBottom) { return; }else{ PNODE p = S->pTop; PNODE q = NULL; while(p != S->pBottom){ q = p->next; free(p); p = q; } S->pTop = S->pBottom; } } int main() { STACK S; // STACK 等价于 struct Stack init(&S); push(&S,1); //入栈 push(&S,44); push(&S,22); push(&S,36); push(&S,67); int a = pop(&S); //假设出栈失败返回0 if(a != 0){ printf("出栈:%dn",a); } a = pop(&S); if(a != 0){ printf("出栈:%dn",a); } print(&S); //栈 先进后出 clear(&S); //清空 print(&S); return 0; }
链式队列算法演示图
链式队列实现
#include循环队列#include typedef struct Node { int data; struct Node *next; }NODE, *PNODE; typedef struct Queue { PNODE pTop; PNODE pBottom; }Queue, *PQueue; void init(PQueue S) { S->pTop = (PNODE)malloc(sizeof(NODE)); if(S->pTop == NULL){ printf("动态分配失败n"); exit(-1); }else{ S->pBottom = S->pTop; S->pTop->next = NULL; } } void push(PQueue Q,int a) { PNODE new = (PNODE)malloc(sizeof(NODE)); Q->pBottom->next = new; Q->pBottom = new; new->data = a; new->next = NULL; } int pop(PQueue Q) { int data=0; if (Q->pTop == Q->pBottom) { return 0; }else{ PNODE r = Q->pTop->next; //pHead不是要删除的队首元素,pHead->pNext所指向的元素才是要删除的元素, Q->pTop->next = r->next; data = r->data; free(r); return data; } } void print(PQueue Q) { PNODE p = NULL;//结点指针 if (Q->pTop == Q->pBottom) { printf("空队列n"); return; } printf("链式队列数据: "); p = Q->pTop->next;//第一个有效结点 while (p != NULL)//最后一个结点结束 { printf("%d ", p->data);//结点数据 p = p->next;//下一个结点 } printf("rn"); } void clear(PQueue S) { if (S->pTop == S->pBottom) { return; }else{ PNODE p = S->pTop; PNODE q = NULL; while(p != S->pBottom){ q = p->next; free(p); p = q; } S->pTop = S->pBottom; } } int main() { Queue S; // Queue 等价于 struct Queue init(&S); push(&S,1); //入队 push(&S,44); push(&S,22); push(&S,36); push(&S,67); print(&S); int a = pop(&S); //假设出栈失败返回0 if(a != 0){ printf("出队:%dn",a); } a = pop(&S); if(a != 0){ printf("出队:%dn",a); } print(&S); //队列 先进先出 clear(&S); //清空 print(&S); return 0; }
循环队列的讲解:
1)队列初始化
front和rear的值都是零
2)队列非空
front代表队列的第一个元素
rear代表了最后一个有效元素的下一个元素
3)队列空
front和rear的值相等,但是不一定是零
循环队列入队
1)将值存入r所代表的位置
2)将r后移,正确写法是 rear = (rear+1)%数组长度
循环队列出队:front = (front+1) % 数组长度
如何判断循环队列是否为空:Q->front == Q->rear
如何判断循环队列是否已满:if( (r+1)%数组长度 == f )
循环队列实现
#include#include typedef struct Queue { int *pbase; int front; //队首 int rear; //队尾的下一个元素 }QUEUE; void init(QUEUE *Q) { Q->pbase = (int *)malloc(sizeof(int)*6); Q->front = 0; Q->rear = 0; } void en_queue(QUEUE *Q,int a) { if((Q->rear + 1) % 6 == Q->front){ printf("入队失败n"); return; }else{ Q->pbase[Q->rear] = a; Q->rear = (Q->rear+1)%6; } } void print(QUEUE *Q) { int i = Q->front; while(i != Q->rear){ printf("%d ",Q->pbase[i]); i = (i+1)%6; } putchar('n'); return; } int out_queue(QUEUE *Q) { int data; if(Q->front == Q->rear){ printf("空队列n"); return 0; }else{ data = Q->pbase[Q->front]; Q->front = Q->front+1; return data; } } int main() { int data; QUEUE Q; init(&Q); en_queue(&Q,1); en_queue(&Q,2); en_queue(&Q,3); en_queue(&Q,4); en_queue(&Q,5); en_queue(&Q,6); print(&Q); data = out_queue(&Q); if(data != 0){ printf("出队:%dn",data); } data = out_queue(&Q); if(data != 0){ printf("出队:%dn",data); } data = out_queue(&Q); if(data != 0){ printf("出队:%dn",data); } print(&Q); return 0; }



