表(list)

來源:互聯網
上載者:User

標籤:

表

表(list)是常見的資料結構。從數學上來說,表是一個有序的元素集合。在C語言的記憶體中,表儲存為分散的節點(node)。每個節點包含有一個元素,以及一個指向下一個(或者上一個)元素的指標。如所示:

表: 橙色儲存資料,藍色儲存指標

圖中的表中有四個節點。第一個節點是前端節點(head node),這個節點不用於儲存元素,只用於標明表的起始。前端節點可以讓我們方便的插入或者刪除表的第一個元素。整個表中包含有三個元素(5, 2, 15)。每個節點都有一個指標,指向下一個節點。最後一個節點的指標為NULL,我們用“接地”來圖示該指標。

表的功能與數組(array)很類似,數組也是有序的元素集合,但數組在記憶體中為一段連續記憶體,而表的每個節點佔據的記憶體可以是離散的。在數組中,我們通過跳過固定的記憶體長度來尋找某個編號的元素。但在表中,我們必須沿著指標聯絡起的長鏈,遍曆查詢元素。此外,數組有固定的大小,表可以根據運行情況插入或者刪除節點,動態更改大小。表插入節點時需要從進程空間的堆中開闢記憶體空間,用以儲存節點。刪除節點可以將節點佔據的記憶體歸還給進程空間。

刪除節點, free釋放記憶體

 

插入節點,malloc開闢記憶體

 

表有多種變種。上面的表中,指標指向是從前向後的,稱為單向鏈表(linked list)。還有雙向鏈表(double-linked list),即每個節點增加一個指向前面一個元素的指標。以及迴圈鏈表(tabular list),最後一個元素的指標並不為NULL,而是指向前端節點。不同類型的鏈表有不同的應用情境。

雙向鏈表

 

迴圈鏈表

 

雙向迴圈鏈表

 

單向鏈表的C實現

一個資料結構的實現有兩方面: 1. 資料結構的記憶體表達方式; 2. 定義在該資料結構上的操作。我們這裡實現最簡單的單向鏈表。表所支援的操作很靈活多樣,我們這裡定義一些最常見的操作。每個操作都寫成一個函數。

/* By Vamei */
#include <stdio.h>#include <stdlib.h>
typedef struct node *LIST;
typedef struct node *position;

/* node,節點 */struct node { int element; position next;};/*
* operations (stereotype)
* 操作
*/
LIST init_list(void);void delete_list(LIST);
int is_null(LIST);
void insert_node(position, int);void delete_node(LIST, position);
position find_last(LIST);position find_value(LIST, int);position find_previous(LIST, position);
void print_list(LIST);
/* for testing purpose */void main(){ LIST L; position np; int i; /* elements to be put into the list */ int a[] = {1, 3, 5, 7, 9}; /* initiate a list */ L = init_list(); print_list(L); /* insert nodes. Insert just after head node */ for (i=4; i>=0; i--) { insert_node(L, a[i]); } print_list(L); /* delete first node with value 5 */ np = find_value(L, 5); delete_node(L, np); print_list(L); /* delete list */ delete_list(L); /* initiate a list */ L = init_list(); print_list(L); /* insert nodes. Insert just after head node */ for (i=4; i>=0; i--) { insert_node(L, a[i]); } print_list(L); /* delete list */ delete_list(L);}/* * Traverse the list and print each element
* 列印表 */void print_list(LIST L){ position np; if(is_null(L)) { printf("Empty List\n\n"); return; } np = L; while(np->next != NULL) { np = np->next; printf("%p: %d \n", np, np->element); } printf("\n");}/* * Initialize a linked list. This list has a head node * head node doesn‘t store valid element value
* 建立表 */LIST init_list(void) { LIST L; L = (position) malloc(sizeof(struct node)); L->next = NULL; return L;}/* * Delete all nodes in a list
* 刪除表 */void delete_list(LIST L){ position np, next; np = L; do { next = np->next; free(np); np = next; } while(next != NULL); }/* * if a list only has head node, then the list is null.
* 判斷表是否為空白 */int is_null(LIST L) { return ((L->next)==NULL);}/* * insert a node after position np
* 在np節點之後,插入節點 */void insert_node(position np, int value) { position nodeAddr; nodeAddr = (position) malloc(sizeof(struct node)); nodeAddr->element = value; nodeAddr->next = np->next; np->next = nodeAddr; }/* * delete node at position np
* 刪除np節點 */void delete_node(LIST L, position np){ position previous, next; next = np->next; previous = find_previous(L, np); if(previous != NULL) { previous->next = next; free(np); } else { printf("Error: np not in the list"); }}/*
 * find the last node of the list
* 尋找表的最後一個節點
 */position find_last(LIST L){ position np; np = L; while(np->next != NULL) { np = np->next; } return np;}/* * This function serves for 2 purposes: * 1. find previous node * 2. return NULL if the position isn‘t in the list
* 尋找npTarget節點前面的節點 */position find_previous(LIST L, position npTarget){ position np; np = L; while (np->next != NULL) { if (np->next == npTarget) return np; np = np->next; } return NULL;}/* * find the first node with specific value
* 查詢 */position find_value(LIST L, int value) { position np; np = L; while (np->next != NULL) { np = np->next; if (np->element == value) return np; } return NULL;}

 

在main()函數中,我們初始化表,然後插入(1, 3, 5, 7, 9)。又刪除元素5。可以看到,節點零散的分布在記憶體中。刪除節點操作不會影響其他節點的儲存位置。

我們隨後刪除表,又重新建立表。可以看到,這次表佔據記憶體的位置與第一次不同。

 

下面是main()函數的運行結果。

Empty List

0x154d0b0: 1 
0x154d090: 3 
0x154d070: 5 
0x154d050: 7 
0x154d030: 9 

0x154d0b0: 1 
0x154d090: 3 
0x154d050: 7 
0x154d030: 9 

Empty List

0x154d070: 1 
0x154d010: 3 
0x154d0b0: 5 
0x154d090: 7 
0x154d050: 9

 

總結

表: 記憶體中離散分布的有序節點

插入,刪除節點

表(list)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.