栈与队列的区别
区别
1 队列先进先出,栈先进后出(栈类似于箱子)
2 对插入和删除操作的限定不同
栈是限定只能在表的一端进行插入和删除操作的线性表
队列是限定只能在表的一端进行插入,在另一端进行删除操作的线性表
3 遍历数据速度不同
栈只能从头部取数据,也就最先放入的需要遍历整个栈最后才能取出来,而且在遍历数据的时候还得为数据开辟临时空间,保持数据在遍历前后的一致性。
队列则不同,它基于地址指针进行遍历,而且可以从头或尾部开始遍历,但不能同时遍历,无需开辟临时空间,因为在遍历的过程中不影像数据结构,速度要快的多。
动态栈
动态栈算法演示图
动态栈的实现
#include <stdio.h>
#include <stdlib.h>
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("出栈:%d\n",a);
}
a = pop(&S);
if(a != 0){
printf("出栈:%d\n",a);
}
print(&S); //栈 先进后出
clear(&S); //清空
print(&S);
return 0;
}
链式队列
链式队列算法演示图
链式队列实现
#include <stdio.h>
#include <stdlib.h>
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("\r\n");
}
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("出队:%d\n",a);
}
a = pop(&S);
if(a != 0){
printf("出队:%d\n",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 <stdio.h>
#include <stdlib.h>
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("出队:%d\n",data);
}
data = out_queue(&Q);
if(data != 0){
printf("出队:%d\n",data);
}
data = out_queue(&Q);
if(data != 0){
printf("出队:%d\n",data);
}
print(&Q);
return 0;
}