数据结构——队列、循环队列、链式队列主要操作函数的实现

来源:互联网 发布:淘宝网小虫米子 编辑:程序博客网 时间:2024/06/15 21:43
  1 //队列是另一种限定存取位置的线性表。它只允许在表的一端插入,在另一端删除。允许插入的一端叫做队尾,允许删除的一端叫做队头。每次  2 //在队尾加入新元素,最先进入队列的元素最先退出队列。先进先出  3   4   5 //循环队列:  6   7 //循环队列,其首尾相接,当队头指针front和队尾指针rear进到maxSize-1后,再前进一个位置九自动到0,这样可以利用整除取余来实现  8 //队头指针进1:front = (front + 1)%maxSize  9 //队尾指针进1:rear = (rear + 1)%maxSize 10  11 //循环队列的结构定义 12 typedef int QElemType; 13 #define maxSize 20         //循环队列的容量 14 typedef struct CircQueue 15 { 16     QElemType elem[maxSize];    //数组元素 17     int front, rear;            //队头指针和队尾指针(数组下标) 18 }; 19  20 //循环队列初始化 21 void InitQueue(CircQueue& Q) 22 {//循环队列初始化:令队头指针和队尾指针归零 23     Q.front = Q.rear = 0; 24 } 25  26 //循环队列插入 27 void EnQueue(CircQueue& Q, QElemType x) 28 {//若对列不满,则将元素x插入到队尾,函数返回1,否则函数返回0,不能进队列 29     if((Q.rear + 1)%maxSize == Q.front) return 0; //队列满则不能插入,函数返回0 30     Q.elem[Q.rear] = x;   //按照队尾指针指示位置插入 31     Q.rear = (Q.rear + 1)%maxSize;  //队尾指针进1 32     return 1;    //插入成功,函数返回1 33 } 34 
 35 //循环队列删除 36 int DeQueue(CircQueue& Q, QElemType& x) 37 {//若队列不空,则函数推掉一个队头元素并通过引用型参数x返回,函数返回1,否则函数返回0,此时x的值不可引用 38     if(Q.front == Q.rear)  return 0;  //队列空则不能删除,函数返回0 39     x = Q.elem[Q.front]; 40     Q.front = (Q.front + 1)%maxSize;  //队头指针进1 41     return 1;   //删除成功,函数返回1 42 } 43  44 //返回队头元素的值 45 int GetQueue(CircQueue& Q, QElemType& x) 46 {//若对列不空,则函数通过引用型参数x返回队头元素的值,函数返回1,否则函数返回0,此时x的值不可引用 47     if(Q.front == Q.rear) return 0;//返回队头元素的值 48     x = Q.elem[Q.front]; 49     return 1; 50 } 51  52 //判断队列是否为空 53 int QueueEmpty(CircQueue& Q) 54 {//判队列空否。若队列空,则函数返回1,否则返回0 55     return Q.front == Q.rear;  //返回Q.front == Q.rear 运算结果 56 } 57  58 //判断队列满否 59 int QueueFull(CircQueue& Q) 60 {//判断队列满否。若队列满,则函数返回1,否则返回0 61     return (Q.rear + 1)%maxSize == Q.front;  //返回(Q.rear + 1)%maxSize == Q.front运算结果 62 } 63  64 //求队列元素个数 65 int QueueSize(CircQueue& Q) 66 {//求队列元素个数 67     return (Q.rear - q.front + maxSize)%maxSize; 68 }

 71 //链式队列 72  73 //链式队列是对列基于单链表的存储表示,在单链表的每一个结点中有两个域:data域存放队列元素的值,link域存放单链表下一个结点的地址 74 //队列的头指针指向单链表的头结点,但实际队头结点在头结点后面的首元结点,意味着队列的头元素放在单链表的首元结点内,若要从队列中 75 //退出一个元素,必须从单链表中删去首元结点。而队列的队尾指针指向单链表的尾结点,存放新元素的结点应插在队列的队尾。 76  77 //链式队列的结构定义 78 typedef struct node   //链式队列结点定义 79 { 80     QElemType data;    //结点数据 81     struct node* link;  //结点链接指针 82 }LinkNode; 83 typedef struct LinkQueue      //链式队列定义 84 { 85     LinkNode *front, *rear;  //队头和队尾指针 86 } 87  88 //链式队列初始化 89 void InitQueue(LinkQueue& Q) 90 {//队列初始化:创建链式队列的头结点,令队头指针和队尾指针指向头结点 91     Q = new LinkNode;          //创建链式队头结点 92     if(!Q){cerr<<"存储分配失败!\n";  exit(1);} 93     Q.front == Q.rear == Q;    //队头与队尾指针初始化 94 } 95  96 //链式队列的插入:即入队列 97 int EnQueue(LinkQueue& Q, QElemType x) 98 {//进对列:将新元素x插入到队列的队尾(链尾) 99     Q.rear->link = new LinkNode;     //创建新结点100     if(!Q.rear->link){cerr<<"存储分配失败!\n";  exit(1);}101     Q.rear = Q.rear->link;      //新结点成为新的队尾102     Q.rear->data = x;  Q.rear->link = NULL;    //将插入的新结点值赋给队尾元素,队尾下一个元素指向空103     return 1;   //插入成功104 }
106 //链式队列的删除:即出对列107 int DeQueue(LinkQueue& Q, QElemType& x)108 {//出对列:如果队列不空,将队头结点从链式队列中删去,并通过引用向参数x返回被删元素的值,同时函数返回1;若队列空,则函数返回0,109     //此时x的值不可引用110     if(!Q.front->link) return 0;    //队列空则返回0111     LinkNode *p = Q.front->link;    //队列不空,保存队头结点地址112     x = p->data;113     Q.front->link = p->link;        //队头修改114     delete p;                       //释放元对头结点115     return 1;                       //函数返回1116 }117 118 //读取队头元素的值119 int GetFront(LinkQueue& Q, QElemType& x)120 {//读取队头元素的值:若对列不空,则函数通过引用型参数x返回队列元素的值,函数返回1;若队列空,则函数返回0,且x的值不可引用121     if(!Q.front->link) return 0;    //队列空则返回0122     x = Q.front->link->data;        //取队头元素中的数据值123     return 1;124 }125 126 //判断队列是否为空127 int QueueEmpty(LinkQueue& Q)128 {//判队列空否:队列空则函数返回1,否则函数返回0129     return Q.front->link == NULL;130 }131 132 //求队列元素个数133 int QueueSize(LinkQueue& Q)134 {135     LinkNode *p = Q.front->link; int k = 0;136     while(p != NULL)137     {138         p = p->link;139         k++;140     }141     return k;142 }


阅读全文
0 0
原创粉丝点击