数据结构 第三章 栈和队列 习题

3.1

栈的顺序存储结构

顺序栈的实现

顺序存储

# define MaxSize 50
typedef struct{
   
	Elemtype data[MaxSize];
	int top;	//栈顶指针
}SqStack;

栈顶指针:S.top,初始时设置S.top=-1;
栈顶元素:S.data[S.top];
进栈操作:栈不满时,栈顶指针先加1,再赋值到栈顶元素;
出栈操作:栈非空时,先取栈顶元素值,再将栈顶指针减1;
栈空条件:S.top==-1;
栈满条件:S.top==MaxSize-1;
栈长:S.top+1

初始化

void InitStack(SqStack &S){
   
	S.top=-1;
}

判断栈空

bool StackEmpty(SqStack S){
   
	return S.top==-1
}

进栈

bool Push(SqStack &S, ElemType x){
   
	if(S.top==MaxSize-1)
		return false;
	S.data[++S.top]=x;
	return true;
}

出栈

bool Pop(SqStack &S, ElemType &x){
   
	if(S.top==-1)
		return false;
	x=S.data[S.top--]
	return true;
}

读栈顶元素

bool GetTop(SqStack S, ElemType &x){
   
	if(S.top==-1)
		return false;
	x=S.data[S.top];
	return true;
}

共享栈

栈底位置相对不变,两个顺序栈共享一个一维数组,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间中间延伸。
共享栈
top0=-1 0号栈为空;top1=MaxSize 1号栈为空
当top1-top0=1时,栈满。
0号栈进栈,top0先+1后赋值;1号栈进栈,top1先-1再赋值。

栈的链式存储结构

定义

typedef struct Linknode{
   
	ElemType data;
	struct Linknode *next;
}*LiStack;

习题3.1

3.1.1
CDEBA
CDBEA
CDBAE

3.1.2
BCAED可,其操作为A进、B进、C进、C出、B出、D进、E进、E出、D出、A出
DBACE不可,因为D最先出,说明栈内已经有ABC,则B和A不可能在C前出。

3.1.3
1)A、C、D合法
2)

int judge(ElemType A, int n){
   
	int count = 0;
	for(int i=0;i<n;i++){
   
		if(A[i]=='I')
			count++;
		else
			count--;
		if(count < 0)
			return 0;
	}
	return 1;
}

3.1.4

int dc(LinkList L, int n){
   
	int i;
	char s[n/2];
	p=L->next;
	for(i=0;i<n/2;i++){
   
		s[i]=p->data;
		p=p->next;
	}
	i--;	//恢复最后的i值
	if(n%2==1)
		p=p->next;
	while(p!=NULL&&s[i]==p->data){
   
		i--;
		p=p->next;
	}
	if(i==-1)
		return 1;
	else
		return 0;
}

3.1.5
入栈

int push(int i, elemtp x){
   
	if(i<0||i>1){
   
		printf("栈号输入不对");
		exit(0);
	}
	if(s.top[1]-s.top[0]==1){
   
		printf("栈已满\n");
		return 0;
	}
	switch(i){
   
		case 0: s.stack[++s.top[0]]=x;
				return 1;
				break;
		case 1: s.stack[--s.top[1]]=x;
				return 1;
	}
}

出栈

int pop(int i, elemtp x){
   
	if(i<0||i>1){
   
		printf("栈号输入不对");
		exit(0);
	}
	switch(i){
   
		case 0:
			if(s.top[0]==-1){
   
				printf("0栈空\n");
				return -1;
			}
			else
				return s.stack[s.top[0]--];
			break;
		case 1:
			if(s.top[1]==maxsize){
   
				printf("1栈空\n");
				return -1;
			}
			else
				return s.stack[s.top[1]++]
	}
}

3.2

队列的顺序存储结构

队列的顺序存储

队列的顺序实现:分配一块连续的存储单元存放队列中的元素,并附设两个指针:队头指针front指向队头元素,队尾指针rear指向队尾元素的下一个位置。

#define MaxSize 50
typedef struct{
   
	ElemType data[MaxSize];
	int front, rear;
}SqQueue;

初始状态(队空条件):Q.frontQ.rear0;
进队操作:队不满时,先送值到队尾元素,再将队尾指针+1;
出队操作:队不空时,先取队头元素,再将队头指针+1;

单纯的队列会导致假溢出,明明有存储空间,但因为指针指向队尾,无法再向队列中存放元素

循环队列

初始状态:Q.frontQ.rear0;
队首指针进1:Q.front=(Q.front+1)%MaxSize;
队尾指针进1:Q.rear=(Q.rear+1)%MaxSize;
队列长度:(Q.rear+MaxSize-Q.front)%MaxSize
出队入队时:指针都按顺时针方向进1
由于队空和队满有三种处理方式:

  1. 牺牲一个单元来区分队空和队满,入队时少用一个队列单元,约定以“队头指针在队尾指针的下一位置作为队满的标志”,
    队满条件:(Q.rear+1)%MaxSizeQ.front
    队空条件:Q.front
    Q.rear
    队列中元素的个数:(Q.rear-Q.front+MaxSize) %MaxSize
  2. 类型中增设一个元素个数。这样队空条件为Q.size0;队满的条件为Q.sizeMaxSize.(都可能出现Q.front==Q.rear)
  3. 类型中增设tag,区分队满队空,tag=0时,若因删除导致Q.frontQ.rear,则为队空;tag=1时,若因插入导致Q.frontQ.rear,则为队满。

初始化

void InitQueue(SqQueue &Q){
   
	Q.rear=Q.front=0;
}

判断队空

bool isEmpty(SqQueue Q){
   
	if(Q.rear=Q.front)
		return true;
	else return false;
}

入队

bool EnQueue(SqQueue &Q, ElemType x){
   
	if((Q.rear+1)%MaxSize==Q.front)
		return false;
	Q.data[Q.rear]=x'
	Q.rear=(Q.rear+1)%MaxSize
}

出队

bool DeQueue(SqQueue &Q, ElemType &x){
   
	if(Q.rear==Q.front) 
		return false;
	x=Q.data[front];
	Q.front=(Q.front+1)%MaxSize;
	return true;
}

队列的链式存储结构

队列的链式存储

队列的链式表示是一个同时带有队头指针和队尾指针的单链表。

typedef struct{
   
	ElemType data;
	struct LinkNode *next;
}LinkNode;

typedef struct{
   
	LinkNode *front, *rear;
}LinkQueue;

当Q.frontNULL&&Q.rearNULL时,链式队列为空。

单链表的链式队列表示适合于数据元素变动比较大的情形,且不存在列满溢出的情况。

链式队列的基本操作

初始化

void InitQueue(LinkQueue &Q){
   
	Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
	Q.front->next=NULL;
}

判队空

bool IsEmpty(LinkQueue Q){
   
	if(Q.front==Q.rear)
		return true;
	else
		return false;
}

入队

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值