链栈与链队列
程序员文章站
2022-07-14 13:09:07
...
链栈
链栈的定义
- 栈的链式存储结构
链栈:即用链表实现栈存储结构
栈顶:允许插入和删除的一端(top)
栈底:不同于栈顶的另外一端(bottom)
空栈:不含任何元素的栈
链栈实际上就是一个只能采用头插法插入或删除数据的链表
//链栈表示
struct link{
int data;
struct link *next;
};
//链栈初始化
void initstack(struct link *top){
top=(struct link *)malloc(sizeof(struct link));
top->next =NULL;
}
1.入栈
入栈关键三步:
- 给待插入结点p的数据域赋值
- 将结点p指向当前top指向的结点
- 将top指针移动到p结点之上
//入栈
int push(struct link *top,int x){
struct link *p;
p=(struct link *)malloc(sizeof(struct link));
if(!p)
return ERROR;
p->data=x;
p->next=top->next;
top->next =p;
return OK;
}
2.出栈
出栈关键两步:
- 将top指针指向的下一结点地址赋给p,p为待删除结点的地址
- 将top指针下移
//出栈
int pop(struct link *top,int *x){
struct link *p;
p=top->next ;
if(p==NULL){
printf("栈为空\n");
return OVERFLOW;
}
top->next =p->next ;
*x=p->data ;
free(p);
return OK;
}
3.整体代码和实现情况
#include<stdio.h>
#include<malloc.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
//链栈表示
struct link{
int data;
struct link *next;
};
//链栈初始化
void initstack(struct link *top){
top=(struct link *)malloc(sizeof(struct link));
top->next =NULL;
}
//入栈
int push(struct link *top,int x){
struct link *p;
p=(struct link *)malloc(sizeof(struct link));
if(!p)
return ERROR;
p->data=x;
p->next=top->next;
top->next =p;
return OK;
}
//出栈
int pop(struct link *top,int *x){
struct link *p;
p=top->next ;
if(p==NULL){
printf("栈为空\n");
return OVERFLOW;
}
top->next =p->next ;
*x=p->data ;
free(p);
return OK;
}
int main(){
struct link top;
initstack(&top);
int a;
int i,j;
for(i=5;i>0;i--){
push(&top,i);
printf("入栈元素为:%d\n",i);
}
for(j=5;j>0;j--){
pop(&top,&a);
printf("出栈元素为:%d\n",a);
}
return 0;
}
链队列
链队列的定义
-
用单链表实现先进先出的队列链式存储结构
对于链表依旧是数据域+指针域
但为了清楚表示队列的队头与队尾使用了队头指针和队尾指针
当队列为空时,队头指针=队尾指针
队列只能从队头出,队尾入,即入则改队尾指针,出则改队头指针
//单链队列
struct node{
int data;
struct node *next;
};
struct linkqueue{
struct node *front; //队头指针
struct node *rear; //队尾指针
};
//创建一个空队列
int initqueue(struct linkqueue *q){
q->front=q->rear=(struct node *)malloc(sizeof(struct node));
if(!q->front )
return OVERFLOW;
q->front->next =NULL;
return OK;
}
1.入队列
入队列关键三步:
- 入队结点指向空,给待插结点的数据域赋值
- 将新结点的地址赋给当前队尾结点的指针域
- 将队尾指针指向插入后的新结点
//入队
int enqueue(struct linkqueue *q,int x){
struct node *p=(struct node *)malloc(sizeof(struct node));
if(!p)
return OVERFLOW;
p->data =x;
p->next =NULL;
q->rear->next =p;
q->rear=p;
}
2.出队列
出栈关键两步:
- p指向待删除的结点
- 将队头指针的下一个指向待删除结点的下一个
//出队
int dequeue(struct linkqueue *q,int *x){
if(q->front ==q->rear )
return ERROR;
struct node *p=(struct node *)malloc(sizeof(struct node));
p=q->front->next ;
*x=p->data;
q->front->next =p->next ;
if(q->rear ==p)
q->rear =q->front ;
free(p);
return OK;
}
注意有一个特殊情况:
当队列中的最后一个元素被删后,队尾指针也丢失了。因此要对队尾指针重新赋值,即指向头结点。
3.整体代码和实现情况
#include<stdio.h>
#include<malloc.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
//单链队列
struct node{
int data;
struct node *next;
};
struct linkqueue{
struct node *front; //队头指针
struct node *rear; //队尾指针
};
//创建一个空队列
int initqueue(struct linkqueue *q){
q->front=q->rear=(struct node *)malloc(sizeof(struct node));
if(!q->front )
return OVERFLOW;
q->front->next =NULL;
return OK;
}
//入队
int enqueue(struct linkqueue *q,int x){
struct node *p=(struct node *)malloc(sizeof(struct node));
if(!p)
return OVERFLOW;
p->data =x;
p->next =NULL;
q->rear->next =p;
q->rear=p;
}
//出队
int dequeue(struct linkqueue *q,int *x){
if(q->front ==q->rear )
return ERROR;
struct node *p=(struct node *)malloc(sizeof(struct node));
p=q->front->next ;
*x=p->data;
q->front->next =p->next ;
if(q->rear ==p)
q->rear =q->front ;
free(p);
return OK;
}
int main(){
struct linkqueue q;
initqueue(&q);
int a;
int i,j;
for(i=5;i>0;i--){
enqueue(&q,i);
printf("入队元素为:%d\n",i);
}
for(j=5;j>0;j--){
dequeue(&q,&a);
printf("出队元素为:%d\n",a);
}
return 0;
}
上一篇: 【翻译】Spring Integration参考手册-第二章
下一篇: jaxb的类型绑定