1. 程式人生 > >靜態連結串列的原理及實現

靜態連結串列的原理及實現

靜態連結串列是一種使用陣列模擬連結串列的方法,在某些不支援指標的語言中,可以用它來模擬連結串列。

靜態連結串列使用一個數組,但是該陣列通過下標指向連成兩個“連結串列”,一個用來儲存尚未存放資料的節點,另一個儲存已經存放資料的節點。

靜態連結串列的資料結構如下:

#define MAXSIZE 1000
typedef struct
{
	int data;
	int cur;
}List,Linklist[MAXSIZE];

結構體陣列Linklist中data為資料(假定為int型),cur為下一個元素的下標(類似於連結串列中的指向下一個節點的指標)。MAXSIZE為最大可以儲存的資料元素個數。

靜態連結串列的邏輯形式如下:


該圖為一個靜態連結串列的初始狀態。

初始狀態下每一個節點的cur為下一個節點的下標。最後一個節點暫時存放0號節點的下標。

實現:

void init(Linklist s)
{
	int i;
	for(i=0;i<MAXSIZE-1;i++)
		s[i].cur=i+1;
	s[i].cur=0;
}


上圖為靜態連結串列使用的某個狀態。

前面說過靜態連結串列實際上維持兩個連結串列。存放元素的連結串列首節點由MAXSIZE-1獲得(s[MAXSIZE-1].cur),最後一個節點因為指向0號節點,也可獲得。而空連結串列首節點為0號節點,通過首節點即可找到下一個可用的空節點

插入節點時,從0號節點開始查詢可用的節點,若存在可用節點,則加入,並修改一些節點的指向。

為了方便起見,將插入分為兩個部分:插入首節點,插入其他節點。

插入首節點:

//插入第一個節點時,需要將s[MAXSIZE-1]指向首節點
void insertFirst(Linklist s,int data)
{
	s[MAXSIZE-1].cur=1;
	s[1].data=data;
	s[1].cur=0;
	s[0].cur=2;
	return ;
}
插入其他節點:
int insert(Linklist s,int pos,int data)//連結串列,插入位置,資料
{
	if(pos>getLength(s)+1||pos<=0)
	{
		printf("wrong insert position!\n");
		return -1;
	}
	int i,j,n;
	i=getSpacePos(s);
	s[i].data=data;
	n=MAXSIZE-1;
	for(j=1;j<pos;j++)
		n=s[n].cur;
	s[i].cur=s[n].cur;
	s[n].cur=i;
	return 0;
}

其中,getLength(s)獲取存放資料鏈表的長度,getSpacePos(s)獲取下一個可用的節點位置。

int getLength(Linklist s)
{
	int count,n;
	count=0;
	n=MAXSIZE-1;
	while(s[n].cur!=0)
	{
		count++;
		n=s[n].cur;
	}
	return count;
}
int getSpacePos(Linklist s)
{
	int i=s[0].cur;//s[0]指向下一個可用的節點位置
	if(i)
	{
		s[0].cur=s[i].cur;//使得s[0]繼續指向下一個可用的節點位置
	}
	return i;
}
刪除節點同理:找到節點位置,刪除,修改指向。
int deletePos(Linklist s,int pos)
{
	if(pos>getLength(s)+1||pos<=0)
	{
		printf("wrong delete position!\n");
		return -1;
	}
	int n=MAXSIZE-1;
	while(s[n].cur!=0)
	{
		if(s[n].cur==pos)
		{
			if(s[s[n].cur].cur==0)
				s[n].cur=0;
			else
				s[n].cur=s[s[n].cur].cur;
			release(s,pos);
			break;
		}		
		n=s[n].cur;
	}
	return 0;
}
其中realease(s,pos)用來維護空連結串列,修改空連結串列指向。
//釋放節點,將該節點放在0號節點後面
void release(Linklist s,int pos)
{
	s[pos].cur=s[0].cur;
	s[0].cur=pos;
}
遍歷存放資料的連結串列:
void print(Linklist s)
{
	printf("pos\tdata\tnext\n");
	int i=s[MAXSIZE-1].cur;
	while(s[i].cur!=0)
	{
		printf("%d\t%d\t%d\n",i,s[i].data,s[i].cur);
		i=s[i].cur;
	}
	printf("%d\t%d\t%d\n",i,s[i].data,s[i].cur);
	return ;
}
完整的demo下載:靜態連結串列