1.基本結構
連結清單的一般定義是n個節點通過指針互相連接配接形成連結清單。靜态連結清單是借由一維數組對于線性連結清單進行描述,靜态連結清單的資料域仍然記作變量data,不同于一般的線性連結清單,其“指針”用一個int 類型的變量cur來表示,而不是傳回類型為Node的指針next。靜态連結清單單個元素的類型名稱記作component,類似地,指針域用一個Slinklist數組來表示,通路位序為i的元素的指針需要定義slinklist類型的對象space,通過space[i].cur完成對指針的指派。靜态連結清單的基本結構代碼如下:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct
{
int data;
int cur;
}component,slinklist[1000];
靜态連結清單中的元素位序下标與元素指針需要分别看待,定義一個slinklist型的變量記作space,space[i].cur訓示了第i個元素在靜态連結清單中的位置,而假設int 型變量j=space[i].cur,則s[j].data存儲了線性表的第i位元素的資料。根據以上的性質,可以實作在靜态連結清單中的定位函數,基本思路如下: 1)定義變量i,初始化為靜态連結清單中第0個元素的位置 2)通過while循環,利用判斷條件,當space[i]的資料域不為e時,将i指派為space[i].cur ,即通過變量cur的值,通路位序為i的元素的後繼結點 3)循環直到資料域等于e為止 代碼如下:
int locate(slinklist space,int e)
{
int i=space[0].cur;
while(i&&space[i].data!=e)
{
i=space[i].cur;
}
return i;
}
2.靜态連結清單的連結清單初始化函數以及結點初始化函數
實作了靜态連結清單的定位函數後,可以實作靜态連結清單的插入以及删除算法,靜态連結清單的插入以及删除操作不需要移動元素,隻需要修改指針域的值即可完成元素的移動。插入操作需要自行定義兩個函數,包括靜态連結清單的連結清單初始化函數Init(Slinklist space),以及靜态連結清單節點的初始化函數malloc(Slinklist space).靜态連結清單的連結清單初始化函數主要思路如下:1)建立一個Slinklist類型的數組space,用于表示結點的資料域以及指針域 2)通過for循環,初始化space數組的指針域,space[0]的指針域記作1,即靜态連結清單space的位序為1的元素後繼是位序為2的元素,以此類推,直到space[max-1]的指針域為0,即靜态連結清單space的最後一個元素的後繼元素是靜态連結清單的位序為1的元素,達成了一個連結清單的循環,代碼如下:
void Init(slinklist space)
{
for(int i=0;i<max-1;i++)
{
space[i].cur=i+1;
}
space[max-1].cur=0;
}
靜态連結清單節點的初始化函數主要思路如下:1)定義一個變量i作為位序為1的元素的後繼,語句為:int i=space[0].cur 2)進行條件的判斷,如果此時位序為1的元素後繼位序不為0時(後繼為0表示位序為1的元素後繼與表尾元素相同,同時意味着連結清單已滿) space[0].cur=space[i].cur;相當于是有結點插入在位序為1的元素之前,同時該結點的位序由位序為1的元素獲得。在應用之中,由于space[0].cur初始化為1,是以i一般由1開始變化。每插入一個新節點,space[0].cur的值會更新。在靜态連結清單的插入操作中,該函數用于獲得靜态連結清單邏輯位序為2的結點的實體位序。代碼以及示意圖如下:
int malloc(slinklist space)
{
int i=space[0].cur;
if(space[0].cur)
{
space[0].cur=space[i].cur;
}
return i;
}
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX61kaOJTUE9ENNpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TMwEjM0cTMwADOycDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
靜态連結清單初始化
靜态連結清單中位序為2的結點初始化
3.靜态連結清單的插入函數
靜态連結清單的初始化插入操作函數基本思路如下:1)假定函數的參數為space數組,要求在靜态連結清單的第m+1位之前插入(位序為m+1,同時m由0開始增加至Max-1) ,待插入的結點資料值為e 2)定義變量j,k,l 變量j初始化為位序為1的結點的後繼結點(j=malloc(space)),變量k初始化為max-1,用于在for循環中尋找第m+1個結點的位序(k=space[max-1].cur,初始值為1,經過m-1次循環可以找到結點位置) 3)将新插入的結點的後繼結點設定為與此時的第m個結點相同,第m個結點的後繼設定為新插入的結點j(此處與單連結清單插入節點的方法相同)。代碼如下:
void Insert(slinklist space,int e,int m)
{
int k=max-1;
int j=malloc(space);
space[j].data=e;
for(int i=1;i<=m-1;i++)
{
k=space[k].cur;
}
space[j].cur=space[k].cur;
space[k].cur=j;
}
4.靜态連結清單的周遊操作
靜态連結清單的周遊函數主要的思路為:1)在插入了n個結點後,定義一個變量為k,k初始化為space[max-1].cur,即初始化為實體位序最大的結點的後繼 2)進行while循環,當結點i的後繼不為0(後繼為0意味着結束連結清單的輸出,位序為0的結點資料值為空且其後繼的所有節點資料值均為空),輸出實體位序為i的結點的數值以及使i通路其邏輯位序的後繼。
void travel(slinklist space)
{
int i=space[max-1].cur;
while(space[i].cur!=0)
{
cout<<i<<" "<<space[i].data<<" "<<space[i].cur<<endl;
i=space[i].cur;
}
}
靜态連結清單初始化
靜态連結清單完成元素插入示意圖
靜态連結清單插入元素,周遊元素的主程式代碼如下:
int main()
{
slinklist space;
Init(space);
int m;
cin>>m;
int num[m];
for(int i=0;i<m;i++)
{
cin>>num[i];
}
for(int k=0;k<=m;k++)
{
Insert(space,num[k],k+1);
}
travel(space);
return 0;
}
5.靜态連結清單的釋放空間操作以及删除結點
靜态連結清單的删除操作,與靜态連結清單的插入操作類似的,僅僅隻需通過修改指針域來完成元素的“删除”,在定義删除操作前,前行定義釋放邏輯位序為k+1的結點的函數free(slinklist space,k),釋放結點空間的操作等同于将邏輯位序為k+1的結點的後繼設定為實體位序為1的元素的後繼,再将實體位序為1的元素後繼設定為這個釋放的結點,相當于将該節點連結入一個無用的連結清單之中(屬于實體位序為1的結點的後繼,無法被通路到)。具體代碼如下:
int free(slinklist space,int k)
{
space[k].cur=space[0].cur;
space[0].cur=k;
}
類比單連結清單的形式,在定義完成free函數後,進行删除操作的基本思路如下:1)定義變量i,表示删除邏輯位序為i的元素 2)定義變量k,m,l 。變量k用于通路邏輯位序為i-1,i,i+1的元素,先通過for循環通路邏輯位序為i-1的元素,用變量m存儲其實體位序,此處用 m=space[k].cur語句進行表示 3)進行兩次通路後繼節點操作後,用變量l存儲該節點的實體位序 4)将m的後繼結點值賦為l,就達到了删除結點k的目的 4)釋放此時位序為k的結點的空間(在通路位序為i-1的元素後進行的第一次通路後繼結點語句将k的值賦成i,此處的i與k是等價的) 5) 定義int類型變量e,使用e傳回删除的元素值 。代碼如下所示:
void Delete(slinklist space,int i)
{
int k=max-1;
int l,m;
for(int j=0;j<=i-2;j++)
{
k=space[k].cur;
}
m=k;
k=space[m].cur;
l=space[k].cur;
space[m].cur=l;
int e=space[k].data;
cout<<e<<endl;
free(space,k);
}