双向循环链表 (只需要一个 head 节点), 从头尾部 删除 插入 数据都比较方便
Posted 皮特99
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向循环链表 (只需要一个 head 节点), 从头尾部 删除 插入 数据都比较方便相关的知识,希望对你有一定的参考价值。
#include "common.h" #define nullptr 0 #define maxmemsize 21 typedef struct memNode { int data; int next; }memNode; typedef struct memlinklist { memNode memory[maxmemsize]; int freep; int headp; }memlinklist; static memlinklist mMemorylink; int allocate_node() { int addr = mMemorylink.freep; mMemorylink.freep = mMemorylink.memory[mMemorylink.freep].next; return addr; } void free_node(int memidx) { mMemorylink.memory[memidx].next = mMemorylink.freep; mMemorylink.freep = memidx; } typedef struct LinkNode { int id; int data; int memidx; LinkNode *prev; LinkNode *next; }LinkNode; static LinkNode g_n_mem[maxmemsize]; typedef struct Queue { LinkNode *head; //只需要一个 head 实现双向循环链表 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->head->prev = Q->head->next = Q->head; 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->head; pNode->prev = Q->head->prev; Q->head->prev->next = pNode; Q->head->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->head->prev; pNode->prev->next = Q->head; Q->head->prev = pNode->prev; Q->size--; my_free(mMemHeap, pNode->memidx); return pNode; } static LinkNode * delete_key(Queue* Q, memHeap *mMemHeap, int key) { if (Q->size <= 0) return nullptr; LinkNode * pNode = Q->head->next; while (pNode != Q->head) { if (pNode->data == key) { pNode->prev->next = pNode->next; pNode->next->prev = pNode->prev; Q->size--; break; } pNode = pNode->next; } 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->head) { 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->head) { printf("[%d %d] ", pNode->id, pNode->data); pNode = pNode->next; } printf("\\n\\n"); } 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("\\n\\n"); } 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_one_head_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\\n", pNode->id, pNode->data, pNode->memidx, mQ->size, mMemHeap->tail); pNode->prev = pNode->next = nullptr; } LOGE("\\n"); clear_queue(mQ, mMemHeap); init_doule_list(mQ, mMemHeap, 20); display_queue(mQ); delete_key(mQ, mMemHeap, 110); //delete the node who\'s data == 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\\n", pNode->id, pNode->data, pNode->memidx, mQ->size, mMemHeap->tail); pNode->prev = pNode->next = nullptr; } LOGE("\\n"); display_queue(mQ); delete mMemHeap; mMemHeap = nullptr; delete mQ; mQ = nullptr; }
以上是关于双向循环链表 (只需要一个 head 节点), 从头尾部 删除 插入 数据都比较方便的主要内容,如果未能解决你的问题,请参考以下文章