第3章 栈和队列

一、栈

1.定义及特点

(1)定义:

栈(stack)是一种只能在同一端进行插入或删除操作的线性表。

(2)主要特点:

1. 后进先出,即后进栈的元素先出栈。

2. 每次进栈的元素都作为新栈顶元素,每次出栈的元素只能是当前栈顶元素。

3. 栈也称为后进先出表或者先进后出表。

2. 栈的顺序存储结构及其基本运算算法实现

(1)顺序栈:

四要素:

① 栈空条件:len(data)==0或者not data。

② 栈满条件:由于data列表可以动态扩展,所以不必考虑栈满。

③ 元素e进栈操作:将e添加到栈顶处。

④ 出栈操作:删除栈顶元素并返回该元素。

class SqStack:
  def __init__(self):         	#构造方法
    self.data=[]                	#存放栈中元素,初始为空

基本运算:

1)判断栈是否为空empty()

def empty(self):        	#判断栈是否为空
  if len(self.data)==0:
    return True
  return False

2)进栈push(e)

def push(self,e):              #元素e进栈
  self.data.append(e)

3)出栈pop()

def pop(self):        			#元素出栈
  assert not self.empty()     		#检测栈为空
  return self.data.pop()

4)取栈顶元素gettop()

def gettop(self):      		#取栈顶元素
  assert not self.empty()   	#检测栈为空
  return self.data[-1]

(2)双栈

设有两个栈S1和S2,它们都采用顺序栈存储,并且共享一个固定容量的存储区s[0..M-1],为了尽量利用空间,减少溢出的可能,请设计这两个栈的存储方式。

栈S1空的条件是top1=-1。

栈S1满的条件是top1=top2-1;

元素e进栈S1(栈不满时)的操作是:top1++;s[top1]=e。

元素e出栈S1(栈不空时)的操作是:e=s[top1];top1--。


栈S2空的条件是top2=M。

栈S2满的条件是top2=top1+1。

元素e进栈S2(栈不满时)的操作是:top2--;s[top2]=e。

元素e出栈S2(栈不空时)的操作是:e=s[top2];top2++

3.栈的链式存储结构及其基本运算算法实现

class LinkNode:               	#单链表结点类
  def __init__(self,data=None):  #构造方法
    self.data=data               #data属性
    self.next=None               #next属性
class LinkStack:                	#链栈类
  def __init__(self):           	#构造方法
    self.head=LinkNode()        	#头结点head
    self.head.next=None

基本运算:

1)判断栈是否为空empty()

def empty(self):    	#判断栈是否为空
  if self.head.next==None:
    return True
  return False

2)进栈push(e)

def push(self,e):           	#元素e进栈
  p=LinkNode(e)
  p.next=self.head.next
  self.head.next=p

3)出栈pop()

def pop(self):                     	#元素出栈
  assert self.head.next!=None  		#检测空栈的异常
  p=self.head.next;
  self.head.next=p.next
  return p.data

4)取栈顶元素gettop()

def gettop(self):                   	#取栈顶元素
  assert self.head.next!=None     	#检测空栈的异常
  return self.head.next.data

 二、队列

1.定义及特点

(1)定义:

队列(queue)是一种只能在不同端进行插入或删除操作的线性表。

(2)主要特点:

1. 先进先出,即先进队的元素先出队。

2. 每次进队的元素作为新队尾元素,每次出队的元素只能是队头的元素。

3. 队列也称为先进先出表。

2.队列的顺序存储结构及其基本运算算法实现

(1)非循环队列

四要素:

1. 队空条件:front==rear。

2. 队满(上溢出)条件:rear==MaxSize-1(因为每个元素进队都让rear增1,当rear到达最大下标时不能再增加。

3. 元素e进队操作:rear增1,将元素e放在该位置(进队的元素总是在尾部插入的)。

4. 出队操作:front增1,取出该位置的元素(出队的元素总是在队头出来的)。

MaxSize=100                          	#假设容量为100
class SqQueue:      			#非循环队列类
  def __init__(self):                 	#构造方法
    self.data=[None]*MaxSize        	#存放队列中元素
    self.front=-1                   	#队头指针
    self.rear=-1                    	#队尾指针

基本运算:

1)判断队列是否为空empty()

def empty(self):	#判断队列是否为空
   return self.front==self.rear

2)进队push(e)

def push(self,e): 			#元素e进队
  assert not self.rear==MaxSize-1   	#检测队满
  self.rear+=1
  self.data[self.rear]=e

3)出队pop()

def pop(self):				#出队元素
  assert not self.empty()         	#检测队空
  self.front+=1
  return self.data[self.front]

4)取队头元素gethead()

def gethead(self):		#取队头元素
  assert not self.empty()      	#检测队空
  return self.data[self.front+1]

(2)循环队列

四要素:

1. 队空条件:rear==front。

2. 队满条件:(rear+1)%MaxSize==front(相当于试探进队一次,若rear达到front,则认为队满了)。

3. 元素e进队:rear=(rear+1)%MaxSize,将元素e放置在该位置。

4. 元素出队:front=(front+1)%MaxSize,取出该位置的元素。

MaxSize=100                     	#全局变量,假设容量为100
class CSqQueue:      		#循环队列类
  def __init__(self):           	#构造方法
    self.data=[None]*MaxSize    	#存放队列中元素
    self.front=0                	#队头指针
    self.rear=0                 	#队尾指针

基本运算:

1)判断队列是否为空empty()

def empty(self):	  		#判断队列是否为空
  return self.front==self.rear

2)进队push(e)

def push(self,e):				#元素e进队
  assert (self.rear+1)%MaxSize!=self.front 	#检测队满
  self.rear=(self.rear+1)%MaxSize
  self.data[self.rear]=e

3)出队pop()

def pop(self):				#出队元素
  assert not self.empty()       		#检测队空
  self.front=(self.front+1)%MaxSize
  return self.data[self.front]

4)取队头元素gethead()

def gethead(self):		#取队头元素
  assert not self.empty()       	#检测队空
  head=(self.front+1)%MaxSize   	#求队头元素的位置
  return self.data[head]

3.队列的链式存储结构及其基本运算算法实现

四要素:

1. 队空条件:fronr=rear==None,不妨仅以front==None作为队空条件。

2. 由于只有内存溢出时才出现队满,通常不考虑这样的情况。

3. 元素e进队操作:在单链表尾部插入存放e的s结点,并让队尾指针指向它。

4. 出队操作:取出队首结点的data值并将其从链队中删除。

class LinkNode:                 		#链队结点类
  def __init__(self,data=None): 		#构造方法
    self.data=data                  	#data属性
    self.next=None                  	#next属性
class LinkQueue:      			#链队类
  def __init__(self):                	#构造方法
    self.front=None                 	#队头指针
    self.rear=None                  	#队尾指针

基本运算:

1)判断队列是否为空empty()

def empty(self):		#判断队是否为空
  return self.front==None

2)进队push(e)

def push(self,e):		#元素e进队
  s=LinkNode(e)                	#新建结点s
  if self.empty():		#原链队为空
    self.front=self.rear=s
  else:				#原链队不空
    self.rear.next=s		#将s结点链接到rear结点后面
    self.rear=s

 3)出队pop()

def pop(self):				#出队操作
  assert not self.empty()		#检测空链队
  if self.front==self.rear:		#原链队只有一个结点
    e=self.front.data			#取首结点值
    self.front=self.rear=None		#置为空队
  else:					#原链队有多个结点
    e=self.front.data			#取首结点值
    self.front=self.front.next		#front指向下一个结点
  return e

 4)取队头元素gethead()

def gethead(self):   		#取队头元素
  assert not self.empty()	#检测空链队
  e=self.front.data		#取首结点值
  return e

 

双端队列deque

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值