相信大家都对队列不陌生,这里为了实现动态存取数据而采用链表结构来构建队列数据结构,来的十分的灵活,是我非常喜欢的一种构建方式。
下面就直接给出构建的代码,具体可以看注释,基本上有问题的都写在注释中了:
//超超
//2016 10 6
#include <iostream>
using namespace std;
enum error_code{success,overflow,underflow,rangeerror};
typedef int elementtype ;
typedef struct linknode {
elementtype data;
struct linknode *next;
}node;
class link_queue{
public:
link_queue();
~link_queue();
bool isempty()const;
bool isfull()const; //注意链表动态结构不需要考虑满情况
error_code get_front(elementtype &x)const;//取队头元素
error_code append(const elementtype x);//入队
error_code serve();//出队
private:
int count;
node * front;//头指针
node * rear;//尾指针
};
link_queue::link_queue(){
front = new node;
rear = front;
front->next=NULL;
count = 0;
}
//析构函数的实现
link_queue::~link_queue(){
while ( !isempty() ) serve();
delete front; //释放头结点完成空间的释放
}
bool link_queue::isempty() const{
return count == 0;
//等价于return front==rear;或return front->next==NULL;
}
bool link_queue::isfull() const{
return false; //本函数无实际意义可以不写的
}
//取队头元素,注意链表结构是使用头指针指向取下一个结点数据
error_code link_queue::get_front(elementtype &x)const{
if ( isempty() ) return underflow;
x=front->next->data;
return success;
}
//入队,不需要考虑队满的情况,所以做的是对尾指针的下一位结点添加操作
error_code link_queue::append(const elementtype x){
node *s = new node; //定义新结点
s->data=x; //加数据加入新结点
s->next=NULL;//新数据的下一结点为空
rear->next=s;//将原来的尾指针指向下一位的改为新数据指向
rear = s; //尾指针指向新结点完成入队操作
count ++;
return success;
}
//出队,是取队头操作,直到取完所有的数据
error_code link_queue::serve(){
node *u;//定义一个结点
if (isempty()) return underflow;
u=front->next;//u保存要删除的结点指针
front->next=u->next;//绕过要删除的结点完成删除操作
delete u;//释放要删除的结点,释放空间
count --;
//注意这里有一个极端情况:删除的是最后一个结点。会涉及尾指针的操作,要把头尾指针对应起来
if (front->next==NULL) rear = front;
return success;
}
//使用链队列来存取数据
void main()
{
link_queue lq;
elementtype x;
int i;
cout<<"请输入要存的数据个数:"<<endl;
cin>>i;
for(int j=1;j<=i;j++){
cout<<"请输入第"<<j<<"个数: ";
cin>>x;
lq.append(x);
}
cout<<"链队存储的数据顺序为:"<<endl;
while(!lq.isempty()){
lq.get_front(x);
cout<<x<<" ";
lq.serve();
}
cout<<endl;
}
这是最基础的构建方案,后面还会有各种基本算法的代码带给大家,尽量使用最精炼有效的方法让读者能自己使用。