栈与队列

 栈的本质就是一个线性表,也分有顺序存储和链式存储(一般用到顺序存储结构)。
 特点:先进后出,只能对队尾操作

 最开始栈中不含有任何数据,栈顶即栈底,也称作空栈。
 栈顶是指有效地址之后的一个元素地址

顺序存储栈结构

定义一个栈结构:

typedef int Elemtype;
typedef struct
{
	Elemtype *base;	//指向栈底
	Elemtype *top;	//指向栈顶
	int stackSize;	//栈的最大容量
}sqStack;

初始化栈:

#define Init_SIZE 100;
InitStack(sqStack *s)
{
	s->base = (Elemtype *)malloc(Init_SIZE*sizeof(Elemtype));
	if(!s->base)
	{exit(0)};
	s->top = s->base;		//栈顶就是栈底
	s->stacksize = Init_SIZE;
}

压栈:

#define Increment 10

Push(sqstack *s,Elemtype e)
{
	if(s->top - s->base > = s->stackSize)//栈已满
		{
		 s->base = (Elemtype *)realloc(s->base,(s->stackSize + Increment)*sizeof(Elemtype));//扩栈
		 if(!s->base)
		 exit(0);
		 s->top = s->base + s->stackSize;//设置栈顶
		 s->stackSize = s->stackSize + Increment; 
		}
	
	*(s->top) = e;
	(s->top)++;
}

出栈:

Pop(sqstack *s,Elemtype *e)
{
	if(s->base = s->top)//空栈
		return;
	(s->top)--;		//*base=1,*(base+1) = 2,top指向 base+2
	*e = *(s->top);
}

清空栈:

Clearstack(sqstack *s)
{
	s->top=s->base;
}
//使得栈顶等于栈尾,并不清空物理空间(栈容量),直接清空栈列表中的元素。

销毁栈:

DestroyStack(sqstack *s)
{
	int i,len;
	len = s->stackSize;
	for(i = 1;i < len ;i++){
		free(s->base);
		s->base++;
	}
	s->base = s->top = NULL;
	s->stackSize = 0;
}

计算栈的当前容量:

int stacklen(sqstack s)
{
	return(s->top - s->base);//指针允许相减(不能相加)
}

链式存储栈结构

typedef char Elemtype;
typedef struct StackNode
{
    Elemtype data;//栈元素
    struct StackNode *Next;//Next为前一栈
}StackList,*LinkStackPtr;

typedef struct LinkStack
{
    LinkStackPtr top;//栈顶-指向最末的有元素栈
    int count;
}

void InitStackList(LinkStack *s)
{
    s->top = NULL;
    s->count = 0;
}
void Push(LinkStack *s,Elemtype e)
{
    p = (LinkStackPtr)malloc(sizeof(StackNode));
    p->data = e;
    p->next = s->top;
    s->top = p;
    (s->count)++;
}

void Pop(LinkStack *s,Elemtype *e)
{
    LinkStackPtr p;
    if (s->top == NULL)
    {
        return 1;
    }
    *e = s->top->data;
    p = s->top;
    s->top = s->top->next;
    free(p);
    (s->count)--;
}



队列

与栈结构相同,队列也是一种重要的线性结构。
实现一个队列,同样需要顺序表或者链表作为其基础。
重要特点:先进先出,只允许一端入列操作,另一端出列操作。栈一般我们用顺序表来实现,而队列我们常用链表来实现,简称为链队列

 链队列

定义一个链队列结构:

typedef struct QNode
{
	Elemtype data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef struct 
{
	QueuePtr front,rear;//队头,队尾
}LinkQueue;
//空队列时,头尾都指向头结点

初始化:

InitQueue(LinkQueue *q)
{
	q->front = q->rear =(QueuePtr)malloc(sizeof(QNode));
	if(q->front == NULL)
	{	
		return 1;
	}
	q->front->next = NULL;
}
//入列
InsertQueue(LinkQueue *q,Elemtype e)
{
	QueuePtr temp = (QueuePtr)malloc(sizeof(QNode));
	temp->data = e;
	p->next = NULL;
	q->rear->next = temp;
	q->rear = temp;
}
//出列
DeleteQueue(LinkQueue *q,Elemtype *e)
{
	QueuePtr temp;
	if(q->front == q->rear)
	{	
		return 1;//空队列
	}
	temp = q->front->next;
	if(q->rear == temp)
	{
		q->rear = q->front;//只有一个结点的特殊情况
	}
	*e = temp->data;
	q->front->next = temp->next;
	free(temp);
}
//销毁
DestoryQueue(LinkQueue *q)
{
	while(q->front){
	q->rear = q->front->next;
	free(q->front);
	q->front = q->rear;
	}
}

 顺序存储队列

顺序存储结构:
  假设有一个n个元素,那么必须创建一个大于n的顺序队列(数组最后一个空间是不用的),使用循环队列逻辑,解决效率(普通队列数组,加入时‘O(1)’,推出时则要’O(n)’)和“假溢出”的问题。

 取模运算:商永远不会大于除数。

#define MaxSize 100

typedef struct
{
	Elemtype *base;
	int front;
	int rear;
} * CycleQueue

InitQueue(CycleQueue *q)
{
	q->base = (Elemtype *)malloc(Maxsize * sizeof(Elemtype));
	if(q->base == NULL)
	{
		exit(1);
	}
	q->front = q->rear = 0;
}

InsertQueue(CycleQueue *q,Elemtype e)
{
	if((q->rear +1)%MaxSize == q->front)
	{return;}//队列已满,数组最后一个空间是不用的
	q->base[q->rear] = e;
	q->rear = (q->rear+1) % MaxSize;//取模运算,永远不大于被除数
}

DeleteQueue(CycleQueue *q,Elemtype *e)
{
	if(q->front == q->rear)
	{return;}//空队列
	*e = q->base[q->front];
	q->front = (q->front+1) % MaxSize;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值