實戰資料結構(6)_靜態連結串列的使用

YunShell發表於2013-08-25

         前幾節介紹的動態連結串列都是用C中堆記憶體的開闢方法,用函式mallocfree來開闢和釋放節點,但是在某些語言中沒有指標的型別,如何做呢?可以用陣列來模擬動態連結串列的建立過程。 

/************************************************************************/
/* @author lynnbest
目標:靜態連結串列的使用  插入和刪除
 1.建立一個靜態迴圈連結串列 {A,B,C,D,E,F}
 2.插入操作
 3.刪除操作
 4.列印操作                                                     */
/************************************************************************/
/************************************************************************/
/* 思路:
用陣列來模擬動態連結串列的建立過程
1.插入
	①先獲取備份空閒節點 L.av 同時更新新節點資料和av
	②遍歷獲取位置 得到前驅節點
	③插入
                                                                     */
/************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define size 10
typedef struct //節點結構體
{
	char data;	//資料域
	int cur;	//遊標指標
}slistnode;

typedef struct 
{
   slistnode list[size];	//陣列個數
   int av;	//備份遊標指標
}slinklist;

void InitSlinklist(slinklist *L);
void InsertSlistNode(slinklist *L,int pos,char ch);
void DeleteSlistNode(slinklist *L,int pos);
void PrintfSlist(slinklist L);
int length(slinklist L);

void main()
{	
	printf("   靜態連結串列的使用	\n");
	printf("----by lynnbest ----\n\n");
	//初始化連結串列 
	slinklist L;
	InitSlinklist(&L);	//初始化靜態連結串列,m.
	int choice,pos;
	char ch;
	while(1)
	{
		printf("1---建立靜態連結串列\n");
		printf("2---插入節點\n");
		printf("3---刪除節點表\n");
		printf("4---列印當前元素\n");
		printf("5---退出\n請選擇:\n");
		scanf("%d",&choice);
		switch(choice)
		{
			case 1:
				{	
					char a[]={'A','B','C','D','E'};
					int len=sizeof(a)/sizeof(a[0]);
					for(int j=1;j<=len;j++)
						InsertSlistNode(&L,j,a[j-1]);
					break;
				}
			case 2:
				{	
					printf("請輸入要插入的元素位置和字元:\n");
					scanf("%d,%c",&pos,&ch);
				//	printf("請輸入要插入的位置:\n");
				//	scanf("%d",&pos);
					InsertSlistNode(&L,pos,ch);
					break;
				}
			case 3:
				{	printf("請輸入要刪除元素的位置:\n");
					scanf("%d",&pos);
					DeleteSlistNode(&L,pos);
					break;
				}
			case 4:
				{	printf("靜態連結串列中的元素為:\n");
					PrintfSlist(L); 
					break;
				}
			case 5:
				{
					return;
				}
			default :
				break;
		}
	}
	
}

void InitSlinklist(slinklist *L)
{	
	memset(L,NULL,sizeof(*L));
	for(int i=0;i<size;i++)	//初始化cur i是陣列編號
	{
		(*L).list[i].cur=i+1;
	}
	(*L).list[size-1].cur=0;	//做迴圈
	(*L).av=1;	//分配空閒節點
}

void InsertSlistNode(slinklist *L,int pos,char ch)
{	
	if(pos<1||pos>size-1)
	{
		printf("插入位置非法\n");
		return ;
	}
	int able=(*L).av;	//獲取空閒節點
	(*L).list[able].data=ch;  //插入新資料
	(*L).av=(*L).list[able].cur; //更新空閒節點
	//int start=(*L).list[0].cur; //開始位置 
	int start=0;
	for(int i=0;i<pos-1;i++)
		start=(*L).list[start].cur;
	//遍歷完後,查詢到  start為前驅編號
	(*L).list[able].cur=(*L).list[start].cur; //先修改able的指標
	(*L).list[start].cur=able;	//在修改前驅編號的指標
}


void DeleteSlistNode(slinklist *L,int pos)
{
	if(pos<1||pos>size-1)
	{
		printf("刪除位置非法\n");
		return ;
	}
//	int pre=(*L).list[0].cur;
	int  pre=0;
	for(int x=0;x<pos-1;x++)
		pre=(*L).list[pre].cur;	//查詢刪除節點的前驅編號
	int next=(*L).list[pre].cur;  //獲取下一個遊標
	(*L).list[pre].cur=(*L).list[next].cur; //刪除操作結束
	(*L).list[next].cur=(*L).av;
	(*L).av=next;	
}
void PrintfSlist(slinklist L)
{	
	int start=L.list[0].cur;
	for(int i=1;i<=length(L);i++)
	{
		printf("%3c",L.list[start].data);
		start=L.list[start].cur;
	}
	printf("\n");
}

int length(slinklist L)
{	
	int p=L.list[0].cur;
	int count=0;
	while( L.list[p].cur!=1)//還不完善
	{	p=L.list[p].cur;
		count++;
	}
	return count+1;
}

相關文章