前言: 此代码可动态的构建内存队列,当队列长度达到最大长度(MAXLEN ),ac_adjust_queue函数会删除队列中无效的内存。
1、头文件 linkqueue.h
#ifndef _MEM_LINK_H
#define _MEM_LINK_H
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR -1
#define TRUE 1
#define FALSE 0
#define OVERMEM -2
#define MAXLEN 3
typedef struct FrameInfo
{
unsigned int width;
unsigned int height;
unsigned int istate;
unsigned char* memry;
}FrameInfo;
typedef FrameInfo ElemType;
typedef struct LinkNode {
ElemType data;
struct LinkNode *next;
}LinkNode, *LinkNodePtr;
typedef struct {
LinkNodePtr front;
LinkNodePtr rear;
}LinkQueue;
int ac_init_queue(LinkQueue *Q);
int av_clear_queue(LinkQueue *Q);
int ac_destroy_queue(LinkQueue *Q);
int ac_queue_empty(LinkQueue Q);
int ac_queue_lenth(LinkQueue Q);
int ac_adjust_queue(LinkQueue *Q);
int ac_get_head(LinkQueue Q, ElemType *e);
int ac_get_ready(LinkQueue Q, ElemType **e);
int ac_entry_queue(LinkQueue *Q, ElemType *e);
int ac_out_queue(LinkQueue *Q, ElemType *e);
#endif
2、相应的实现文件 linkqueue.c
#include <string.h>
#include "linkqueue.h"
/*初始化队列(链表)*/
int ac_init_queue(LinkQueue *Q) {
//initiate an empty queue
Q->front = Q->rear = (LinkNodePtr)malloc(sizeof(LinkNode));
if (!Q->front)
return OVERMEM;
Q->front->next = NULL;
return OK;
}
/*清空队列*/
int av_clear_queue(LinkQueue *Q) {
//clear an exitstd queue
if (Q->front == NULL)
return ERROR;
LinkNodePtr p, q;
Q->rear = Q->front;
p = Q->front->next;
Q->front->next = NULL;
while (p) {
q = p;
p = p->next;
free(q);
}
return OK;
}
/*销毁队列*/
int ac_destroy_queue(LinkQueue *Q) {
//destroy an existed queue
if (Q->front == NULL)
return ERROR;
while (Q->front) {
Q->rear = Q->front->next;
free(Q->front);
Q->front = Q->rear;
}
return OK;
}
/*判断队列是否为空*/
int ac_queue_empty(LinkQueue Q) {
//whether the queue is empty
if (Q.front == NULL)
return ERROR;
else if (Q.front->next == NULL)
return TRUE;
else
return FALSE;
}
/*获取队列的长度*/
int ac_queue_lenth(LinkQueue Q) {
//get the length of the queue
if (Q.front == NULL)
return ERROR;
int len = 0;
LinkNodePtr p;
p = Q.front;
while (p != Q.rear) {
len++;
p = p->next;
}
return len;
}
/*调整队列,删除队列中不合要求的元素*/
int ac_adjust_queue(LinkQueue *Q){
LinkNodePtr ptr;
LinkNodePtr curptr, preptr;
int iwidth, iheight, idx, ix, noest;
int imaxc = 0, imaxidxco = 0;
int iPw[MAXLEN] = { 0, 0 }, iPh[MAXLEN] = { 0, 0 }, iPc[MAXLEN] = {0, 0};
ptr = Q->front;
if (ac_queue_lenth(*Q) >= MAXLEN){
//统计开辟的内存中,宽与高组合的概率
ix = 0, noest = 0;
while (ptr != Q->rear){
ptr = ptr->next;
if (ptr != NULL){
iwidth = ptr->data.width;
iheight = ptr->data.height;
for (idx = 0; idx < MAXLEN; idx++){
if (iPw[idx] == iwidth && iPh[idx] == iheight){
iPc[idx]++;
noest = 0;
break;
}
else{
noest = 1;
}
}
if (idx == MAXLEN && noest == 1){
iPw[ix] = iwidth;
iPh[ix] = iheight;
iPc[ix]++;
ix++;
}
}
}
//寻找出现次数最多的宽高组合
for (idx = 0; idx < MAXLEN; idx++){
if (iPc[idx] > imaxc){
imaxc = iPc[idx];
imaxidxco = idx;
}
}
//调整队列链表, 删除不合要求的内存
//LinkNodePtr curptr, preptr;
/*curptr = Q.front->next;
if (curptr->data.width != iPw[imaxidxco] || ptr->data.height != iPh[imaxidxco]){
Q.front->next = curptr->next;
free(curptr);
}*/
preptr = Q->front;
curptr = preptr->next;
while (curptr != NULL){
if (curptr->data.width != iPw[imaxidxco] || curptr->data.height != iPh[imaxidxco]){
preptr->next = curptr->next;
free(curptr->data.memry);
free(curptr);
curptr = preptr->next;
}
else{
preptr = curptr;
curptr = preptr->next;
}
}
}
return 0;
}
/*获取队列头元素*/
int ac_get_head(LinkQueue Q, ElemType *e) {
//get the head element of the queue
if (Q.front == Q.rear)
return ERROR;
*e = Q.front->next->data;
return OK;
}
/*获取队列中可用的元素*/
int ac_get_ready(LinkQueue Q, ElemType **e){
LinkNodePtr ptr;
if (Q.front == NULL)
return ERROR;
ptr = Q.front;
while (ptr != Q.rear ){
ptr = ptr->next;
if (ptr->data.istate == 0)
break;
}
if (ptr != Q.rear || ptr->data.istate == 0){
*e = &ptr->data;
return OK;
}
else{
return FALSE;
}
}
/*元素入队列*/
int ac_entry_queue(LinkQueue *Q, ElemType *e) {
//input an element e as the new rear of the queue
LinkNodePtr p;
p = (LinkNodePtr)malloc(sizeof(LinkNode));
if (!p)
return OVERMEM;
p->data.memry = e->memry;//(unsigned char*)malloc(e.width * e.height * sizeof(unsigned char));
p->data.width = e->width;
p->data.height = e->height;
p->data.istate = e->istate;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
return OK;
}
/*元素出队列*/
int ac_out_queue(LinkQueue *Q, ElemType *e) {
//delete an element which was the head of the queue
if (Q->front == Q->rear)
return ERROR;
LinkNodePtr p;
p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front;
free(p);
return OK;
}
3、主函数main.c
#include "linkqueue.h"
int main() {
ElemType in;
ElemType *ot = NULL;
LinkQueue *q1 = (LinkQueue*)malloc(sizeof(LinkQueue));
ac_init_queue(q1);
GETMEM:
if (ac_queue_empty(*q1) == 1)
{
in.width = 1281;
in.height = 720;
in.istate = 1;
in.memry = (unsigned char*)malloc(in.width * in.height * sizeof(unsigned char));
memset(in.memry, 0, in.width * in.height);
ac_entry_queue(q1, &in);
}
else
{
if (ac_get_ready(*q1, &ot) != 1)//队列中无可用内存
{
in.width = 1280;
in.height = 720;
in.istate = 1;
in.memry = (unsigned char*)malloc(in.width * in.height * sizeof(unsigned char));
ac_entry_queue(q1, &in);
}
}
in.width = 1280;
in.height = 721;
in.istate = 0;
in.memry = (unsigned char*)malloc(in.width * in.height * sizeof(unsigned char));
ac_entry_queue(q1, &in);
in.width = 1280;
in.height = 720;
in.istate = 0;
in.memry = (unsigned char*)malloc(in.width * in.height * sizeof(unsigned char));
ac_entry_queue(q1, &in);
ac_adjust_queue(q1);
if (ac_get_ready(*q1, &ot) != 1)
{
printf("can not get memory!\n");
return ERROR;
}
if (ot->width != 1280 || ot->height != 720){
ot->istate = 2;
goto GETMEM;
}
return 0;
}
参考网址:http://blog.csdn.net/went2011/article/details/6929509