使用 head + tail 两个头尾节点实现双向链表 (队列太多会占用内存), 数据的添加删除比较方便

#include "common.h"

#define nullptr 0

typedef struct LinkNode
{
	int id;
	int data;
	int memidx;
	LinkNode *prev;
	LinkNode *next;
}LinkNode;

#define maxmemsize 22
static LinkNode g_n_mem[maxmemsize]; // 使用静态内存

typedef struct Queue
{
	LinkNode *head;
	LinkNode *tail;
	int size;
}Queue;

typedef struct memHeap // 用一个堆链表实现静态内存的读取
{
	int heap[maxmemsize];
	int tail;
}memHeap;

static LinkNode * my_allocate(memHeap *mMemHeap) // 循环内存也可以通过 g_n_mem[g_n_mem_cnt++ % maxmemsize] 实现
{
	if (mMemHeap->tail <= 0)
		return nullptr;
	return &g_n_mem[mMemHeap->heap[--mMemHeap->tail]];
}

static void my_free(memHeap *mMemHeap, int memidx) // 静态内存的回收
{
	mMemHeap->heap[mMemHeap->tail++] = memidx;
}

static void init_queue(Queue **queue, memHeap *mMemHeap)
{
	if ((*queue) == nullptr)
	{
		(*queue) = new Queue;
	}

	Queue *Q = (*queue);
	Q->head = my_allocate(mMemHeap);
	Q->tail = my_allocate(mMemHeap);

	Q->head->prev = nullptr;
	Q->head->next = Q->tail;

	Q->tail->prev = Q->head;
	Q->tail->next = nullptr;
	Q->size = 0;
}

//从头节点处添加数据 static void en_queue_head(Queue* Q, LinkNode *pNode) { pNode->next = Q->head->next; pNode->prev = Q->head; Q->head->next->prev = pNode; Q->head->next = pNode; Q->size++; }
//从尾结点添加数据 static void en_queue_tail(Queue* Q, LinkNode *pNode) { pNode->next = Q->tail; pNode->prev = Q->tail->prev; Q->tail->prev->next = pNode; Q->tail->prev = pNode; Q->size++; } static LinkNode * de_queue_head(Queue* Q, memHeap *mMemHeap) //从头节点开始删除数据 { if (Q->size <= 0) return nullptr; LinkNode *pNode = Q->head->next; pNode->next->prev = Q->head; Q->head->next = pNode->next; Q->size--; mMemHeap->heap[mMemHeap->tail++] = pNode->memidx; return pNode; } static LinkNode * de_queue_tail(Queue* Q, memHeap *mMemHeap) //从尾部删除数据 { if (Q->size <= 0) return nullptr; LinkNode * pNode = Q->tail->prev; pNode->prev->next = Q->tail; Q->tail->prev = pNode->prev; Q->size--; my_free(mMemHeap, pNode->memidx); return pNode; } static void clear_queue(Queue* Q, memHeap *mMemHeap) { if (Q->size <= 0) return; LinkNode * pNode = Q->head->next; while (pNode != Q->tail) { my_free(mMemHeap, pNode->memidx); pNode = pNode->next; } Q->head->prev = Q->head->next = Q->head; } static void display_queue(Queue* Q) { if (Q->size <= 0) { LOGE("Q is null, return"); return; } LinkNode *pNode = Q->head->next; //for (register int i = 0; i < Q->size; i++) while (pNode != Q->tail) { printf("[%d %d] ", pNode->id, pNode->data); pNode = pNode->next; } printf(" "); } static void init_doule_list(Queue *Q, memHeap *mMemHeap, int num) { srand((int)time(0)); for (register int i = 0; i < num; i++) { LinkNode *pNode = my_allocate(mMemHeap); pNode->id = i; //pNode->data = i + 100;; //次关键字 pNode->data = 1 + rand() % (100 - 10 + 1) + 10; printf("[%d %d] ", pNode->id, pNode->data); //虽然进队函数不同,但下面两个生成的链表最终包含的数据是一样的 //en_queue_head(Q, pNode); en_queue_tail(Q, pNode); } printf(" "); } static void init_memory(memHeap **mMemHeap) { *mMemHeap = new memHeap; (*mMemHeap)->tail = maxmemsize; // 0 ~ maxmemsize-1 for (register int i = 0; i < maxmemsize; i++) { g_n_mem[i].memidx = i; (*mMemHeap)->heap[i] = i; } } extern void test_head_tail_double_list() { static memHeap *mMemHeap; init_memory(&mMemHeap); static Queue *mQ; init_queue(&mQ, mMemHeap); init_doule_list(mQ, mMemHeap, 20); display_queue(mQ); LOGE("dequeue from head : "); while (mQ->size > 0) { LinkNode *pNode = de_queue_head(mQ, mMemHeap); printf("[%d %d] memidx= %d Q size = %d tail= %d ", pNode->id, pNode->data, pNode->memidx, mQ->size, mMemHeap->tail); pNode->prev = pNode->next = nullptr; } LOGE(" "); clear_queue(mQ, mMemHeap); init_doule_list(mQ, mMemHeap, 20); display_queue(mQ); LOGE("dequeue from tail : "); while (mQ->size > 0) { LinkNode * pNode = de_queue_tail(mQ, mMemHeap); printf("[%d %d] memidx= %d Q size = %d tail= %d ", pNode->id, pNode->data, pNode->memidx, mQ->size, mMemHeap->tail); pNode->prev = pNode->next = nullptr; } LOGE(" "); display_queue(mQ); delete mMemHeap; mMemHeap = nullptr; delete mQ; mQ = nullptr; }

  

原文地址:https://www.cnblogs.com/Pitter99/p/15116768.html