数据结构——栈和队列相关算法实现 (2)

数据结构——栈和队列相关算法实现

算法小结

队列的操作和栈的操作基本原理上是差不多的,值得注意的是再对队列进行遍历的话和栈的遍历稍微有点差别。其中需要注意的地方已经在代码块中进行了说明。

基本算法演示(循环队列) /* 1.循环队列初始化 2.循环队列进队 3.循环队列出队 4.循环队列遍历 5.循环队列长度 */ // 实现循环队列 #include <stdio.h> #include <stdlib.h> #define MaxSize 21 typedef int ElementType; typedef struct { int data[MaxSize]; int rear; // 队尾指针 int front; // 队头指针 }Queue,*L; void InitQueue(Queue * Q ) { Q->front = Q->rear = 0; } // 元素入队 void AddQ(Queue *PtrQ, int item) { if( (PtrQ->rear+1)%MaxSize == PtrQ->front ) { printf("队列满.\n"); return; } PtrQ->rear = (PtrQ->rear+1) % MaxSize; PtrQ->data[PtrQ->rear] = item; } // 删除队头元素并把队头元素返回 int DeleteQ( Queue *PtrQ ) { if( PtrQ->front == PtrQ->rear ) { printf("队列空.\n"); return -1; } else { PtrQ->front = (PtrQ->front+1) % MaxSize; return PtrQ->data[PtrQ->front]; } } // 队列元素的遍历 void print(Queue *PtrQ) { int i = PtrQ->front; if( PtrQ->front == PtrQ->rear ) { printf("队列空."); return; } printf("队列存在的元素如下:"); while( i != PtrQ->rear) { printf("%d ", PtrQ->data[i+1]); i++; i = i % MaxSize; } return; } int len(Queue *PtrQ) { return (PtrQ->rear-PtrQ->front+MaxSize)%MaxSize; } int main() { Queue Q; //注意不是Queue * Q; 因为数组本身就是地址吧~(emmmm,应该是,求大佬解答) int length; length = len(&Q); //用Queue * Q 的话会报错 InitQueue(&Q); AddQ(&Q,1); AddQ(&Q,2); AddQ(&Q,3); AddQ(&Q,4); print(&Q); DeleteQ(&Q);//出队一次 print(&Q); printf("\n循环队列的长度为%d",length); return 0; } 运行演示

数据结构——栈和队列相关算法实现

算法小结

循环队列和链队列基本是一致的,之所以引入“循环队列”是因为,对于顺序列会存在“假溢出的现象”。相关概念不多做解释,原理主要在数据结构-用C语言描述(第二版)[耿国华] 一书的p101-103。值得注意的是,在main方法中和链队列不同的是Queue Q;个人认为是利用数组模拟的原因,因为数组本身也是利用地址传值嘛。关于循环队列长度计算:当rear大于front时,循环队列的长度:rear-front,当rear小于front时,循环队列的长度:分为两类计算 0+rear和Quesize-front即rear-front+Quesize。总的来说,总长度是(rear-front+Quesize)%Quesize

循环链表拓展 头节点循环链表

带头结点的循环链表表示队列, 并且只设一个指针指向队尾元素结点, 试编写相应的队列初始化,入队列和出队列的算法。

/* 数据结构算法题(假设以带头结点的循环链表表示队列, * 并且只设一个指针指向队尾元素结点(注意不设头指针) * 试编写相应的队列初始化,入队列和出队列的算法!) */ #include<stdio.h> #include<stdlib.h> #include<time.h> #define OK 1 #define ERROR 0 typedef int QElemType; typedef int Status; typedef struct QNode { QElemType data; struct QNode * rear; struct QNode * next; }QNode,*LinkQueue; //链式队列的初始化 Status InitLinkQueue(LinkQueue * L) { (*L)=(LinkQueue)malloc(sizeof(QNode)); if((*L)==NULL) { printf("内存分配失败!\n"); return OK; } (*L)->rear=(*L); return OK; } //链式队列的建立 Status Create(LinkQueue * L,int n) { srand(time(0)); LinkQueue P; for(int i=0;i<n;i++) { P=(LinkQueue)malloc(sizeof(QNode)); P->data=rand()%100+1; (*L)->rear->next=P; (*L)->rear=P; } P->next=(*L); return OK; } //入队操作 Status EnQueue(LinkQueue * L,QElemType e) { LinkQueue P; P=(LinkQueue)malloc(sizeof(QNode)); P->data=e; P->next=(*L); (*L)->rear->next=P; (*L)->rear=P; return OK; } //出队操作 Status DeQueue(LinkQueue * L,QElemType * e) { LinkQueue temp; *e=(*L)->next->data; temp=(*L)->next; (*L)->next=(*L)->next->next; delete(temp); return OK; } //输出 void Print(LinkQueue * L) { LinkQueue P; P=(*L)->next; printf("输出元素:\n"); while(P!=(*L)) { printf("%d ",P->data); P=P->next; } printf("\n"); } int main() { LinkQueue L; int ElemNumber; QElemType EnElem,DeElem; InitLinkQueue(&L); printf("请输入元素个数:\n"); scanf("%d",&ElemNumber); Create(&L,ElemNumber); Print(&L); printf("请输入入队元素:\n"); scanf("%d",&EnElem); EnQueue(&L,EnElem); Print(&L); printf("出队操作,并返回出队元素:\n"); DeQueue(&L,&DeElem); printf("出队元素为:%d\n",DeElem); Print(&L); return 0; } 参考文献

带头结点的循环链表表示队列, 并且只设一个指针指向队尾元素结点, 试编写相应的队列初始化,入队列和出队列的算法

数据结构-用C语言描述(第二版)[耿国华]

循环队列长度计算

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zysddy.html