数据结构-单链队列相关操作算法

#include <stdio.h>
#include <stdlib.h>

#define OVERFLOW -2
#define OK 1
#define ERROR 0

typedef int QElemType;

//单链队列结构体定义
typedef struct QNode {
    QElemType data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

//当所有自定义的函数都写在主函数前面时,可以不用声明各个函数;当主函数写在最前面时,所有自定义的函数都要在主函数之前进行声明

//函数声明(此时不声明也可以)
int InitQueue(LinkQueue *Q);//初始化队列
int DestoryQueue(LinkQueue *Q);//销毁队列
int EmptyQueue(LinkQueue *Q);//判断队列是否为空
int EnQueue(LinkQueue *Q,QElemType e);//插入元素e为Q的新的队尾元素
int DeQueue(LinkQueue *Q,QElemType *e);//删除非空队列的队头元素,并用e返回删除元素的值
int ClearQueue(LinkQueue *Q);//清空队列
int QueueLength(LinkQueue *Q);//取得队列的长度
int GetHead(LinkQueue *Q,QElemType *e);//取得队头元素
void visit(QElemType e);//自定义visit函数,表示输出元素的值
void QueueTraverse(LinkQueue *Q,void *visit(QElemType));//从队头到队尾依次对队列Q中每个元素调用visit函数

//初始化队列
int InitQueue(LinkQueue *Q) {
    Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
    if(!Q->front) exit(OVERFLOW);
    Q->front->next = NULL;
    return OK;
}

//销毁队列
int DestoryQueue(LinkQueue *Q) {
    while(Q->front) {
        Q->rear = Q->front->next;
        free(Q->front);
        Q->front = Q->rear;
    }
    return OK;
}

//判断队列是否为空,为空返回1,不为空返回0
int EmptyQueue(LinkQueue *Q) {
    if(Q->front == Q->rear) {
        return OK;
    } else {
        return ERROR;
    }
}

//插入元素e为Q的新的队尾元素
int EnQueue(LinkQueue *Q,QElemType e) {
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);
    p->data = e;
    p->next = NULL;
    Q->rear->next = p;
    Q->rear = p;
    return OK;
}

//删除非空队列的队头元素,并用e返回删除元素的值
int DeQueue(LinkQueue *Q,QElemType *e) {
    QueuePtr p;
    if(Q->front == Q->rear) return ERROR;
    p = Q->front->next;
    *e = p->data;
    Q->front->next = p->next;
    if(Q->rear == p) {
        Q->rear = Q->front;
        Q->front->next = NULL;
    }
    free(p);
    return OK;
}

//清空队列
int ClearQueue(LinkQueue *Q) {
    QueuePtr p,q;
    if(!EmptyQueue(Q)) {
        p = Q->front->next;
        while(p!=Q->rear) {
            q = p;
            Q->front->next = p->next;
            p = p->next;
            free(q);
        }
        free(p);
        Q->rear = Q->front;
        return OK;
    } else {
        return ERROR;
    }

}

//取得队列的长度
int QueueLength(LinkQueue *Q) {
    QueuePtr p;
    int i=0;
    p = Q->front;
    while(p!=Q->rear) {
        ++i;
        p = p->next;
    }
    return i;
}

//取得队头元素
int GetHead(LinkQueue *Q,QElemType *e) {
    if(!EmptyQueue(Q)) {
        *e = Q->front->next->data;
        return OK;
    } else {
        return ERROR;
    }
}

//自定义visit函数,表示输出元素的值
void visit(QElemType e) {
     printf("%d ",e);
 }

//从队头到队尾依次对队列Q中每个元素调用visit函数
void QueueTraverse(LinkQueue *Q,void *visit(QElemType)) {
    QueuePtr p;
    p = Q->front->next;
    printf("队列中的元素为:");
    while(p) {
        visit(p->data);
        p= p->next;
    }
    printf("\n");
}

int main()
{
    LinkQueue *link;
    int f1,f2,f3,f4,f5,f6,e,i,a,len,n;

//队列初始化
    f1 = InitQueue(link);
    if(f1) printf("队列初始化成功!\n");
    else printf("队列初始化失败!\n");

//入队
    printf("请输入队列中元素的个数:");
    scanf("%d",&n);
    printf("请输入队列中元素的值:");
    for(i=0; i<n; i++) {
        scanf("%d",&a);
        EnQueue(link,a);
    }

//获取队列长度
    len = QueueLength(link);
    printf("队列的长度为:%d\n",len);

//判断队列是否为空
    f2 = EmptyQueue(link);
    if(f2) printf("队列为空!\n");
    else printf("队列不为空!\n");

//遍历队列
    QueueTraverse(link,&visit);

//出队
    f3 = DeQueue(link,&e);
    if(f3) printf("删除的队头元素为:%d\n",e);
    else printf("队列为空!无法删除队头元素!\n");

//取得队头元素
    f4 = GetHead(link,&e);
    if(f4) printf("队头元素为:%d\n",e);
    else printf("队列为空!");

//清空队列
    f6 = ClearQueue(link);
    if(f6) printf("清空队列成功!\n");
    else printf("清空队列失败!\n");

//销毁队列
    f5 = DestoryQueue(link);
    if(f5) printf("销毁队列成功!\n");
    else printf("销毁队列失败!\n");

return 0;
}

时间: 2024-10-11 23:13:39

数据结构-单链队列相关操作算法的相关文章

STL之heap相关操作算法

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 堆(heap)是一种非常重要的数据结构(这里我们讨论的是二叉堆),它是一棵满足特定条件的完全二叉树,堆的定义如下: 堆是一棵树完全二叉树,对于该完全二叉树中的每一个结点x,其关键字大于等于(或小于等于)其左右孩子结点,而其左右子树均为一个二叉堆. 在上述的定义中,若堆中父亲结点关键字的值大于等于孩子结点,则称该堆为大顶堆:若堆中父亲结点关键子的值小于等于孩子结点,则称该堆为小顶堆. 由于堆是一棵完全二叉树,所以我们可以很轻易地用一个数组存储堆中

数据结构(C语言版)链表相关操作算法的代码实现

这次实现的是带头结点的单链表的初始化.遍历.创建.插入.删除.判断链表是否为空.求链表长度函数,编译环境是vs2013. 其中插入和删除函数中循环的条件目前还不太明白. #include<iostream> using namespace std; typedef int Status; typedef char Elemtype; //定义链表的存储结构,注意这里与算法的定义有一处不同,是定义结构体时就命名Lnode,说明*next的类型只要说是Lnode类型就可以 typedef stru

linux消息队列相关操作

/* 发送消息队列 */ #include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ipc.h>#include <sys/msg.h> struct mymsg { long mtype; /* messag

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

数据结构栈和队列的基本算法实现 限定性线性表--栈 栈的定义 栈作为一种限定性的线性表,是将线性表的插入和删除操作限制为仅在表的一端进行. 基本算法演示 /* 栈的常见操作: 1.初始化栈 2.元素进栈 3.元素出栈 4.栈的遍历 5.判断栈是否为空栈 6.清空整个栈 */ # include <stdio.h> # include <stdlib.h> typedef struct Node { int date; struct Node * pNext; }NODE,* PNO

数据结构——串的相关算法实现

数据结构--串的相关算法实现 顺序串的插入函数实现 在进行顺序串的插入时,插入pos将串分为两个部分(假设为A.B,长度为LA.LB)及待插入部分(假设为C,长度为LC),则串由插入前的AB变为ACB,由于是顺序串,插入会引起元素的移动.可能会出现以下的三种情况: ①插入后串长度(LA+LC+LB)<=MAXLEN,则将B后移LC个元素位置,再将C插入: ②插入后串长度 >=MAXLEN 且 pos+LC <=MAXLEN,则 B 后移时会有部分字符被舍弃; ③插入后串长度>MAX

数据结构-字符串的统计相关操作

统计字符串的相关操作 统计字符出现次数 /*统计串S中字符的种类和个数*/ #include<cstring> #include<iostream> using namespace std; #define OK 1 #define ERROR 0 #define OVERFLOW -2 typedef int Status; #define MAXSTRLEN 255 //用户可在255以内定义最长串长 //typedef char SString[MAXSTRLEN+1]; /

Scala学习(三)----数组相关操作

数组相关操作 摘要: 本篇主要学习如何在Scala中操作数组.Java和C++程序员通常会选用数组或近似的结构(比如数组列表或向量)来收集一组元素.在Scala中,我们的选择更多,不过现在我们先假定不关心其他选择,而只是想马上开始用数组.本篇的要点包括: 1. 若长度固定则使用Array,若长度可能有变化则使用ArrayBuffer 2. 提供初始值时不要使用new 3. 用()来访问元素 4. 用for (elem<-arr)来遍历元素 5. 用for (elem<-arr if…)…yie

Linux TCP队列相关参数的总结 转

    在Linux上做网络应用的性能优化时,一般都会对TCP相关的内核参数进行调节,特别是和缓冲.队列有关的参数.网上搜到的文章会告诉你需要修改哪些参数,但我们经常是知其然而不知其所以然,每次照抄过来后,可能很快就忘记或混淆了它们的含义.本文尝试总结TCP队列缓冲相关的内核参数,从协议栈的角度梳理它们,希望可以更容易的理解和记忆.注意,本文内容均来源于参考文档,没有去读相关的内核源码做验证,不能保证内容严谨正确.作为Java程序员没读过内核源码是硬伤. 下面我以server端为视角,从 连接建

[转]一些NSArray,NSDictionary,NSSet相关的算法知识

iOS编程当中的几个集合类:NSArray,NSDictionary,NSSet以及对应的Mutable版本,应该所有人都用过.只是简单使用的话,相信没人会用错,但要做到高效(时间复杂度)精确(业务准确性),还需要了解其中所隐藏的算法知识. 在项目当中使用集合类几乎是不可避免的,集合类的使用场景其实可以进行抽象的归类.大多数时候我们需要将若干个对象(object)暂时保存起来,以备后续的业务逻辑进行操作,「保存和操作」,或者说「存与取」,对应到计算机世界的术语就是读和写.最初保存的时候我们Ins