C语言数据结构-栈与队列

栈与队列

栈的定义

栈(stack)是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表尾端有其特殊含义,称为栈顶(top),相应的,表头端称为栈底(bottom)。不含元素的空表称为空栈。因为仅在表尾进行操作所以符合先进后出的规律。

栈的实现

栈的定义如下:

#define STACK_INIT_SIZE 100		//定义初始分配空间大小 
typedef struct {
    SElemType* base;			//栈顶 
    SElemType* top;				//栈底
    int stacksize;
}SqStack;

栈的初始化

栈的初始化需要先定义栈的大小,这个可以提前定义。

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 Delete(SqStack* S)//用e返回栈顶元素并删除栈顶元素
{
    if (S->top == S->base)//栈为空 
        return ERROR;
    S->top--;
    return OK;
}

栈的压入

栈的压入,先将栈顶元素压入,然后移动栈顶指针,这样就将元素压入。

Status Push(SqStack* S, SElemType e)//插入元素e为新的栈顶元素
{
	
	if (S->top - S->base >= S->stacksize)
    {
        S->base = (SElemType*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));//分配新储存空间 
        if (!S->base) exit(OVERFLOW);	//分配空间失败 
        S->top = S->base + S->stacksize;
        S->stacksize += STACKINCREMENT;
    }
    *S->top++ = e;
    return OK;
}

栈顶元素的取出

一下函数中Pop函数与GetTop函数类似,但是还是有区别所以功能上也有不同。由于Pop函数中栈用的是指针,所以栈顶指针会移动,则会删除栈顶元素并返回栈顶元素。而GetTop函数没有用到指针,只会返回栈顶元素不会删除栈顶元素。

Status Pop(SqStack* S, SElemType* e)//用e返回栈顶元素并删除栈顶元素
{
    if (S->top == S->base)//栈为空 
        return ERROR;
    *e = *(--S->top);
    return OK;
}

Status Delete(SqStack* S)//删除栈顶元素
{
    if (S->top == S->base)//栈为空 
        return ERROR;
    S->top--;
    return OK;
}

Status GetTop(SqStack S, SElemType* e)//返回栈顶元素
{
    if (S.top == S.base)//栈为空 
        return ERROR;
    *e = *(--S.top);
    return OK;
}

队列的定义

和栈相反,队列(queue)是一种先进先出的线性表它只允许在表的一端进行插入,而再另一端删除元素。在队列中,允许插入的一端叫做队尾(rear),允许删除的一端则称为队头(front)。
有时为了节省空间会有双端队列,还有循环队列等。

队列的实现

队列的定义如下:

typedef struct {
	QueuePtr front;            // 队头指针 
	QueuePtr rear;             // 队尾指针 
}LinkQueue;

队列的初始化

Status InitQueue(LinkQueue &Q)				// 创建一个新队列
{
	Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
	if(!Q.front) exit(OVERFLOW);         // 分配存储失败 
	Q.front->next = NULL;
	return OK;
}

队列的删除

队列的删除与栈的删除类似,使对头和队尾相连即可

Status DestroyQueue(LinkQueue &Q)			// 销毁队列 
{
	while(Q.front){
		Q.rear = Q.front->next;
		free(Q.front);
		Q.front = Q.rear;
	} 
	return OK;
}

队列的插入

Status EnQueue(LinkQueue &Q, QueuePtr s)	// 插入元素 e 为 Q 的新的队列元素 
{
	s->next = NULL;                // 队尾 next == NULL,有 data 
	Q.rear->next = s;
	Q.rear = s;                    // 更新队尾 
	return OK; 
}

队头元素的取出

Status DeQueue(LinkQueue &Q, QElemType &e)		//用于返回路径 
		// 若对头不空,则删除对头元素,用 e 返回其值,并返回 OK,否则返回 ERROR
{
	if(Q.front == Q.rear) return ERROR;
	QueuePtr p = Q.front->next;         // Q.front 没有 data, next != NULL(除非空队列) 
	e = p->data;
	Q.front->next = p->next;            // 更新队头 
	if(Q.rear == p) Q.rear = Q.front;   // 队列为空了 
	free(p);
	return OK;
}

以上便是栈与队列的基本操作,我的知识有限,如果大家有其他想法可以提出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值