复习ppt第三课:栈和队列

1.顺序栈的存储结构定义

#define STACKINCREMENT 10
#define STACK_INIT_SIZE 100
typedef int SElemType
typedef struct {
	SElemType* base;
	SElemType* top;
	int stacksize;
}SqStack;

2.顺序栈基本操作的实现—初始化/销毁/置空等

Status InitStack(SqStack& S) {
	S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if (!S.base)
		exit OVERFLOW;
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;
	return OK;
}

思路:操作和线性表很像。首先栈底开辟空间,判断存储是否分配失败。进行空栈赋值处理。然后赋值栈空间大小。最后返回。

总结下来就是开辟空间,判断是否开辟成功,空栈处理,栈空间赋值处理。三步操作。

Status DestroyStack(SqStack& S) {
	free(S.base);
	S.base = NULL;
	S.top = NULL;
	S.stacksize = 0;
	return OK;
}

销毁空间,指针赋空,空间大小赋空。结束。

Status ClearStack(SqStack &S){
    S.top=S.base;  
    return OK;
} 

base指针永远指向栈底,top指针不停向上移动。当两指针指向相同时即为空栈。

Status StackEmpty(SqStack S)
{
	if (S.top == S.base)
		return TRUE; 
	else return FALSE;
}
int StackLength(SqStack S) 
{ 
	return (S.top - S.base); 
}
Status GetTop(SqStack S, SElemType& e) {
	if (S.top == S.base)
		return ERROR;
	e = *(S.top - 1);  //注意top指向待插入位置
	return OK;
}
Status StackTraverse(SqStack S, Status(*visit)(ElemType)) {
	//从栈底元素到栈顶元素依次执行visit函数,常用于输出栈中元素
	ElemType* p = S.base;
	while (p < S.top) {
		if (visit(*p) == ERROR)
			return ERROR;
		++p;
	}
	return OK;
}//除遍历操作外时间复杂度均O(1)

3.入栈与出栈

Status Push(SqStack& S, SElemType e) {
	if (S.top - S.base == stacksize) {
		S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType);
		if (!S.base)
			exit OVERFLOW;
		S.top = (S.base + S.stacksize);//使得S.top重新指向栈顶,因realloc
		S.stacksize += STACKINCREMENT;
	}
	*S.base=e;
	S.base++;
	return OK;
}

入栈Push:判断栈满,若满需要扩容,判断空间分配是否成功,栈顶位置改变,栈容量改变。

插入元素赋值,指针上移。

Status Pop(SqStack& S, SElemType& e) {
	if (S.top == S.base)
		return ERROR;
	e = *S.top;
	*S.top--;
	return OK;
}

出栈Pop:判断是否栈空,传回元素值,指针下移。

4.链栈的定义与实现

4.1存储结构定义

typedef struct StackNode{  
      SElemType data;
      struct SNode *next;
  }StackNode, *LinkStack;
  LinkStack S;

使用条件:不清楚栈元素数目

注意:链栈用无头结点的单链表表示。栈名指针S指向栈顶元素,而顺序栈栈顶指针指向第一个空位置。

4.2基本操作

5.队列

5.1存储结构定义

typedef struct {
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

5.2基本操作

5.2.1初始化

Status InitQueue(LinkQueue& Q) {
	Q.front = Q.rear = (QNode*)malloc((sizeof * (QNode));
	if (!Q.front)
		exit OVERFLOW;
	Q.front->next = NULL;
	return OK;
}

头指针和头结点

5.2.2销毁

Status DestroyQueue(LinkQueue& Q) {
	QueuePtr p = Q.front, postp;
	while (p) {
		postp=p->next
		free(p);
		p=postp;
	}
	Q.front = NULL;
	Q.rear = NULL;
	return OK;
}

代码有问题

清空要保留头节点,类比单链表操作

p=postp:pq指向同一位置,共享同一段内存

5.2.3入队

Status EnQueue(LinkQueue& Q, QElemType e) {
	QueuePtr p;
	p = (QNode*)malloc(sizeof * (QNode));
	if (!p)
		exit OVERFLOW;
	p->data = e;
	p->next = NULL;
	Q.rear->next = p;
	Q.rear = p;
	return OK;
}

入队的节点的指针域记得赋空。

    Q.rear->next = p;    尾指针是要不断往后移动的,尾指针的指针域链接新入队的节点,让p入队
    Q.rear = p;              尾指针指向最新的节点

5.2.4出队

Status DeQueue(LinkQueue& Q, QElemType& e) {
	if (Q.front == Q.rear)
		return ERROR;
	QueuePtr p = Q.front->next;
	e = p->data;
	Q.front->next = p->next;
	if (Q.rear == p)
		Q.rear = Q.front;
	return OK;
}

只1个结点时改尾指针

6.循环队列

Q.base[Q.rear] = e;

Q.base 指向动态分配的数组中的元素。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值