1. 程式人生 > >靜態記憶體分配-連結串列管理(1)單向量表講解

靜態記憶體分配-連結串列管理(1)單向量表講解

單向連結串列

單向量表有頭節點 和節點組成,頭節點主要是管理連結串列使用,節點組成資料。

資料結構

頭節點結構
**last指向尾節點的Next指標,在節點尾部插入節點時,直接調整頭節點的last內容的指向即可在尾部插入。first指標指向連結串列的首節點。
節點結構
value是資料,Next指向下一個節點。

連結串列操作

連結串列成員變數定義

成員變數主要有頭結點和節點,頭結點不是真正的有效資料,主要是利於連結串列的插入,遍歷等,節點是連結串列中主要的資料。

程式碼

定義節點

#define SIMPLEQ_ENTRY(type)                     \
struct {    \
struct type *sqe_next;  /* next element */          \
}

上述程式碼定義了節點中的Next指標域,type是連結串列的型別,例如連結串列節點定義如下:

struct items_type{
SIMPLEQ_ENTRY(items_type) field; 
u8 value;
};

上述程式碼定義了一個連結串列節點型別,可使用該型別定義一個節點。例如

struct items_type node0 = {.value = 0};
struct items_type node1 = {.value = 1};
struct items_type node2 = {.value = 2};
struct items_type node3 = {.value = 3};

定義了三個節點。

#define SIMPLEQ_HEAD(name, type)                    \
struct name {                               \
struct type *sqh_first; /* first element */         \
    struct type **sqh_last; /* addr of last next element */     \
}

上述程式碼定義了連結串列的頭節點。name為頭結點的名字,type為節點的型別,例子

SIMPLEQ_HEAD(head, items_type) list_head;

上述程式碼定義了名為 list_head的頭節點。

API

#define SIMPLEQ_ENTRY(type)

定義節點型別,型別名為type。

#define SIMPLEQ_HEAD(name, type)

定義頭節點,name為頭節點名,type為節點型別。

#define SIMPLEQ_HEAD_INITIALIZER(head)
#define SIMPLEQ_INIT(head)

兩個API作用相同,頭節點初始化。

#define SIMPLEQ_INSERT_HEAD(head, elm, field)

在連結串列首部插入一個節點,head為頭節點,elm為要插入的元素,filed為指標域,與節點型別有關,上面的例子中型別的指標域名為filed,以後的使用過程也必須用filed。

#define SIMPLEQ_INSERT_TAIL(head, elm, field)

在連結串列的尾部插入一個節點,head為頭節點,lem為要插入的元素,filed見上述解釋。

#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field)

在連結串列的listelm節點後插入elm節點。其他見上述解釋。

#define SIMPLEQ_REMOVE_HEAD(head, field)

移除連結串列中的首節點。

#define SIMPLEQ_REMOVE(head, elm, type, field)
SIMPLEQ_REMOVE(&list_head, &node1, items_type, field);

移除連結串列中的elm節點,type為節點的型別。

#define SIMPLEQ_FOREACH(var, head, field)
SIMPLEQ_FOREACH(ptype, &list_head, field) {
    printf("value = %4d,", ptype->value);
}

遍歷連結串列,例子如上。

#define SIMPLEQ_EMPTY(head)

連結串列是否為空。

#define SIMPLEQ_FIRST(head)

找出首節點。

#define SIMPLEQ_NEXT(elm, field)

找出連結串列中某個元素的下一個元素。

圖形說明

單向連結串列插入說明
上圖為單向連結串列說明
雙向連結串列說明

測試程式碼

#include "queue.h"
#include "types.h"
#include "stdio.h"
struct items_type{
    SIMPLEQ_ENTRY(items_type) field;
    u8 value;//Êý¾ÝÓò£¬´æ´¢Êý¾Ý};

SIMPLEQ_HEAD(head, items_type) list_head;

void List_Init(void)
{
    SIMPLEQ_INIT(&list_head);
}

struct items_type node0 = {.value = 0};
struct items_type node1 = {.value = 1};
struct items_type node2 = {.value = 2};
struct items_type node3 = {.value = 3};
void List_Insert(void)
{
    if (SIMPLEQ_EMPTY(&list_head)) {
            SIMPLEQ_INSERT_HEAD(&list_head, &node0, field); 
            SIMPLEQ_INSERT_HEAD(&list_head, &node1, field);                
            SIMPLEQ_INSERT_HEAD(&list_head, &node2, field);
            SIMPLEQ_INSERT_AFTER(&list_head, &node2, &node3, field);
            /*2310*/
    } else {
            SIMPLEQ_INSERT_TAIL(&list_head, &node0, field);
            SIMPLEQ_INSERT_TAIL(&list_head, &node1, field);
            SIMPLEQ_INSERT_TAIL(&list_head, &node2, field);
    }
}
#if 0
void List_Travel(void)
{
    struct items_type * ptype = NULL;       
    do {
            ptype = SIMPLEQ_FIRST(&list_head);
            if (ptype == NULL) {
                    break;
            } else {
                    printf("%d\r\n", ptype->value);
                    //ÒƳýµÚÒ»¸ö½áµã
                    SIMPLEQ_REMOVE_HEAD(&list_head, field);

            }

    }while(ptype != NULL);

}
#else

void List_Travel(void)
{
    struct items_type  *ptype;
    SIMPLEQ_FOREACH(ptype, &list_head, field) {
            printf("value = %4d,", ptype->value);
    }
    printf("\r\n");

}

#endif

void ListItems_Remove(void)
{
        SIMPLEQ_REMOVE(&list_head, &node1, items_type, field);
}

void ListFirst(void)
{
        struct items_type *type;
        type = SIMPLEQ_FIRST(&list_head);
        printf("%4d\r\n", type->value);

}

void SimpleQueue_Test(void)
{

    List_Init();
    List_Insert();

    List_Travel();
    ListItems_Remove();
    List_Travel();
    ListFirst();

    while(1) {

    }
}