赞
踩
队列(Queue)是另一种限定性的线性表,它只允许在表的一端插入元素,而在另一端删除元素,所以队列具有先进先出(Fist In Fist Out,缩写为FIFO)的特性。这与我们日常生活中的排队是一致的,最早进入队列的人最早离开,新来的人总是加入到队尾。在队列中,允许插入的一端叫做队尾(rear),允许删除的一端则称为队头(head)。
本次只写了顺序队列和链队的基本操作,以及一个利用队来实现的将随机数奇偶分配输出的程序 ,不太严谨,尚待改进,可供参考
这次并不是写在一个源文件里的,而是分了四个源文件出来加一个头文件:
目录
代码及详情如下:
-
- #include<stdio.h>
- #include<malloc.h>
- #include<stdlib.h>
- #include<Windows.h>
- #include<time.h>
-
- #define MAX 100 //队的最大元素个数
- #define DataType int //数据类型
-
- typedef struct SqQueue { //顺序队结构
- DataType data[MAX]; //数据
- int head, rear; //头指针与尾指针
- int length; //队元素个数
- }SQ;
-
- typedef struct LNode { //链表结点结构
- DataType data; //数据域
- struct Node* next; //指针域
- }LNode,*Node;
-
- typedef struct LkQueue { //链队结构
- Node head; //头指针
- Node rear; //尾指针
- int size; //元素个数
- }LQ;
-
- int main1(); //顺序队的主函数
- int main2(); //链队的主函数
- void menu1(); //副菜单
-
- //顺序队的函数声明
- void Enqueue(SQ* q, int num);
- void Dequeue(SQ* q);
- void ClearQueue(SQ* q);
- DataType HeadOfQueue(SQ* q);
- int LengthOfQueue(SQ* q);
- void PrintQueue(SQ* q);
- void File(SQ* q);
-
- //链队的函数声明
- void Enqueue2(LQ* p, DataType num);
- void PrintQueue2(LQ* p);
- int SizeOfQueue2(LQ* p);
- DataType HeadOfQueue2(LQ* p);
- void ClearQueue2(LQ* p);
- void Dequeue2(LQ* p);
- void SaveFile2(LQ* q);
效果如图:
代码及详情如下:
-
- /*所有函数声明和结构体声明都在这个头文件里*/
- #include"Queue.h"
-
-
- void menu() {
- printf("###################\n");
- printf(" 请选择:\n");
- printf(" 1、顺序队\n");
- printf(" 2、链队\n");
- printf(" 3、奇偶分配\n");
- printf(" 0、退出\n");
- printf("###################\n");
- }
-
- int main(){
- int chose;
- system("title 队列的操作");
- while (1) {
- system("cls"); //清屏
- menu(); //主菜单
- scanf("%d", &chose);
- switch (chose) {
- case 1: //进入顺序队的操作
- system("cls");
- system("title 顺序队");
- main1(); //顺序对的主函数
- break;
- case 2: //进入链队的操作
- system("cls");
- system("title 链队");
- main2(); //联队的主函数
- break;
- case 3:
- system("cls");
- system("title 奇偶分配");
- main3();
- system("pause");
- break;
- case 0:return;
- default:printf("输入错误!重新输入:\n"); system("pause");
- }
- }
- return 0;
- }
效果如图:
- /*所有函数声明和结构体声明都在这个头文件里*/
- #include"Queue.h"
-
-
- int main1(){ //通过主菜单调用的
- SQ queue; //创建一个队
- SQ* q = &queue; //用指针操作
- q->rear = 0; //
- q->head = 0; //初始化
- q->length = 0; //
- int chose;
- int num;
-
- while (1) {
- menu1(); //菜单
- scanf("%d", &chose);
- switch (chose) {
- case 1:
- printf("请输入入队的值:");
- scanf("%d", &num);
- Enqueue(q, num); //入队操作
- printf("入队成功!\n");
- break;
- case 2:
- if (q->length == 0) {
- printf("当前空队!\n");
- break;
- }
- Dequeue(q); //出队操作
- printf("出队成功!\n");
- break;
- case 3:
- ClearQueue(q); //清空队操作
- printf("清空成功!\n");
- break;
- case 4: //显示队列首元素
- if (q->length == 0) {
- printf("当前空队!\n");
- break;
- }
- printf("该队列的首元素是:%d\n", HeadOfQueue(q));
- break;
- case 5: //显示队列长度
- printf("该队列的元素个数是:%d\n", LengthOfQueue(q));
- break;
- case 6:
- if (q->length == 0) {
- printf("当前空队!\n");
- break;
- }
- printf("当前队列:");
- PrintQueue(q); //打印队列
- printf("\n");
- break;
- case 7:
- File(q);
- printf("保存成功!\n");
- break;
- case 0:
- return 0;
- default:
- printf("输入错误!重新输入:\n");
- }
- }
- return 0;
- }
- void menu1() {
- printf("###################\n");
- printf(" 1、数据入队\n");
- printf(" 2、数据出队\n");
- printf(" 3、清空队列\n");
- printf(" 4、队首元素\n");
- printf(" 5、元素个数\n");
- printf(" 6、打印队列\n");
- printf(" 7、保存为文件\n");
- printf(" 0、退出\n");
- printf("###################\n");
- printf("请输入:\n");
- }
- //1、入队
- /*单个单个元素入队,也可以写个循环入队快点*/
- /*因为初始队的头指针尾指针都指在0的位置,所以入队rear要++*/
- void Enqueue(SQ* q,int num) {
- q->data[q->rear++] = num;
- q->length++; //队列的元素个数
- }
-
- //2、出队
- void Dequeue(SQ* q) {
- q->head++; //队的head++
- q->length--; //元素减少
- }
-
- //3、清空队列
- void ClearQueue(SQ* q) {
- while (q->head != q->rear) { //将队列清空就是两头指针在一个位置,但head不能++到rear,因为清空栈栈的大小不会变
- q->rear--;
- }
- q->length = 0; //同时将元素个数变为0
- }
-
- //4、队首元素
- DataType HeadOfQueue(SQ* q) {
- return (q->data[q->head]); //只要不是出栈头指针是不会移动的,可以直接打印出来
- }
-
- //5、队列元素个数
- int LengthOfQueue(SQ* q) {
- return q->length; //直接打印length
- }
-
- //6、打印队列
- void PrintQueue(SQ* q) {
- int i = q->head; //打印队列但不是出队,所以拿两个指针代替原两指针操作
- int j = q->rear;
- for (i; i < j; i++) {
- printf("%d ", q->data[i]);
- }
- }
- //7、保存文件
- void File(SQ* q) {
- FILE* pfWrite1;
- // 打开文件
- pfWrite1 = fopen("SqQueue.txt", "w");
- if (pfWrite1 == NULL) {
- printf("%s\n", strerror(errno));
- }
- //写文件
- for (int i = 0; i < q->length; i++) {
- fprintf(pfWrite1, "%d ", q->data[i]);
- }
- //关闭文件
- fclose(pfWrite1);
- pfWrite1 = NULL;
- }
效果如图:
- /*所有函数声明和结构体声明都在这个头文件里*/
- #include"Queue.h"
-
-
- int main2(){ //通过主菜单调用的
- //创建头节点
- Node head = (Node)malloc(sizeof(Node));
- head->next = NULL;
- //创建链队
- LQ L;
- LQ* p = &L;
- p->size = 0; //链队的元素个数初始为0
- p->head = head; //联队的头指针初始指向头节点
- p->rear = head; //同上
- int chose;
- DataType num; //入队的值
- while (1) {
- menu1(); //菜单
- scanf("%d", &chose);
- switch (chose) {
- case 1: //入队操作
- printf("请输入要入队的值:\n");
- scanf("%d", &num);
- Enqueue2(p,num);
- printf("入队成功!\n");
- break;
- case 2: //出队操作
- if (p->head == p->rear) { //判断是否空队
- printf("当前是空队列!\n");
- break;
- }
- Dequeue2(p);
- printf("出队成功!\n");
- break;
- case 3: //清空队列
- ClearQueue2(p);
- printf("清空成功!\n");
- break;
- case 4: //队列首元素
- if (p->head == p->rear) {
- printf("当前是空队列!\n");
- break;
- }
- printf("该队列首元素是:%d \n",HeadOfQueue2(p));
- break;
- case 5: //队列元素个数
- printf("该队列元素个数是:%d\n",SizeOfQueue2(p));
- break;
- case 6: //打印队列
- if (p->head == p->rear) {
- printf("当前是空队列!\n");
- break;
- }
- printf("当前队列:");
- PrintQueue2(p);
- printf("\n");
- break;
- case 7:
- SaveFile2(p);
- printf("保存成功!\n");
- break;
- case 0:
- return 0;
- default:printf("输入错误!重新输入:\n");
- }
- }
- return 0;
- }
- //1、入队操作
- void Enqueue2(LQ* p,DataType num) {
- Node new = (Node*)malloc(sizeof(Node)); //新建一个结点
- new->data = num; //赋值
- new->next = NULL; //将他指向NULL
- p->rear->next = new; //第一次用尾指针代头节点将头节点与新结点连起来,以后就是将最后一个结点和新节点连起来
- p->rear = new; //尾指针移动到新结点上
- p->size++; //元素个数加一
- }
- //2、出队操作
- void Dequeue2(LQ* p) {
- p->head = p->head->next; //头指针移动到下一个即出队
- p->size--; //元素个数要减一
- }
- //3、清空队列
- void ClearQueue2(LQ* p) {
- while (p->head != p->rear) { //一直出队直到两指针指在了一起
- Dequeue2(p); //调用出队函数
- }
- p->size = 0; //将元素个数为0
- }
- //4、队首元素
- DataType HeadOfQueue2(LQ* p) {
- Node new = p->head->next; //用个new代替头指针,不然头指针会发生变化
- return new->data;
- }
- //5、元素个数
- int SizeOfQueue2(LQ* p) {
- return p->size; //直接返回
- }
-
- //6、打印队列
- void PrintQueue2(LQ* p) {
- Node new = p->head->next; //打印不出队,所以用个new代替头指针,循环打印一直到new==NULL
- while (new != NULL) {
- printf("%2d ", new->data);
- new=new->next;
- }
- }
-
- //7、保存文件
- void SaveFile2(LQ* q) {
- // 打开文件
- FILE* pfWrite2= fopen("LkQueue.txt", "w");
- if (pfWrite2 == NULL) {
- printf("%s\n", strerror(errno));
- }
- //写文件
- for (Node i = q->head->next; i !=NULL; i=i->next) {
- fprintf(pfWrite2, "%d ", i->data);
- }
- //关闭文件
- fclose(pfWrite2);
- pfWrite2 = NULL;
- }
效果如图:
代码及详情如下:
-
- #include"Queue.h"
-
-
-
- int main3(){
- //创建头节点
- Node head1 = (Node)malloc(sizeof(Node));
- Node head2 = (Node)malloc(sizeof(Node));
- head1->next = NULL;
- head2->next = NULL;
- int num;
- //创建两个链队
- LQ Q1; LQ Q2;
- LQ* q1; LQ* q2;
- q1 = &Q1; q2 = &Q2;
- //初始化
- q1->head = head1; q1->rear = head1;
- q2->head = head2; q2->rear = head2;
- q1->size = 0; q2->size = 0;
- //随机数种子
- srand((unsigned)time(NULL));
- for (int i = 0; i < 20; i++) {
- num = rand() % 100; //100以内的随机数
-
- if (num % 2 == 0) { //偶数
- Enqueue2(q1, num); //放在q1里面
- }
- else { //奇数
- Enqueue2(q2, num); //放在q2里面
- }
- }
- //打印看看
- printf("偶数为:");
- PrintQueue2(q1);
- printf("\n");
- printf("奇数为:");
- PrintQueue2(q2);
- printf("\n");
-
- printf("开始配对:\n");
- //将q1,q2从头节点的位置移到第一个结点的位置
- q1->head = q1->head->next;
- q2->head = q2->head->next;
-
- while (q1->head != NULL && q2->head != NULL) {//任何一个为NULL停止
- Sleep(300);
- printf("%2d ", q1->head->data);
- Sleep(300);
- printf("%2d ", q2->head->data);
- printf("\n");
- q1->head = q1->head->next;
- q2->head = q2->head->next;
- }
- return 0;
- }
总结:
1、一个程序里面只能有一个主函数,不管有多少个源文件
2、头文件一般是用来 声明的,一般不写实现代码,自己写的头文件用“”括起来
3、队就是线性表,用的都是顺序表和链表的形式实现的,写的时候会有点昏,但写完发现没有什么特别难的东西,都是老套路
4、这次写了个文件的保存操作,因为对文件操作的不熟悉所以没有写读取操作,连这个保存操作都是格式套的
5、奇偶分配这个了解了一下随机数,会用了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。