队列:
特点:
1、队列是只允许在一段插入,而在另一端进行删除操作的线性表
2、允许插入的称为队尾,允许删除的一端对头
3、先进先出,FIFO。
物理机构:
顺序队列
循环队列
常规操作 :入队 出队
顺序表队列:
seqqueue.h:
#ifndef _SEQQUE_H_
#define _SEQQUE_H_
typedef int DATATYPE;
typedef struct {
DATATYPE *array;
int tlen;
int head;
int tail;
}SeqQueue;
SeqQueue *CreateSeqQueue(int len);
int DestroySeqQueue(SeqQueue *queue);
int QuitSeqQueue(SeqQueue *queue);
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data);
int IsEmptySeqQueue(SeqQueue *queue);
int IsFullSeqQueue(SeqQueue *queue);
DATATYPE* GetHeadSeqQueue(SeqQueue* queue);
#endif
seqqueue.c
#include "seqque.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
SeqQueue *CreateSeqQueue(int len)
{
SeqQueue* sq =(SeqQueue*)malloc(sizeof(SeqQueue));
if(NULL == sq)
{
perror("CreateSeqQueue malloc");
return NULL;
}
sq->array = (DATATYPE*)malloc(sizeof(DATATYPE)*len);
if(NULL == sq->array)
{
perror("CreateSeqQueue");
return NULL;
}
sq->tlen = len;
sq->head = 0 ;
sq->tail = 0 ;
return sq;
}
int DestroySeqQueue(SeqQueue *queue)
{
return 0;
}
int QuitSeqQueue(SeqQueue *queue)
{
if(IsEmptySeqQueue(queue))
{
return 1;
}
queue->head = (queue->head +1)%queue->tlen ;
return 0;
}
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data)
{
if(IsFullSeqQueue(queue))
{
return 1;
}
memcpy(&queue->array[queue->tail],data,sizeof(DATATYPE));
queue->tail = (queue->tail +1)%queue->tlen;
return 0;
}
int IsEmptySeqQueue(SeqQueue *queue)
{
return queue->head == queue->tail ;
}
int IsFullSeqQueue(SeqQueue *queue)
{
return (queue->tail +1 )%queue->tlen == queue->head ;
}
DATATYPE* GetHeadSeqQueue(SeqQueue* queue)
{
if(IsEmptySeqQueue(queue)) return NULL;
return &queue->array [queue->head];
}
示例:
#include "seqque.h"
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
#include <unistd.h>
sem_t sem_task;
void* th1(void* arg)
{
SeqQueue* sq =(SeqQueue*) arg;
DATATYPE data;
while(1)
{
bzero(&data,sizeof(data));
sem_wait(&sem_task);
DATATYPE* tmp = GetHeadSeqQueue(sq);
memcpy(&data,tmp,sizeof(DATATYPE));
QuitSeqQueue(sq);
if(0 == strcmp(data.task_name ,"over"))
{
break;
}
while(data.task_time--)
{
printf("I'm %s\n",data.task_name);
sleep(1);
}
}
return NULL;
}
int main(int argc, char *argv[])
{
DATATYPE data []=
{
{"cooking", 5},
{"washing", 3},
{"working", 8},
{"playing", 5},
{"over",0},
};
SeqQueue* sq = CreateSeqQueue(10);
pthread_t tid1;
sem_init(&sem_task,0,0);
pthread_create(&tid1,NULL,th1,sq);
DATATYPE dat;
while(1)
{
bzero(&dat,sizeof(dat));
char buf[5]={0};// 1 2 3 4 5\n
int num = 0 ;
fgets(buf,sizeof(buf),stdin);
num = atoi(buf);
//dat = data[num-1];
memcpy(&dat,&data[num-1],sizeof(DATATYPE));
EnterSeqQueue(sq,&dat);
sem_post(&sem_task);
if(0 ==strcmp(dat.task_name ,"over"))
{
break;
}
}
pthread_join(tid1,NULL);
sem_destroy(&sem_task);
DestroySeqQueue(sq);
return 0;
}
链式表队列:
linkqueue.h:
#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_
typedef int DATATYPE;
typedef struct link_que_node {
DATATYPE data;
struct link_que_node *next;
}QueueNode;
typedef struct {
QueueNode *head;
int clen;
QueueNode *tail;
}LinkQueue;
LinkQueue *CreateLinkQueue();
int DestroyLinkQueue(LinkQueue *queue);
int QuitLinkQueue(LinkQueue *queue);
DATATYPE* GetHeadLinkQue(LinkQueue*queue);
int EnterLinkQueue(LinkQueue *queue, DATATYPE *data);
int IsEmptyLinkQueue(LinkQueue *queue);
#endif
linkqueue.c:
#include "linkqueue.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
LinkQueue *CreateLinkQueue()
{
LinkQueue* lq = (LinkQueue*)malloc(sizeof(LinkQueue));
if(NULL == lq)
{
perror("CreateLinkQueue malloc");
return NULL;
}
lq->head = NULL;
lq->tail = NULL;
lq->clen = 0;
return lq;
}
int DestroyLinkQueue(LinkQueue *queue)
{
while(!IsEmptyLinkQueue(queue))
{
QuitLinkQueue(queue);
}
free(queue);
return 0;
}
int QuitLinkQueue(LinkQueue *queue)
{
if(IsEmptyLinkQueue(queue))
{
return 1;
}
QueueNode* tmp = queue ->head ;
queue->head = queue->head->next ;
free(tmp);
queue->clen --;
if(NULL == queue->head )
{
queue->tail = NULL;
}
return 0;
}
DATATYPE* GetHeadLinkQue(LinkQueue*queue)
{
if(IsEmptyLinkQueue(queue))
{
return NULL;
}
return &queue->head->data;
}
int EnterLinkQueue(LinkQueue *queue, DATATYPE *data)
{
QueueNode* newnode =(QueueNode*)malloc(sizeof(QueueNode));
if(NULL == newnode)
{
perror("EnterLinkQueue malloc");
return 1;
}
memcpy(&newnode->data,data,sizeof(DATATYPE));
newnode->next = NULL;
if(IsEmptyLinkQueue(queue))
{
queue->head = newnode;
queue->tail = newnode;
}
else
{
queue->tail->next = newnode;
queue->tail = newnode;
}
queue->clen ++;
return 0;
}
int IsEmptyLinkQueue(LinkQueue *queue)
{
return 0 == queue->clen;
}
示例:
把指定目录 所有 遍历.h #define Log #define PI 3.14 24 filename 1.主线程:如果是文件,找#define,找到写文件 如果是目录,就入队 2.工作线程 如果是文件,找#define,找到写文件
#include "linkqueue.h"
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <dirent.h>
#include <semaphore.h>
#define PATH "/home/linux/20240108"
pthread_t main_tid;
sem_t sem_task;
int check_file(char *path,FILE* log)
{
printf("processing %s\n",path);
FILE* fp = fopen(path,"r");
if(NULL == fp)
{
perror("check_file fopen");
return 1;
}
int num =1;
while(1)
{
char buf[1024]={0};
if(fgets(buf,sizeof(buf),fp))
{
if(strstr(buf,"#define"))
{
buf[strlen(buf)-1]='\0';
fprintf(log,"%s %d %s\n",buf,num,path );
fflush(log);
}
}
else
{
break;
}
num++;
}
fclose(fp);
return 0;
}
int do_ls(char* path,FILE* log,LinkQueue*lq)
{
DIR* dir = opendir(path);
if(NULL == dir)
{
perror("opendir");
return 1;
}
char newpath[512]={0};
DATATYPE data;
while(1)
{
bzero(newpath,sizeof(newpath));
bzero(&data,sizeof(DATATYPE));
struct dirent* info = readdir(dir);
if(NULL == info)
{
break;
}
sprintf(newpath,"%s/%s",path,info->d_name);
if(DT_DIR == info->d_type)
{
if(0 == strcmp(info->d_name,".")
|| 0 == strcmp(info->d_name,".."))
{
continue;
}
if(main_tid == pthread_self())
{
strcpy(data.pathname, newpath);
EnterLinkQueue(lq,&data);
sem_post(&sem_task);
}
else
{
do_ls(newpath,log,lq);
}
}
else
{
check_file(newpath,log);
}
}
closedir(dir);
return 0;
}
typedef struct
{
FILE* fp ;
LinkQueue* lq;
}TH_ARG;
void* th(void* arg)
{
TH_ARG *tmp = (TH_ARG*)arg;
FILE* log = tmp->fp ;
LinkQueue*lq = tmp->lq ;
char path[512]={0};
while(1)
{
bzero(path,sizeof(path));
sem_wait(&sem_task);
DATATYPE* ret = GetHeadLinkQue(lq);
strcpy(path,ret->pathname);
QuitLinkQueue(lq);
if(0 == strcmp(path,"over"))
{
break;
}
do_ls(path,log,lq);
}
return NULL;
}
int main(int argc, char *argv[])
{
main_tid=pthread_self();
TH_ARG arg;
bzero(&arg,sizeof(arg));
LinkQueue* lq = CreateLinkQueue();
FILE* log = fopen("log","w");
if(NULL == log)
{
perror("fp");
return 1;
}
arg.fp = log;
arg.lq = lq;
sem_init(&sem_task,0,0);
pthread_t tid1,tid2,tid3;
pthread_create(&tid1,NULL,th,&arg);
pthread_create(&tid2,NULL,th,&arg);
pthread_create(&tid3,NULL,th,&arg);
do_ls(PATH,log,lq);
int i = 0 ;
for(i =0;i<3;i++)
{
DATATYPE data;
strcpy(data.pathname,"over");
EnterLinkQueue(lq,&data);
sem_post(&sem_task);
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_join(tid3,NULL);
fclose(log);
sem_destroy(&sem_task);
DestroyLinkQueue(lq);
return 0;
}