数据结构笔记:栈和队列

栈和队列的特性,一个是先进后出,一个是先进先出。

对于栈来说,可以通过链表或者数组来进行实现 。

对于顺序栈来说,代码如下


//顺序栈类SeqStack的类定义 
const int StackSize = 10;           //10是示例性的数据,根据实际问题具体定义
template <typename DataType>         //定义模板类SeqStack
class SeqStack
{
public:
    SeqStack( );                 //构造函数,初始化一个空栈
    ~SeqStack( );               //析构函数
    void Push( DataType x );      //入栈操作,将元素x入栈
    DataType Pop( );            //出栈操作,将栈顶元素弹出
    DataType GetTop( );         //取栈顶元素(并不删除)
    int Empty( );                //判断栈是否为空
private:
    DataType data[StackSize];    //存放栈元素的数组
    int top;                    //游标,栈顶指针,为栈顶元素在数组中的下标
};


//顺序栈类SeqStack的构造函数和析构函数 
template <typename DataType>
SeqStack<DataType> :: SeqStack()
{
 top = -1;
}

template <typename DataType>
SeqStack<DataType> :: ~SeqStack()
{
 
}

//顺序栈类SeqStack的入栈操作 
template <typename DataType>
void SeqStack<DataType> :: Push(DataType x)
{
 if (top == StackSize - 1) throw "上溢";
 data[++top] = x;
}

//顺序栈类SeqStack的出栈操作 
template <typename DataType>
DataType SeqStack<DataType> :: Pop( )
{
 DataType x;
 if (top == -1) throw "下溢";
 x = data[top--];
 return x;
}

 //顺序栈类SeqStack的判空操作
template <typename DataType>
int SeqStack<DataType> :: Empty()
{
 if(top == -1)
  return 1;
 else 
  return 0;
}

//顺序栈类SeqStack的取栈顶操作
template <typename DataType>
DataType SeqStack<DataType> :: GetTop( )
{
 if(top == -1)
  throw "下溢异常";
 else
  return data[top];
}

而另外的一种,链栈,则是


//链栈类LinkStack的类定义 
template <typename DataType> 
struct Node
{
 DataType data;               //数据域
    Node<DataType> *next;       //指针域
};

template <typename DataType> 
class LinkStack
{
public:
    LinkStack( );                     //构造函数,初始化一个空链栈
    ~LinkStack( );                    //析构函数,释放链栈各结点的存储空间
    void Push(DataType x);            //入栈操作,将元素x入栈
    DataType Pop( );                 //出栈操作,将栈顶元素出栈
    DataType GetTop( );              //取栈顶元素(并不删除)
    int Empty( );                    //判空操作,判断链栈是否为空栈
private:
    Node<DataType> *top;                       //栈顶指针即链栈的头指针
};

//链栈类LinkStack的构造函数 
template <typename DataType> 
LinkStack<DataType> :: LinkStack()
{
  top = new Node<DataType>;              //生成头结点
   top->next = nullptr;                      //头结点的指针域置空
}

// 链栈类LinkStack的析构函数 

template <typename DataType> 
LinkStack<DataType> :: ~LinkStack()
{
   Node<DataType> *q = nullptr;
   while (top != nullptr)        //释放链栈的每一个结点的存储空间
   {
     q = top;                 //暂存被释放结点
     top = top->next;         // top指向被释放结点的下一个结点
     delete q;    
   }
}
//链栈类LinkStack的入栈操作
template <typename DataType> 
void LinkStack<DataType> :: Push(DataType x)
{
 Node<DataType> *s = nullptr;
 s = new Node<DataType>; s->data = x;         //申请结点s数据域为x
 s->next = top; top = s;                       //将结点s插在栈顶
}

//链栈类LinkStack的出栈操作 

template <typename DataType> 
DataType LinkStack<DataType> :: Pop( )
{
   Node<DataType> *p = nullptr;
   DataType x;
   if (top == nullptr) throw "下溢";
   x = top->data; p = top;                //暂存栈顶元素
   top = top->next;                     //将栈顶结点摘链
   delete p;
   return x;
}
//链栈类LinkStack的取栈顶操作
template <typename DataType>
DataType LinkStack<DataType> :: GetTop()
{
 if(top == nullptr)
  throw "下溢异常";
 else
  return top->data;
}

//链栈类LinkStack的判空操作 

template <typename DataType> 
int LinkStack<DataType> :: Empty()
{
 if(top == nullptr)
  throw "下溢异常";
 else
  return 0;
}

同样的对于队列也有顺序存储和链式存储两种方式

顺序存储

//循环队列类CirQueue的类定义 

const int QueueSize = 100;               //100是示例性数据,根据需要重新定义
template <typename DataType>             //定义模板类CirQueue
class CirQueue
{
public:
    CirQueue( );                        //构造函数,初始化空队列
    ~ CirQueue( );                     //析构函数
    void EnQueue(DataType x);          //入队操作,将元素x入队
    DataType DeQueue( );              //出队操作,将队头元素出队
    DataType GetQueue( );             //取队头元素(并不删除)
    int Empty( );                     //判断队列是否为空
private:
    DataType data[QueueSize];             //存放队列元素的数组
    int front, rear;                     //游标,队头和队尾指针
};


//循环队列类CirQueue的构造函数 

template <typename DataType>
CirQueue<DataType> :: CirQueue()
{
 rear = front = QueueSize - 1;
}

//循环队列类CirQueue的析构函数
template <typename DataType>
CirQueue<DataType> :: ~CirQueue()
{
 
}

//循环队列类CirQueue的入队操作 

template <typename DataType>
void CirQueue<DataType> :: EnQueue(DataType x)
{
  if ((rear + 1) % QueueSize == front) 
    throw "上溢";
   rear = (rear + 1) % QueueSize;          //队尾指针在循环意义下加1
   data[rear] = x;                       //在队尾处插入元素
}
//循环队列类CirQueue的出队操作 

template <typename DataType>
DataType CirQueue<DataType> :: DeQueue( )
{
 if (rear == front) throw "下溢"; 
   front = (front + 1) % QueueSize;      //队头指针在循环意义下加1
   return data[front];                  //读取并返回出队前的队头元素
}  
//循环队列类CirQueue的取队头操作

template <typename DataType>
DataType CirQueue<DataType> :: GetQueue( )
{
 if (rear == front) throw "下溢"; 
   return data[(front + 1) % QueueSize];        //注意不修改队头指针
}
//循环队列类CirQueue的判空操作 

template <typename DataType>
int CirQueue<DataType> :: Empty()
{
 if(front == rear)
  return 1;
 else
  return 0;
} 

链式存储

//链队列类LinkQueue的类定义 
template <typename DataType>  
struct Node
{
 DataType data;               //数据域
 Node<DataType> *next;       //指针域
};
template <typename DataType>
class LinkQueue
{
public:
    LinkQueue( );               //构造函数,初始化一个空的链队列
    ~LinkQueue( );              //析构函数,释放链队列各结点的存储空间
    void EnQueue(DataType x);    //入队操作,将元素x入队
    DataType DeQueue( );        //出队操作,将队头元素出队
    DataType GetQueue( );        //取链队列的队头元素
    int Empty( );                //判断链队列是否为空
private:
    Node<DataType> *front, *rear;       //队头和队尾指针,分别指向头结点和终端结点
};
//链队列类LinkQueue的构造函数 
template <typename DataType>
LinkQueue<DataType> :: LinkQueue( )
{
 Node<DataType> *s = nullptr;
   s = new Node<DataType>; s->next = nullptr;              //创建头结点s
   front = rear = s;                //将队头指针和队尾指针都指向头结点s
}

//链队列类LinkQueue的析构函数 

template <typename DataType>
LinkQueue<DataType> :: ~LinkQueue()
{
 Node<DataType> *q = nullptr;
   while (front != nullptr)        //释放单链表的每一个结点的存储空间
    {
     q = front;                 //暂存被释放结点
     front = front->next;         // front指向被释放结点的下一个结点
     delete q;    
    }
}
//链队列类LinkQueue的入队操作 

template <typename DataType>
void LinkQueue<DataType> :: EnQueue(DataType x)
{
   Node<DataType> *s = nullptr;
   s = new Node<DataType>;                 //申请结点s
   s->data = x; s->next = nullptr; 
   rear->next = s; rear = s;                   //将结点s插入到队尾
}
//链队列类LinkQueue的出队操作 

template <typename DataType>
DataType LinkQueue<DataType> :: DeQueue( )
{
 DataType x;
 Node<DataType> *p = nullptr;
 if (rear == front) throw "下溢";
 p = front->next; x = p->data;           //暂存队头元素
 front->next = p->next;                //将队头元素所在结点摘链
 if (p->next == nullptr) rear = front;      //判断出队前队列长度是否为1
 delete p;
   return x;
}
//链队列类LinkQueue的取队头操作

template <typename DataType>
DataType LinkQueue<DataType> :: GetQueue()
{
 if(front == rear)
  throw "下溢异常";
 else
  return front->next->data;
}

//链队列类LinkQueue的判空操作 

template <typename DataType>
int LinkQueue<DataType> :: Empty()
{
 if(front == rear)
  return 1;
 else  
  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值