• 使用 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; }

      

  • 相关阅读:
    关键路径的计算
    JSF简单介绍
    介绍:一款Mathematica的替代开源软件Mathetics
    素材链接
    JSP动作--JSP有三种凝视方式
    【InversionCount 逆序对数 + MergeSort】
    全响应跨设备的Zoomla!逐浪CMS2 x2.0正式公布
    DirectSound的应用
    “海归”首选北上广 薪资期望不太高-有感
    Servlet登陆功能的实现
  • 原文地址:https://www.cnblogs.com/Pitter99/p/15116768.html
Copyright © 2020-2023  润新知