加载中...
链式队列

链式队列

链式队列–使用链表模拟实现队列先进先出,主要由一个一个数据节点连接而成。下面代码封装了两种模式队列
一、更具入队出队改变队列长度,动态分配内存,以及节点内存大小也是动态更具需要分配
二、初始化为定长,节点空间固定大小,连接成环形队列。

图解两种模式队列

#ifndef __QUEUE_PUBLIC_H__
#define __QUEUE_PUBLIC_H__
#include <pthread.h>

typedef unsigned char  Type;

//链表节点
typedef struct Node
{
	Type* buff;
	size_t len;
	struct Node* next;
}Node;

//链表
typedef struct QueueList
{
	pthread_mutex_t mutex_lock;		//互斥锁防止同时出队,和入队活着一个出队一个入队时出现不同步
	size_t res;					//记录链表节点总个数
	size_t size;				//记录每个节点buff空间大小
	Node* head;		
	Node* tail;
}QueueList;

//初始化链式队列
int queuelist_init(QueueList** queue,int len,int size);
//创建节点
Node* node_create(QueueList* queue,Type* buff,int len);
//队列为空
int is_qempty(QueueList* queue);
//队列满
int is_qfull(QueueList* queue);
//队列字符串个数
int queuelist_num(QueueList* queue);
//入队(尾添加)
int Push_QueueList(QueueList* queue,Type* buff,int len);
//出队(头删除)
int Pop_QueueList(QueueList* queue,Type* buff,int len);
//清空队列中数据
void clean_queuelist(QueueList* queue,int len);
//销毁队列
int destroy_queuelist(QueueList** queue);

#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include "queue.h"



//初始化链式队列,len,size 都为0创建变长队列,都不为0创建len长度,每个size大小的队列
int queuelist_init(QueueList** queue,int len,int size)
{
	if((0 == len && 0 == size) || (0 < len && 0 < size))
	{		
		*queue = (QueueList*)malloc(sizeof(QueueList));
		if(NULL == *queue)
		{
			perror("failed while malloc <queuelist>");
			return -1;
		}
	int ret = pthread_mutex_init(&(*queue)->mutex_lock,NULL);
	if(ret)
	{
		printf("failed while MutexCreate\n");
		free(*queue);
		queue = NULL;
		return -1;
	}
		(*queue)->head = NULL;
		(*queue)->tail = NULL;
		(*queue)->res = 0;
		if(0 == len && 0 == size)
		{
			(*queue)->size =0;
			return 0;
		}

		(*queue)->size = size;
		for(int i = 0;i < len;i++)
		{
			Node* node = node_create(*queue,NULL,0);
			if(node == NULL)
			{
				return -1;
			}
			if(NULL == (*queue)->head && NULL == (*queue)->tail)
			{
				(*queue)->head = node;
				(*queue)->tail = node;
			}
			(*queue)->tail->next = node;
			(*queue)->tail = node;
			
		}
		(*queue)->tail->next = (*queue)->head;
		(*queue)->tail = (*queue)->head;
		return 0;
	}
	return -1;	
}

//创建节点 size == 0创建buff长度的节点,size> 0创建size长度的节点
Node* node_create(QueueList* queue,Type* buff,int len)
{

	Node* node = (Node*)malloc(sizeof(Node));
	if(NULL == node)
	{
		perror("failed while malloc <node>\n");
		return node;
	}

	node->buff =  (0 == queue->size) ? (Type*)malloc(len) : (Type*)malloc(queue->size);
	node->next = NULL;
	node->len = len;
	if(queue->size > 0)
	{
		bzero(node->buff,queue->size);
		return node;
	}

	memcpy(node->buff,buff,len);
	return node;
}

//队列为空
int is_qempty(QueueList* queue)
{
	if(NULL == queue)
	{
//		perror("queue is NULLL\n");
		return -1;
	}

	if(queue->res == 0)
	{
		return 1;
	}
	
	return 0;
}

//队列满
int is_qfull(QueueList* queue)
{
	if(NULL == queue)
	{
		printf("queue is NULL\n");
		return -1;
	}
	
	if(queue->size == 0)
	{
		printf("queue type error\n");
		return -1;
	}
	
	if(queue->res > 0 && queue->size > 0 && queue->head == queue->tail )
	{
		return 1;
	}
	return 0;
}

//队列字符串个数
int queuelist_num(QueueList* queue)
{
	if(NULL == queue)
	{
		perror("queue is NULL");
		return -1;
	}
	return queue->res;
}

//入队(尾添加)
int Push_QueueList(QueueList* queue,Type* buff,int len)
{
	pthread_mutex_lock(&queue->mutex_lock);
	if(NULL == queue)
	{
		perror("push fail,queue is NULL");
		pthread_mutex_unlock(&queue->mutex_lock);
		return -2;
	} 
	if(NULL == buff)
	{
		perror("push fail,buff is NULL");
		pthread_mutex_unlock(&queue->mutex_lock);
		return -1;
	}
	
	if(0 == queue->size)
	{
		Node* node = NULL;
		node = node_create(queue,buff,len);
		if(NULL == node)
		{
			pthread_mutex_unlock(&queue->mutex_lock);
			return -1;
		}
	
		if(NULL == queue->head)
		{
			queue->head = node;
			queue->tail = node;
			queue->res++;
			pthread_mutex_unlock(&queue->mutex_lock);
			return len;
		}
	
		queue->tail->next = node;
		queue->tail = node;
	}
	else
	{
		if(1 == is_qfull(queue))
		{
			printf("queue full\n");
			pthread_mutex_unlock(&queue->mutex_lock);
			return -1;
		}
		if(len > queue->size)
		{
			printf("buff too larger!\n");
			return -1;
		}
		memcpy(queue->tail->buff,buff,len);
		queue->tail->len = len;
		queue->tail=queue->tail->next;
	}
	queue->res++;
	pthread_mutex_unlock(&queue->mutex_lock);
	return len;
}

//出队(头删除)
int Pop_QueueList(QueueList* queue,Type* buff,int len)
{
	pthread_mutex_lock(&queue->mutex_lock);
	if(NULL == queue)
	{
		perror("pop fail,queue is NULL");
		pthread_mutex_unlock(&queue->mutex_lock);
		return -2;
	}
	
	if(1 == is_qempty(queue))
	{
		perror("pop fail,queue is empty");
		pthread_mutex_unlock(&queue->mutex_lock);
		return -1;
	}

	if(queue->head->len > len)
	{
		printf("buff is too samll!\n");
		pthread_mutex_unlock(&queue->mutex_lock);
		return -1;
	}

	int size=queue->head->len;
	memcpy(buff,queue->head->buff,queue->head->len);
	memset(queue->head->buff,0x0,queue->size);
	Node* node = queue->head;
	queue->head->len = 0;
	queue->head = queue->head->next;
	queue->res--;
	if(queue->size > 0)
	{
		pthread_mutex_unlock(&queue->mutex_lock);
		return size;
	}
	if(0 == queue->res) 
	{
		queue->tail=NULL;
	}
	free(node->buff);
	free(node);
    pthread_mutex_unlock(&queue->mutex_lock);
	return size;

}

void clean_queuelist(QueueList* queue,int len)
{
	Type buff[len];
	while(!is_qempty(queue))
	{
		Pop_QueueList(queue,buff,len);
	}
}

//销毁队列
int destroy_queuelist(QueueList** queue)
{
	pthread_mutex_lock(&(*queue)->mutex_lock);
	if(NULL == *queue)
	{
		pthread_mutex_unlock(&(*queue)->mutex_lock);
		return -1;
	}
	Node* head_node = (*queue)->head;
	for(Node* node = (*queue)->head;node != NULL && (*queue)->size == 0;)
	{
		Node* temp = node;
		node = node->next;
		free(temp->buff);
		free(temp);
		(*queue)->res--;
	}
	for(Node* node = (*queue)->head;(*queue)->size > 0;)
	{
		Node* temp = node;
		node = node->next;
		free(temp->buff);
		free(temp);
		(*queue)->res--;
		if(head_node == node) break;
	}
	free(*queue);
	(*queue) = NULL;
	pthread_mutex_unlock(&(*queue)->mutex_lock);
	return 0;
}
上一篇:
iptables网络共享
下一篇:
管脚复用
本文目录
本文目录