標籤

2013年8月16日 星期五

link-list 資料插尾插頭

// insert val in head of a link list
void insert_in_head(int val)
{
   // create a node for val
   node *data = (node *) malloc(sizeof(node));
   data->val = val;
   // link head next to data
   data->next = head;
   // new head = data
   head = data;
}
node *tail = NULL;
// insert val in tail of a link list
void insert_in_tail(int val)
{
   // create a node for val
   node *data = (node *) malloc(sizeof(node));
   data->val = val;
   // link NULL to data
   data->next = NULL;

   // if there is no existing node
   if (head == NULL)
      // then this node is head and also tail
      head = tail = data;
   else {
      // otherwise, this node is new tail
      tail->next = data;
      tail = data;
   }
}
資料的插頭,就是把一筆資料直接放入到link list的頭端,如果沒有資料那麼這筆資料就會是新的頭。如果有資料的話那麼目前的頭就會被接在這筆新資料之後。
   data->next = head;
   // new head = data
   head = data;
在create一個node之後我們便把目前的頭接在這筆新資料之後,然後新的頭就會是這筆新資料。在此,即使是沒有任何資料的狀態也不會有問題,因為沒有任何資料的狀況之下,我們早在一開始便把head initialize成為NULL了,因此這時候這筆新資料往後接的,便會是NULL,這也是正常該有的狀況。

而資料的插尾,就是把這筆資料直接放到最尾端。我們可以直接一個一個從頭去search next指標直到尾端去找尾端然後把這筆資料往後接上,但這太耗費工夫,尤其如果是巨量資料之下的話會更明顯。因此我們直接create一個指標tail,指向這個list的最後一個node,我們一開始initialize為NULL:
node *tail = NULL;
接著這個程式create memory並放入資料給這筆新資料之後,首先就將這筆新資料的尾端接為NULL:
   data->next = NULL;
然後我們先判定目前是不是現有資料,原因在於如果不管三七二十一不判定有沒有資料而直接把tail往後接給這筆資料的話,會有問題,因為我們並沒有配給tail一個記憶體空間,所以它的next是不存在的,因為即使是指標,還是需要記憶體空間的。所以如果沒有任何資料在list之內,我們直接把tail和head assign給這筆新資料:
   if (head == NULL)
      // then this node is head and also tail
      head = tail = data;
當然我們也可以用tail == NULL來判斷也是一樣的結果。邏輯上來講,如果沒有任何資料存在,那麼這筆新資料就會是這個link list的頭兼尾,這邊程式的邏輯就會把這段話給烙印上去。

接著如果現有資料的話,我們就把tail往後接這筆資料,接著才把tail assign給這筆資料,這邊順序要對,如果我們先把tail assign給這筆新資料在把tail往後接給這筆資料的話,結果會是這筆資料是孤立的,沒有任何資料接它,並且它的next會是接它自己。
      tail->next = data;
      tail = data;
於是接頭接尾便能夠很簡單的用幾行就可以完成。

沒有留言:

張貼留言