大话数据结构:线性表(2)
生活随笔
收集整理的這篇文章主要介紹了
大话数据结构:线性表(2)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.線性表的鏈式存儲結構
1.1 順序存儲結構不足的解決辦法
線性表的順序存儲結構最大的缺點是插入和刪除時需要移動大量數據,這顯然就需要消耗時間。本節討論的鏈式存儲結構可以很好滴解決這個問題。線性表的鏈式存儲結構的特點是用一組任意的存儲單元存儲線性表的數據元素,這些存儲單元可以使連續的,也可以是不連續的。這就意味著,這些數據元素可以存在內存未被占用的任意位置。 以前的順序結構中,每個數據元素只需要存數據元素的信息就可以了。現在鏈式結構中,除了要存數據元素信息外,還要存儲它的后繼元素的存儲地址。 因此,為了表示每一個數據元素a(i)與其直接后繼數據元素a(i+1)之間的邏輯關系。對數據a(1)來說,除了存儲其本身的信息之外,還需存儲一個指示其直接后繼的信息(即直接后繼的存儲位置)。我們把存儲數據元素信息的域稱為數據域;把存儲直接后繼位置的域稱為指針域。指針域中存儲的信息稱為指針或鏈。這兩部分信息組成元素a(i)的存儲映像,稱為結點。如果每個結點只包含一個指針域,叫做單鏈表。單鏈表正是通過每個節點的指針域將線性表的數據元素按其邏輯次序連接在一起,如圖所示:
對于線性表來說,總要有頭有尾,鏈表也不例外。我們把鏈表中第一個結點的存儲位置叫做頭指針,那么整個鏈表的存取就必須是從頭指針開始進行了。之后的每一個結點,其實就是上一個的后繼指針指向的位置。最后有意義的是討論最后一個結點的指針指向問題,暫時規定,線性鏈表的最后一個結點指針為“空”(NULL)
有時,我們為了更加方便地對鏈表進行操作,會在單鏈表的第一個結點前附設一個結點,稱為頭結點。頭結點的數據域可以不存儲任何信息,頭結點的指針域存儲指向第一個結點的指針,如圖所示:
2.單鏈表操作
2.1 單鏈表的讀取
在線性表的順序存儲結構中,我么要計算任意一個元素的存儲位置時容易的。但是在單鏈表中,由于第i個元素到底在哪?沒辦法一開始就知道,必須從頭開始找。 獲得鏈表第i個數據的算法思路: (1)聲明一個結點p指向鏈表第一個結點,初始化j從1開始; (2)當j<i時,就遍歷鏈表,讓p的指針向后移動,不斷指向下一結點,j累加1; (3)若到鏈表末尾p為空,則說明第i個元素不存在; (4)否則查找成功,返回結點p的數據。 代碼實現如下: Status GetElem( LinkList* L, int i, ElemType* e) {int j;LinkList p; //聲明一節點pp = L->next; //讓p指向鏈表L的第一個節點j = 1;while ( p && j<i) //p不為空 或者計數器j還沒有等于i時,循環繼續{p = p->next; //讓p指向下一個結點++j;}if (!p || j>1i)return ERROR;*e = p->data;return OK; } 說白了,就是從頭開始找,知道第i個元素為止。由于這個算法的時間復雜度取決于i的位置,當i=1時,則不需要遍歷,第一個就取出數據了,而當i = n時,則遍歷n-1次就可以了,因此最壞情況的時間復雜度是O(n)。 由于單鏈表的結構中沒有定義表長,所以不能事先知道要循環多少次,因此也就不方便使用for來控制循環。其主要核心思想就是“工作指針后移”。2.2 單鏈表的元素插入
單鏈表的元素插入用不著驚到其他結點,只需要讓s->next和p->next的指針做一點改變即可。
s->next = p->next; p->next =s; 單鏈表第i個數據插入節點的算法思路: (1)聲明一結點p指向鏈表第一個結點,初始化j從1開始; (2)當j<i時,就遍歷鏈表,讓p的指針向后移動,不斷指向下一結點,j累加1; (3)若到鏈表末尾p為空,則說明第i個元素不存在; (4)否則查找成功,在系統中生成一個空節點s; (5)將數據元素e賦值給s->data; (6)單鏈表的插入標準語句s->next=p->next;p->next = s; (7)返回成功。 實現代碼算法如下: Status ListInsert ( LinkList *L, int i, ElemType e) {int j;LinkList p,s;p = *L;'j = 1;while( p && j<i){p = p->next;++j;}if ( !p || j>1)return ERROR;s = (LinkList)malloc(sizeof(Node));s->data = e;s->next = p->next;p->next = s;return OK; } 2.3 單鏈表的元素刪除 設存儲元素a(i)的結點為q,要實現將節點q刪除單鏈表操作,其實就是將他的前幾結點的指針繞過,指向它的后繼結點即可,如圖所示:
這里需要做的只有一步,p->next = p->next->next,用q來取代p->next,刪除語句可以寫成: q=p->next; p->next = q->next;單鏈表第i個數據刪除節點的算法思路: (1)聲明一個結點p指向鏈表第一個結點,初始化j從1開始; (2)當j小于i時,就遍歷鏈表,讓p的指針向后移動,不斷指向下一個結點,j累加1; (3)若到鏈表末尾p為空,則說明第i個元素不存在; (4)否則查找成功,將預刪除的結點p->next賦值給q; (5)單鏈表的刪除標準語句p->next=q->next; (6)將q結點中的數據賦值給e,作為返回; (7)釋放q結點; (8)返回成功。
實現代碼算法如下: Status ListDelete( LinkList* L, int i, ElemType* e) {int j;LinkList p,q;p = *L;j = 1;while( p->next || j<i ){p = p->next;++j;}if ( !(p->next) || j>i)return ERROR;q=p->next;p->next=q->next;*e = q->data;free(q);return OK; }
總結
以上是生活随笔為你收集整理的大话数据结构:线性表(2)的全部內容,希望文章能夠幫你解決所遇到的問題。