栈,队列

线性表的插入和删除只能在一端进行,这种线性表即为栈,允许插入删除的一端为栈顶。(栈是先进后出)

栈的生成方式:

向下生成的栈。栈顶在高地址端(下方)。 入栈为top++,出栈为top-- ;

向上生成的栈。栈顶在低地址端(上方)。入栈为top--,出栈为top++;

栈顶指针有两种指示方式:

栈顶指针指向空单元 ;

栈顶指针指向最后写入的元素。

根据栈顶指针的指示方式不同,入栈和出栈时的指针操作也不同。

例如: 栈顶指向空单元时。  入栈时先写元素,后修改栈顶指针。出栈时先修改栈顶指针,后读元素。

栈:

1静态顺序栈 ,即用数组描述。(初始化时,top = -1 ) 默认也是指向栈顶元素。

2动态顺序栈 ,定义一个栈时,预先值定义栈的头结点类型,栈存储空间动态申请。(有一个top指针(栈顶),一个base指针(栈底)) 。


双栈 ,  为了共享存储空间,两个栈用一块存储空间存放,两栈栈顶相对()。当这段存储空间用完,即两个栈顶指针相邻。

多栈 。


初始化一个栈:

先调用malloc申请栈空间 (即栈满时所用的存储空间)。 S.base =   -----malloc -------

判断是否申请成功。if(!S.base)  exit (OVERFLOW) ;

申请成功后, S.top = S.base ;再返回OK。


realloc , 改变指针所指存储空间大小    realloc(*ptr , size) ,size可大于原先内存,也可小于原先内存(会丢失数据) ,此函数需要包含 stdlib.h  ,有的要包含 malloc.h

入栈操作:

先判断是否栈满 if(S.top — S.base >= MAXSIZE)  

栈满,再申请存储空间  S.base =  realloc(S.base , size)

修改栈顶指针,  S.top = S.stacksize + S.base (stacksize为原栈大小)

入栈     S[top++] =  e ;  return OK;


出栈操作:

先判是否空栈 , 

出栈 e = S[top--] 


链栈 ,可对应链表,只不过多了了栈元素的节点类型的top指针。

(链栈为空时,top == NULL ,链栈为非空时,top 指向最头结点,即最后一个进栈的节点)

链栈 入栈: 

先申请一个节点空间, 并让节点存储数据,

再类似于单链表的头插法。  S->next = top ; top = s ;

链栈 出栈:

先判是否空栈 if(!top) return ERROR ;

否则 ,  e = top->data ; p = top ; top = top ->next ; free (p) ;


队列:

限制线性表的插入在表一端进行(队尾),限制线性删除的一端称为(队首)。

链队:

链式存储的队列


链队进(Q封装了队列的队首和队尾指针)

队尾进,先申请节点, --- malloc --- ;(假设要进队列的节点为p)

p->next = NULL  ; Q.rear = p ; return OK ;



链队出 

先判断是否空队列(Q.rear == Q.front)

非空队列,则队首出。 p = Q.front->next ; e = p->data ; Q.front->next = p->next ; (从队首删除了一个元素)

再判尾节点是否为p,即删除的节点是否为尾节点,(Q.rear == p) ,如果是,则为空队列,Q.rear = Q.front ; free(p); return OK ;


清空链队列:

p = Q.front ->next ; while(p) { q = p ;  p = p->next ; free q ; }   Q.rear = Q.front (尾指针指向头结点);

撤销链队类(与清空链队列的区别是将释放头节点的内存空间,即 free(Q.front) //并让头指针和尾指针指向相同节点):

while(Q.front) { Q.rear = Q.front->next ; free(Q.rear);Q.front = Q.rear ;} 


顺序队列(队尾进,队首出)

顺序队列,包含队列存储空间首地址,队头队尾指针(数组的索引)

申请一个顺序队的存储空间:Q.base = (Q--- *) malloc (MAXSIZE * sizeof(Q---));

由于空队时, Q.front = Q.rear = -1 。则入队时,Q.base[ ++Q.rear] =  e ; 出队时为,e = Q.base[++Q.front] ;

顺序队列的“假溢出”现象。(即随着进队出队的不断进行,会使队列整体向后移动,就会出现队尾指针移到最后,但是存储空间却并未被完全占满,即队首前还有空间未被占用。)

此时队列的长度为 rear - front 


循环队列:

入队时: Q.rear = (Q.rear+1)% MAXSIZE ;

出队时: Q.front = (Q.front+1)%MAXSIZE; 

此时队列的长度为 length = (Q.rear - Q.front + MAXSIZE)% MAXSIZE      加上MAXSIZE是为了防止队满情况时(front == rear)

队空和队满均为 front == rear 的解决办法

1是:定义一个存储队列中元素个数的变量NUM ,当NUM为0时,队空,当NUM为MAXSIZE时,对满。

2是:牺牲一个元素空间,队满的情况为,(rear+1)%MAXSIZE == front  ;

 

入队操作, Q.rear  = (Q.rear+1)%MAXSIZE ;

 Q.base[Q.rear] = item ; return OK ;

出队操作, Q.front = (Q.front+1)%MAXSIZ ;

item = Q.base[Q.front] ; // 书上的顺序与此相反,但我觉得有问题。因为front指向空,所以应该先操作指针再进行读取元素。


双端队列 , 在两端都可以进行入队和出队操作的队列称为双端队列。这种队列可以看成是由两个对底的双栈所构成的队列。


其中,双端队列还可细分为:

输入受限双端队列,即允许在一端只进行插入操作,在另一端可以进行插入和删除。

输出受限双端队列,允许在一端只进行删除操作,在另一端可以进行插入和删除。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值