数据结构——栈和队列

目录

逻辑结构

基本操作

物理结构

顺序结构

链式存储

队列

逻辑结构

基本操作

物理结构

顺序结构

链式存储

栈和队列不是传统意义上的线性表,它们属于特殊的线性表

逻辑结构

定义:栈是只有一端能够插入删除的线性表。

 特点:后进先出(LIFO)

基本操作

初始化操作InitStack(&S):创建一个新栈S。

销毁操作DestroyStack(&S):销毁一个栈S。

进栈操作Push(&S,x):若栈未满,压栈。

出栈操作Pop(&S,&x):若栈不为空,弹栈。

读栈顶元素Get(S,&x):若栈不为空,读栈顶元素并用x带回。

判空操作Empty(S):判断栈S是否为空栈。

物理结构

顺序结构

栈的定义

#define MaxSize 10
typedef struct
{
	ElemType data[MaxSize];//栈空间
	int top;//栈顶位置
}Stack;

初始化操作InitStack(&S)

void InitStack(Stack &S)
{
	S.top=-1;	//栈顶元素加一才指向此次插入的元素
}

void InitStack(Stack &S)
{
	S.top=0;	//栈顶元素指向此次插入的元素
}

销毁操作DestroyStack(&S)

void DestroyStack(Stack &S)
{
	S.top=-1;
}

void DestroyStack(Stack &S)
{
	S.top=0;
}

判空操作Empty(S)

bool Empty(Stack S)
{
	if(S.top==-1)
		return true;
	return false;
}
bool Empty(Stack S)
{
	if(S.top==0)
		return true;
	return false;
}

进栈操作Push(&S,x)

bool Push(Stack &S,ElemType x)
{
	if(S.top==MaxSize-1)//栈满了
		return false;
	S.data[++S.top]=x;//先加一才能指到元素插入的位置
	return true;
}
bool Push(Stack &S,ElemType x)
{
	if(S.top==MaxSize)//栈满了
		return false;
	S.data[S.top++]=x;//栈顶指针指在插入元素位置,插入完元素加一
	return true;
}

出栈操作Pop(&S,&x)

bool Pop(Stack &S,ElemType &x)
{
	if(S.top==-1)//栈空
		return false;
	x=S.data[S.top--];//先把栈顶元素赋值给x再把栈顶指针减一删掉这个元素
	return true;	
}
bool Pop(Stack &S,ElemType &x)
{
	if(S.top==0)//栈空
		return false;
	x=S.data[--S.top];//栈顶元素在栈顶的下一个,栈顶先减一指向其
	return true;	
}

读栈顶元素Get(S,&x)

bool Get(Stack S,ElemType &x)
{
	if(S.top==-1)
		return false;
	x=S.data[S.top];
	return true;
}
bool Get(Stack S,ElemType &x)
{
	if(S.top==0)
		return false;
	ElemType y=S.top-1;
	x=S.data[y];
	return true;
}

链式存储

 栈的定义

typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode,*Stack;

初始化操作InitStack(&S)

void InitStack(Stack &S)//不带头结点
{
	S=NULL;	
}

判空操作Empty(S)

bool Empty(Stack S)
{
	if(S==NULL)//空栈
		return true;
	return false;
}

进栈操作Push(&S,x)

bool Push(Stack &S,ElemType x)
{
	LNode *p=(LNode *)malloc(sizeof(LNode));
	if(p==NULL)
	{
		return false;
	}
	p->data=x;
	p->next=S;
	S=p;
	return true;
}

出栈操作Pop(&S,&x)

bool Pop(Stack &S,ElemType &x)
{
	if(S==NULL)//空栈
	{
		return false;
	}
	x=S->data;
    LNode *p=S;
	S=S->next;
    free(p);
	return true;
}

读栈顶元素Get(S,&x)

bool Get(Stack S,ElemType &x)
{
	if(S==NULL)//空栈
	{
		return false;
	}
	x=S->data;
	return true;
}

队列

逻辑结构

定义:队列是只有一端能够插入,只有另一端能删除的线性表。

但其实在实际应用时逻辑结构应该采用循环队列,代码对物理结构的操作也是基于此种逻辑结构。

 

特点:先进先出(FIFO)

 

基本操作

初始化操作InitQueue(&q):创建一个新队列q。

销毁操作DestroyQueue(&q):销毁一个队列q。

入队操作InQueue(&q,x):若队未满,入队。

出队操作OutQueue(&q,&x):若队不为空,出队。

读队头元素Get(q,&x):若队列不为空,读队头元素并用x带回。

判空操作Empty(q):判队列是否为空。

判满操作IsFull(q):判断队列q是否为满。

队列长度Length(q):得到队列的长度。

物理结构

顺序结构

定义

#define MaxSize 10
typedef struct
{
	ElemType data[MaxSize];
	int front;//队头指针
	int rear;//队尾指针
}Queue;

InitQueue(&q)

void InitQueue(Queue &q)
{
	q.front=q.rear=0;
}

DestroyQueue(&q)

void DestroyQueue(Queue &q)
{
	q.front=q.rear=0;
}

InQueue(&q,x)

bool InQueue(Queue &q,ElemType x)
{
	if(IsFull(q)==true)
		return false;
	q.data[q.rear]=x;
	q.rear=(q.rear+1)%MaxSize;
	return true;
}

OutQueue(&q,&x)

bool OutQueue(Queue &q,ElemType &x)
{
	if(Empty(q)==true)//空队
	{
		return false;
	}
	x=q.data[q.front];
	q.front=(q.front+1)%MaxSize;
	return true;
}

Get(q,&x)

bool Get(Queue q,ElemType &x)
{
	if(Empty(q)==true)//空队
	{
		return false;
	}
	x=q.data[q.front];
	return true;
}

Empty(q)//浪费一个空间的情况

bool Empty(Queue q)
{
	if(q.front==q.rear)//
		return true;
	return false;
}

IsFull(q)//浪费一个空间的情况

bool IsFull(Queue q)//这里用浪费一个空间的办法
{
	if((q.rear+1)%MaxSize==q.front)
		return true;
	return false;
}

Length(q)

int Length(Queue q)
{
	if(Empty(q)==true)
	{
		return 0;
	}	
	if(IsFull(q)==true)
		return MaxSize-1;//因为浪费一个空间
	return (q.rear+MaxSize-q.front)%MaxSize;
}

不浪费空间判断队满队空的情况

(1)在队列结构体在定义一个size变量记录队元素个数。

(2)用flag变量记录上一步的操作是入队还是出队,入队1,出队0,如果头尾指针相同,上一步操作是1即队满,上一步为0即队空。

链式存储

定义

typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode;
typedef struct
{
	LNode *front,*rear;
}Queue;

InitQueue(&q)

bool InitQueue(Queue &q)//带头结点
{
	LNode *s=(LNode *)malloc(sizeof(LNode));
	if(s==NULL)
	{
		return false;
	}
	q.front=s;
	q.rear=s;
	s->next=NULL;
	return true;
}
bool InitQueue(Queue &q)//不带头结点
{
	q.front=NULL;
	q.rear=NULL;
	return true;
}

InQueue(&q,x)

bool InQueue(Queue &q,ElemType x)//带头结点
{
	LNode *s=(LNode *)malloc(sizeof(LNode));
	if(s==NULL)
		return false;
	s->data=x;
	s->next=NULL;
	q.rear->next=s;
	q=s;
	return true;
}

bool InQueue(Queue &q,ElemType x)//不带头结点
{
	LNode *s=(LNode *)malloc(sizeof(LNode));
	if(s==NULL)
		return false;
	s->data=x;
	if(Empty(q))
	{
		q.front=s;
		q.rear=s;
		return true;
	}
	s->next=NULL;
	q.rear->next=s;
	q=s;
	return true;
}

OutQueue(&q,&x)

bool OutQueue(Queue &q,ElemType &x)//带头结点
{
	if(Empty(q)==true)//空队
	{
		return false;
	}
	x=q.front->next->data;
	LNode *p=q.front->next;
	q.front->next=p->next;
	if(q.rear==p)
	{
		q.rear=q.front;
	}
	free(p);
	return true;
}

Get(q,&x)

bool Get(Queue q,ElemType &x)//带头结点
{
	if(Empty(q)==true)//空队
	{
		return false;
	}
	x=q.front->next->data;
	return true;
}
bool Get(Queue q,ElemType &x)//不带头结点
{
	if(Empty(q)==true)//空队
	{
		return false;
	}
	x=q.front->data;
	return true;
}

Empty(q)

bool Empty(Queue q)//带头结点
{
	if(q.front->next=NULL)//
		return true;
	return false;
}
bool Empty(Queue q)//不带头结点
{
	if(q.front=NULL)//
		return true;
	return false;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值