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中的資料結構很多都是連結串列完成的,比如檔案系統下很多的資料都是,現在就不在說明了,放在下一次。