1. 程式人生 > >C中的資料結構

C中的資料結構

資料結構

主要內容:在linux下的主要資料結構。 linux核心我的理解來說,很大一部分的工作都是在管理各種資料,用到的資料結構也有很多,大致有線性表,佇列,二叉樹,以及連結串列,當然在實現上都可以看作是連結串列的變換,我在原來的學習中對資料結構缺失很多,現在重新學習這一部分,在這裡記錄下我的學習感受。

佇列結構

首先佇列的特點是先進先出。這個是判斷的標準,先進後出就變成了棧,而在程式實現時則都可以用連結串列來實現。所用的也都是結構體和指標。所以說,指標真的是C的精華啊。

typedef struct QNode
{
    struct gate_msg *data;//資料域
    struct QNode *next;   //指標域
}QNode,*QueuePtr;
 

typedef struct{     
        QueuePtr head;//頭指標
        QueuePtr rear;//尾指標
	pthread_mutex_t q_mutex;
	int count;
}LinkQueue;

這裡就是定義一個佇列使所使用的,第一個有指標域和資料域,其中資料域用來存放這個資料結構中的資料,指標域這就是指向佇列中下一個,這裡就不完全說明佇列結構的全部操作,用插入操作來簡要說下自己的理解。

int Queue_Push(LinkQueue* que,struct gate_msg *e)
{
    QueuePtr qptr = (QueuePtr)malloc(sizeof(QNode));
    if(!qptr)
        return ERROR;
	
   pthread_mutex_lock(&que->q_mutex);//互斥鎖
    qptr->data=e;
    qptr->next=NULL;

    que->rear->next = qptr;
    que->rear=qptr;
	que->count++;
	LOGD("push:  queue node:%p, gate_msg: %p, count:%d\n", qptr, e, que->count);
	pthread_mutex_unlock(&que->q_mutex);
    return OK;
}

首先是加鎖的操作,這個我一開始並不注意,最後發現,資料操作是這個還是挺重要的,在此感謝下沈老師啊,加鎖就主要為了在本次操作中訪問佇列只有現在一個使用者,防止資料出錯。其次在資料插入時,就是在一條線中插入一個,可以看做是將插入地方原本的資料塊向後一個,將這個放在裡面,連上前面的資料塊,連上後面的資料塊,由於佇列可以看做是單向連結串列實現,那麼就和單向連結串列一樣,只有向後的指標指向下一個,那麼就需要讓前指標的指向這個,然後數目記錄的count加一,最後關閉鎖,有始有終嘛。 佇列結構主要就是這樣,在資料不是很多的專案中會用的很多,維護一條線的資料,來一個在佇列後加一,然後可以先進先出的處理,在邏輯接收發送時很有用。

接下來就是連結串列了

連結串列很無敵,這個是我老師給我說的,也確實這樣,如果指標是C的精華,是一個一個的釘子,那麼連結串列就是把這些釘子連起來的絲線。連結串列可以寫單向連結串列和雙向連結串列,連結串列可以化成其他的任何資料結構。雙向連結串列如果減少一個指標域,就是單鏈表,如果只能對連結串列的首尾進行插入和刪除就是佇列,而如果只能對連結串列的頭進行插入和刪除,就是棧。而在linux核心原始碼中,也是雙向連結串列居多。

typedef struct node  
{  
    int data;                //    節點中的成員  
    struct node *head;        //    指向下一個節點的指標  
}Node,*pNode;  

這個是單向連結串列,只有向下一個的指標。

typedef struct node {
    int data;
    DNode prev; //前面資料地址
    DNode next;  //後面資料地址
}node* DNode;

這就是個雙向連結串列,有指向前後的指標。

同樣的,用一個雙向連結串列的插入來說明下連結串列操作。

//向雙向連結串列中插入節點
int InsertEleDbLinkList(pNODE pHead, int pos, int data)
{
    pNODE pt = NULL, new = NULL;

    if (pos > 0 && pos < GetLengthDbLinkList(pHead)+2)
    {
        new = (pNODE)malloc(sizeof(NODE));

        if (NULL == p_new)
        {
            printf("記憶體分配失敗!\n");
            exit(EXIT_FAILURE);
        }
      new->prev=new;
      new->next=next;
      head->prev=prev;
      prev->next=new;    
}
}

程式碼中說明的很清楚,插入節點new,head是前節點,在new節點的資料域定義資料,將新節點的前節點連到上節點head,新節點的next連到下一個節點,頭結點的next到new,就是每個節點都有頭指標和後指標,將頭指標指向上一個,後指標到下一個。

linux中的連結串列

linux中的資料結構很多都是連結串列完成的,比如檔案系統下很多的資料都是,現在就不在說明了,放在下一次。