当前位置:   article > 正文

数据结构队列的基本操作(C语言)_c语言中如何通过调用函数来清除输入队列

c语言中如何通过调用函数来清除输入队列

队列(Queue)是另一种限定性的线性表,它只允许在表的一端插入元素,而在另一端删除元素,所以队列具有先进先出(Fist In Fist Out,缩写为FIFO)的特性。这与我们日常生活中的排队是一致的,最早进入队列的人最早离开,新来的人总是加入到队尾。在队列中,允许插入的一端叫做队尾(rear),允许删除的一端则称为队头(head)

本次只写了顺序队列和链队的基本操作,以及一个利用队来实现的将随机数奇偶分配输出的程序 ,不太严谨,尚待改进,可供参考

 这次并不是写在一个源文件里的,而是分了四个源文件出来加一个头文件:


目录

 头文件:

主菜单:

顺序队:

//主函数

//菜单

 //入队

//出队

//清空队

//队首元素

//队列元素个数

//打印队列

//保存为文件

链队:

//主函数

//入队

//出队

//清空队

//求队首元素

//求元素个数

//打印队列

//保存为文件

奇偶分配:

总结:


 头文件:

代码及详情如下:

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<stdlib.h>
  4. #include<Windows.h>
  5. #include<time.h>
  6. #define MAX 100 //队的最大元素个数
  7. #define DataType int //数据类型
  8. typedef struct SqQueue { //顺序队结构
  9. DataType data[MAX]; //数据
  10. int head, rear; //头指针与尾指针
  11. int length; //队元素个数
  12. }SQ;
  13. typedef struct LNode { //链表结点结构
  14. DataType data; //数据域
  15. struct Node* next; //指针域
  16. }LNode,*Node;
  17. typedef struct LkQueue { //链队结构
  18. Node head; //头指针
  19. Node rear; //尾指针
  20. int size; //元素个数
  21. }LQ;
  22. int main1(); //顺序队的主函数
  23. int main2(); //链队的主函数
  24. void menu1(); //副菜单
  25. //顺序队的函数声明
  26. void Enqueue(SQ* q, int num);
  27. void Dequeue(SQ* q);
  28. void ClearQueue(SQ* q);
  29. DataType HeadOfQueue(SQ* q);
  30. int LengthOfQueue(SQ* q);
  31. void PrintQueue(SQ* q);
  32. void File(SQ* q);
  33. //链队的函数声明
  34. void Enqueue2(LQ* p, DataType num);
  35. void PrintQueue2(LQ* p);
  36. int SizeOfQueue2(LQ* p);
  37. DataType HeadOfQueue2(LQ* p);
  38. void ClearQueue2(LQ* p);
  39. void Dequeue2(LQ* p);
  40. void SaveFile2(LQ* q);

主菜单:

效果如图:

 代码及详情如下:

  1. /*所有函数声明和结构体声明都在这个头文件里*/
  2. #include"Queue.h"
  3. void menu() {
  4. printf("###################\n");
  5. printf(" 请选择:\n");
  6. printf(" 1、顺序队\n");
  7. printf(" 2、链队\n");
  8. printf(" 3、奇偶分配\n");
  9. printf(" 0、退出\n");
  10. printf("###################\n");
  11. }
  12. int main(){
  13. int chose;
  14. system("title 队列的操作");
  15. while (1) {
  16. system("cls"); //清屏
  17. menu(); //主菜单
  18. scanf("%d", &chose);
  19. switch (chose) {
  20. case 1: //进入顺序队的操作
  21. system("cls");
  22. system("title 顺序队");
  23. main1(); //顺序对的主函数
  24. break;
  25. case 2: //进入链队的操作
  26. system("cls");
  27. system("title 链队");
  28. main2(); //联队的主函数
  29. break;
  30. case 3:
  31. system("cls");
  32. system("title 奇偶分配");
  33. main3();
  34. system("pause");
  35. break;
  36. case 0:return;
  37. default:printf("输入错误!重新输入:\n"); system("pause");
  38. }
  39. }
  40. return 0;
  41. }

顺序队:

效果如图:

//主函数

  1. /*所有函数声明和结构体声明都在这个头文件里*/
  2. #include"Queue.h"
  3. int main1(){ //通过主菜单调用的
  4. SQ queue; //创建一个队
  5. SQ* q = &queue; //用指针操作
  6. q->rear = 0; //
  7. q->head = 0; //初始化
  8. q->length = 0; //
  9. int chose;
  10. int num;
  11. while (1) {
  12. menu1(); //菜单
  13. scanf("%d", &chose);
  14. switch (chose) {
  15. case 1:
  16. printf("请输入入队的值:");
  17. scanf("%d", &num);
  18. Enqueue(q, num); //入队操作
  19. printf("入队成功!\n");
  20. break;
  21. case 2:
  22. if (q->length == 0) {
  23. printf("当前空队!\n");
  24. break;
  25. }
  26. Dequeue(q); //出队操作
  27. printf("出队成功!\n");
  28. break;
  29. case 3:
  30. ClearQueue(q); //清空队操作
  31. printf("清空成功!\n");
  32. break;
  33. case 4: //显示队列首元素
  34. if (q->length == 0) {
  35. printf("当前空队!\n");
  36. break;
  37. }
  38. printf("该队列的首元素是:%d\n", HeadOfQueue(q));
  39. break;
  40. case 5: //显示队列长度
  41. printf("该队列的元素个数是:%d\n", LengthOfQueue(q));
  42. break;
  43. case 6:
  44. if (q->length == 0) {
  45. printf("当前空队!\n");
  46. break;
  47. }
  48. printf("当前队列:");
  49. PrintQueue(q); //打印队列
  50. printf("\n");
  51. break;
  52. case 7:
  53. File(q);
  54. printf("保存成功!\n");
  55. break;
  56. case 0:
  57. return 0;
  58. default:
  59. printf("输入错误!重新输入:\n");
  60. }
  61. }
  62. return 0;
  63. }

//菜单

  1. void menu1() {
  2. printf("###################\n");
  3. printf(" 1、数据入队\n");
  4. printf(" 2、数据出队\n");
  5. printf(" 3、清空队列\n");
  6. printf(" 4、队首元素\n");
  7. printf(" 5、元素个数\n");
  8. printf(" 6、打印队列\n");
  9. printf(" 7、保存为文件\n");
  10. printf(" 0、退出\n");
  11. printf("###################\n");
  12. printf("请输入:\n");
  13. }

 //入队

  1. //1、入队
  2. /*单个单个元素入队,也可以写个循环入队快点*/
  3. /*因为初始队的头指针尾指针都指在0的位置,所以入队rear要++*/
  4. void Enqueue(SQ* q,int num) {
  5. q->data[q->rear++] = num;
  6. q->length++; //队列的元素个数
  7. }

//出队

  1. //2、出队
  2. void Dequeue(SQ* q) {
  3. q->head++; //队的head++
  4. q->length--; //元素减少
  5. }

//清空队

  1. //3、清空队列
  2. void ClearQueue(SQ* q) {
  3. while (q->head != q->rear) { //将队列清空就是两头指针在一个位置,但head不能++到rear,因为清空栈栈的大小不会变
  4. q->rear--;
  5. }
  6. q->length = 0; //同时将元素个数变为0
  7. }

//队首元素

  1. //4、队首元素
  2. DataType HeadOfQueue(SQ* q) {
  3. return (q->data[q->head]); //只要不是出栈头指针是不会移动的,可以直接打印出来
  4. }

//队列元素个数

  1. //5、队列元素个数
  2. int LengthOfQueue(SQ* q) {
  3. return q->length; //直接打印length
  4. }

//打印队列

  1. //6、打印队列
  2. void PrintQueue(SQ* q) {
  3. int i = q->head; //打印队列但不是出队,所以拿两个指针代替原两指针操作
  4. int j = q->rear;
  5. for (i; i < j; i++) {
  6. printf("%d ", q->data[i]);
  7. }
  8. }

//保存为文件

  1. //7、保存文件
  2. void File(SQ* q) {
  3. FILE* pfWrite1;
  4. // 打开文件
  5. pfWrite1 = fopen("SqQueue.txt", "w");
  6. if (pfWrite1 == NULL) {
  7. printf("%s\n", strerror(errno));
  8. }
  9. //写文件
  10. for (int i = 0; i < q->length; i++) {
  11. fprintf(pfWrite1, "%d ", q->data[i]);
  12. }
  13. //关闭文件
  14. fclose(pfWrite1);
  15. pfWrite1 = NULL;
  16. }

链队:

效果如图:


//主函数

  1. /*所有函数声明和结构体声明都在这个头文件里*/
  2. #include"Queue.h"
  3. int main2(){ //通过主菜单调用的
  4. //创建头节点
  5. Node head = (Node)malloc(sizeof(Node));
  6. head->next = NULL;
  7. //创建链队
  8. LQ L;
  9. LQ* p = &L;
  10. p->size = 0; //链队的元素个数初始为0
  11. p->head = head; //联队的头指针初始指向头节点
  12. p->rear = head; //同上
  13. int chose;
  14. DataType num; //入队的值
  15. while (1) {
  16. menu1(); //菜单
  17. scanf("%d", &chose);
  18. switch (chose) {
  19. case 1: //入队操作
  20. printf("请输入要入队的值:\n");
  21. scanf("%d", &num);
  22. Enqueue2(p,num);
  23. printf("入队成功!\n");
  24. break;
  25. case 2: //出队操作
  26. if (p->head == p->rear) { //判断是否空队
  27. printf("当前是空队列!\n");
  28. break;
  29. }
  30. Dequeue2(p);
  31. printf("出队成功!\n");
  32. break;
  33. case 3: //清空队列
  34. ClearQueue2(p);
  35. printf("清空成功!\n");
  36. break;
  37. case 4: //队列首元素
  38. if (p->head == p->rear) {
  39. printf("当前是空队列!\n");
  40. break;
  41. }
  42. printf("该队列首元素是:%d \n",HeadOfQueue2(p));
  43. break;
  44. case 5: //队列元素个数
  45. printf("该队列元素个数是:%d\n",SizeOfQueue2(p));
  46. break;
  47. case 6: //打印队列
  48. if (p->head == p->rear) {
  49. printf("当前是空队列!\n");
  50. break;
  51. }
  52. printf("当前队列:");
  53. PrintQueue2(p);
  54. printf("\n");
  55. break;
  56. case 7:
  57. SaveFile2(p);
  58. printf("保存成功!\n");
  59. break;
  60. case 0:
  61. return 0;
  62. default:printf("输入错误!重新输入:\n");
  63. }
  64. }
  65. return 0;
  66. }

//入队

  1. //1、入队操作
  2. void Enqueue2(LQ* p,DataType num) {
  3. Node new = (Node*)malloc(sizeof(Node)); //新建一个结点
  4. new->data = num; //赋值
  5. new->next = NULL; //将他指向NULL
  6. p->rear->next = new; //第一次用尾指针代头节点将头节点与新结点连起来,以后就是将最后一个结点和新节点连起来
  7. p->rear = new; //尾指针移动到新结点上
  8. p->size++; //元素个数加一
  9. }

//出队

  1. //2、出队操作
  2. void Dequeue2(LQ* p) {
  3. p->head = p->head->next; //头指针移动到下一个即出队
  4. p->size--; //元素个数要减一
  5. }

//清空队

  1. //3、清空队列
  2. void ClearQueue2(LQ* p) {
  3. while (p->head != p->rear) { //一直出队直到两指针指在了一起
  4. Dequeue2(p); //调用出队函数
  5. }
  6. p->size = 0; //将元素个数为0
  7. }

//求队首元素

  1. //4、队首元素
  2. DataType HeadOfQueue2(LQ* p) {
  3. Node new = p->head->next; //用个new代替头指针,不然头指针会发生变化
  4. return new->data;
  5. }

//求元素个数

  1. //5、元素个数
  2. int SizeOfQueue2(LQ* p) {
  3. return p->size; //直接返回
  4. }

//打印队列

  1. //6、打印队列
  2. void PrintQueue2(LQ* p) {
  3. Node new = p->head->next; //打印不出队,所以用个new代替头指针,循环打印一直到new==NULL
  4. while (new != NULL) {
  5. printf("%2d ", new->data);
  6. new=new->next;
  7. }
  8. }

//保存为文件

  1. //7、保存文件
  2. void SaveFile2(LQ* q) {
  3. // 打开文件
  4. FILE* pfWrite2= fopen("LkQueue.txt", "w");
  5. if (pfWrite2 == NULL) {
  6. printf("%s\n", strerror(errno));
  7. }
  8. //写文件
  9. for (Node i = q->head->next; i !=NULL; i=i->next) {
  10. fprintf(pfWrite2, "%d ", i->data);
  11. }
  12. //关闭文件
  13. fclose(pfWrite2);
  14. pfWrite2 = NULL;
  15. }

奇偶分配:

效果如图:

代码及详情如下:

  1. #include"Queue.h"
  2. int main3(){
  3. //创建头节点
  4. Node head1 = (Node)malloc(sizeof(Node));
  5. Node head2 = (Node)malloc(sizeof(Node));
  6. head1->next = NULL;
  7. head2->next = NULL;
  8. int num;
  9. //创建两个链队
  10. LQ Q1; LQ Q2;
  11. LQ* q1; LQ* q2;
  12. q1 = &Q1; q2 = &Q2;
  13. //初始化
  14. q1->head = head1; q1->rear = head1;
  15. q2->head = head2; q2->rear = head2;
  16. q1->size = 0; q2->size = 0;
  17. //随机数种子
  18. srand((unsigned)time(NULL));
  19. for (int i = 0; i < 20; i++) {
  20. num = rand() % 100; //100以内的随机数
  21. if (num % 2 == 0) { //偶数
  22. Enqueue2(q1, num); //放在q1里面
  23. }
  24. else { //奇数
  25. Enqueue2(q2, num); //放在q2里面
  26. }
  27. }
  28. //打印看看
  29. printf("偶数为:");
  30. PrintQueue2(q1);
  31. printf("\n");
  32. printf("奇数为:");
  33. PrintQueue2(q2);
  34. printf("\n");
  35. printf("开始配对:\n");
  36. //将q1,q2从头节点的位置移到第一个结点的位置
  37. q1->head = q1->head->next;
  38. q2->head = q2->head->next;
  39. while (q1->head != NULL && q2->head != NULL) {//任何一个为NULL停止
  40. Sleep(300);
  41. printf("%2d ", q1->head->data);
  42. Sleep(300);
  43. printf("%2d ", q2->head->data);
  44. printf("\n");
  45. q1->head = q1->head->next;
  46. q2->head = q2->head->next;
  47. }
  48. return 0;
  49. }

总结:

1、一个程序里面只能有一个主函数,不管有多少个源文件

2、头文件一般是用来 声明的,一般不写实现代码,自己写的头文件用“”括起来

3、队就是线性表,用的都是顺序表和链表的形式实现的,写的时候会有点昏,但写完发现没有什么特别难的东西,都是老套路

4、这次写了个文件的保存操作,因为对文件操作的不熟悉所以没有写读取操作,连这个保存操作都是格式套的

5、奇偶分配这个了解了一下随机数,会用了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/646335
推荐阅读
相关标签
  

闽ICP备14008679号