1. 程式人生 > >靜態連結串列詳解及程式碼實現

靜態連結串列詳解及程式碼實現

所謂靜態連結串列,就是用陣列來實現鏈式儲存結構,目的是方便在不設指標型別的高階程式設計語言中使用鏈式結構。

優點:和動態連結串列一樣,刪除和插入元素時間複雜度低

不足:和陣列一樣,需要提前分配一塊較大的空間、

實現原理:

1、使用結構體陣列,結構體有指標域  cur  和資料域  data

2、一個數組分量表示一個節點,用cur代替指標指示節點在陣列中的相對位置

3、陣列邏輯上分為兩個連結串列:備用連結串列(空閒的節點)和資料鏈表(已被使用的節點)

靜態連結串列的理解重點在於:

1、如何實現兩條鏈,兩條鏈之前有什麼聯絡 

2、插入刪除時陣列的變化 

3、cur域是如何代替指標工作的

(修正:下標為1的結點為資料鏈頭結點,資料域應為空)

由圖1可以看出,初始化就是使整個陣列所有分量都包含在備用連結串列中

由圖1、2可以看出,靜態連結串列的插入就是  把節點 x 從備用連結串列中刪除,然後將節點 x 插入資料鏈中

由圖4、5可以看出,靜態連結串列的刪除就是  把節點 x 從資料鏈中刪除,然後將節點 x 插入備用連結串列中

先定義結構體:

#include<stdio.h>
#define maxsize 30

typedef char elemtype;
typedef struct{
	int cur;
	elemtype data;
}slink,slinklist[maxsize];

定義初始化函式(對應圖1):

void initspace_sl(slink *space)
{//將資料各分量連結成一個備用連結串列,space[0]代表頭指標
	int i;
	for(i=0;i<maxsize-1;i++)
	{
		space[i].cur=i+1;
	}//下標為i結點的後繼為下標是i+1的結點
	space[maxsize-1].cur=0;//0表示空指標
} 

使用者需要自己實現malloc函式和free函式

實現過程如下:

int malloc_sl(slink *space)
{//若備用連結串列非空,則返回分配節點下標,否則返回0。
	int i;
	i=space[0].cur;
	if(space[0].cur)
	{	
            space[0].cur=space[i].cur;//使頭結點後繼等於I結點的後繼
	}//既在備用連結串列中刪除i節
        return i;

}
int free_sl(slink *space,int k)
{//將下標為k的空閒節點回收到備用連結串列中
	space[k].cur=space[0].cur;
	space[0].cur=k;
}

以集合(A-B)∪(B-A)運算為例:

思想:假設由終端輸入資料,先建立表示集合A的靜態連結串列S,然後在輸入集合B元素的同時對靜態連結串列S進行查詢,如果存在相同的元素則從S表中刪除,否則將此元素插入表S中。

當集合A為{A,B,C},集合B為{D,E,A,}

程式碼如下:

int difference_sl(slink *space,int *k)
{
	int q,w,r,t,y,u,a;
	elemtype ch;
	initspace_sl(space);
	*k=malloc_sl(space);//k表示返回的頭結點
	q=*k;//q指向最後一個結點
	scanf("%d%d",&w,&r);//輸入A、B的大小
	for(int i=1;i<=w;i++)//將集合A中的資料依次插入靜態連結串列中
	{
		t=malloc_sl(space);
		scanf("%c",&space[t].data);
		space[q].cur=t;
		q=t;
	}
	space[q].cur=0;//最後一個結點的後繼為空指標
	for(int j=1;j<=r;j++)//讀取B集合的元素
	{
		scanf("%c",&ch);
		y=*k;//y指向頭結點
		u=y;
		while(space[y].data!=ch&&y!=space[q].cur)
		{//查詢ch
			u=y;//u指向上一結點
			y=space[y].cur;
		}
		if(y==space[q].cur)//未找到,做插入操作
		{
			a=malloc_sl(space);
			space[a].data=ch;
			space[a].cur=space[q].cur;
			space[q].cur=a;
			q=a;
		}
		else//找到,做刪除操作
		{
			space[u].cur=space[y].cur;
			free_sl(space,y);
			if(y==q){
				q=u;
			}
			
		}
	}
	
}

main函式:

int main()
{
	slinklist space;
	int x,y;
	difference_sl(space,&x);
	y=x;
	while(y)
	{//遍歷靜態連結串列
		printf("%3d  %c\n",y,space[y].data);
		y=space[y].cur;
	}
} 

上學期剛學完資料結構,剛好趁著暑假總結完,本著網際網路人分享的原則,將個人理解與感悟供大家參考,希望對大家有所幫助,由於水平有限,如有不足之處歡迎指正。