一、静态链表图文解析
二、静态链表代码解析
- 1、基本 *** 作
- 1.1 结构
- 1.2 初始化
- 1.3 插入数据
- 1.4 删除数据
- 1.5 修改数据
- 2、源代码及测试
- 2.1 源代码
- 2.2 测试结果
一、静态链表图文解析
静态链表结构
静态链表的结构实际上就是一个数组,静态链表的数组中,每一个元素代表一个结点,结点同样和链表一样包括数据域和指针域
只是在静态链表中的指针域不再是指针指向下一个结点的地址,而是用于存储下一个结点的数组下标,这样同样可以实现结点之间的连接关系
图示
在静态链表中
- 指针域大于0,则代表下一个结点的数组下标
- 指针域等于-1,则代表下一个结点为空
- 指针域等于-2,则代表该结点尚未被使用
二、静态链表代码解析 1、基本 *** 作 1.1 结构
#define MaxSize 10 //最大链表长度
typedef char DataType;
typedef struct LNode
{
DataType data; //数据域
int next; //指针域
}StaticList;
1.2 初始化
void InitList(StaticList **L)
{
// 为静态链表分配空间
(*L) = (StaticList *)malloc(MaxSize * sizeof(StaticList));
// 初始化头结点
StaticList *s = *L;
s[0].data = ';'[
s0].=next - 1;// 初始化链表
int
; ifor
( =i 1 ;< i ; MaxSize++ i)[
{
s]i.=data ';' []
s.i=-next 2 ;}printf
(
"已初始化链表\n");}头部插入
void
1.3 插入数据
HeadInsert
( *)StaticList ifL(
{
) ;Lprintf
{
DataType x(
"请输入插入的数据:");fflush(
stdin);scanf(
"%c",&) ;x// 获取新结点的下标位置int
=
GetFreeNodeIndex free_node ( );Lif(
0 )free_node > // 设置新结点的数据[
{
]
L.free_node=;data // 新结点指向链表的第一个结点 x[
]
L.free_node=[next 0 L].;// 头结点指向新结点,使得新结点成为链表的第一个结点next[
0
L].=;next printf free_node(
"插入成功!\n");}else
printf
(
{
"插入失败! 链表空间已满!\n");}}
else
printf
(
{
"插入失败! 链表已销毁!\n");}}
尾部插入
void
TailInsert
( *)StaticList ifL(
{
) intL;
{
; iprintf
DataType x(
"请输入插入的数据:");fflush(
stdin);scanf(
"%c",&) ;xint=
GetFreeNodeIndex free_node ( );Lif(
0 )free_node > int=
{
0 tail_index ; // 查找尾结点下标while
(
[ ]L.tail_index0)next > =[
{
tail_index ] L.tail_index;}next// 设置新结点数据
[
]
L.free_node=;data // 新结点指针域设置为空 x[
]
L.free_node=-next 1 ;//尾结点指向新结点,使得新结点成为链表的最后一个结点[
]
L.tail_index=;next printf free_node(
"插入成功!\n");}else
printf
(
{
"插入失败! 链表空间已满\n");}}
else
printf
(
{
"插入失败! 链表已销毁!\n");}}
按位置插入
void
LocateInsert
( *)StaticList ifL(
{
) intL,
{
; i; kprintf
DataType x(
"请输入插入的数据和插入位置:");scanf(
"%d %c",&, &k) ;xint=
GetFreeNodeIndex free_node ( );Lif(
0 &&k > 0 ) free_node > int=
{
0 insert_index ; // 查找链表中第(k-1)个结点while
(
(--)&&k[ ] L.insert_index0)next > =[
{
insert_index ] L.insert_index;}next// 插入新结点
if
(
== 0k ) // 设置新结点数据[
{
]
L.free_node=;data // 新结点指向第k个结点下标 x[
]
L.free_node=[next ] L.insert_index;// 第(k-1)个结点指向新结点next[
]
L.insert_index=;next printf free_node(
"插入成功!\n");}else
printf
(
{
"插入失败! 插入位置不合法!\n");}}
else
printf
(
{
"插入失败! 插入位置不合法/链表空间已满!\n");}}
else
printf
(
{
"插入失败! 链表已销毁!\n");}}
头部删除
void
1.4 删除数据
HeadDelete
( *)StaticList ifL(
{
) ifL(
{
[ 0L].0)next > int;
{
// 获取第一个结点 first_index=
[
first_index 0 L].;// 头结点指向第二个结点next[
0
L].=[next ] L.first_index;// 初始化第一个结点next[
]
L.first_index=';'data [ ].
L=first_index-2next ; printf("删除成功!\n"
);}elseprintf
(
"删除失败! 链表为空!\n"
{
);}}else
printf
(
"删除失败! 链表已销毁!\n"
{
);}}尾部删除
// 尾部删除
void
TailDelete
(
* )ifStaticList (L)
{
if (L[
{
0 ]L.0)intnext > =0
{
, i = 0; j // 查询倒数第一个结点(i)和倒数第二个结点(j) while(
[
] .L0i)=next > ;=
{
j [ i]
i . L;i}// 倒数第二个结点指向-1next[
]
.
L=j-1next ; // 初始化最后一个结点[]
.
L=i';'[data ] .=
L-i2;next printf ("删除成功!\n")
;}elseprintf(
"插入失败! 链表为空!\n"
)
{
;}}elseprintf
(
"插入失败! 链表已销毁!\n"
)
{
;}}按位置删除// 按位置删除
void
LocateDelete
(
*
) if(StaticList )Lint
{
; printfL(
{
"请输入删除的数据位置:" k)
;scanf("%d",
&);if (k0&&
[ 0k > ] . L0)int=next > 0,
{
= i 0 ;// 查询第(j = k-1)个结点和第(i = k)个结点 j while ((
--
) &&[k]. 0 L)i=;next > =[
{
j ] i.
i ; L}iif(next<
0
) // 第(k-1)个结点指向第(k+1)个结点k [ ].
{
=
L[j].next ; L// 初始化第k个结点i[]next.
=
L';'i[]data . =-
L2i;printfnext ( "删除成功!\n");
}elseprintf("删除失败! 删除位置不合法!\n"
)
;
{
}}elseprintf(
"删除失败! 链表为空!\n"
)
;
{
}}elseprintf(
"删除失败! 链表已销毁!\n"
)
;
{
}}// 修改链表voidListModify
(
*
1.5 修改数据
)
if ()StaticList intL;
{
; printfL(
{
"请输入需要修改的位置和修改后的数据:" k)
DataType x;
scanf("%d %c",&
,&); ifk( 0x)int
= 0k > ;// 查询第i个结点位置
{
while index ( (--
)
&& []k.0 ) L=index[]next > .;
{
index } Lifindex(<next0
)
[ ]k . =;
{
Lprintfindex("修改成功!\n"data ) x;
}elseprintf("修改失败! 修改位置不合法!\n"
)
;
{
}}elseprintf(
"修改失败! 修改位置不合法!\n"
)
;
{
}}elseprintf(
"链表已销毁!\n"
)
;
{
}}#include#
include
#
2、源代码及测试
2.1 源代码
defineMaxSize
10typedef
char; typedef struct
LNode ; DataTypeint
; } ;
{
DataType datavoid
InitList next(
*StaticList*
) // 为静态链表分配空间(StaticList *)L=
{
(
*)Lmalloc ( *StaticList sizeof())MaxSize ; // 初始化*StaticList=*;
[
StaticList 0s ] .L=
s';'[0]data . =-
s1;int;next for (=1
; i<
; ++i ) [] i . MaxSize= i';'[
{
s]i.=data - 2;
s}iprintf(next "已初始化链表\n" );}
// 查找空闲结点位置的下标
intGetFreeNodeIndex(*)
int
;
for (=StaticList 1L;
{
< i;
++ )i if ([ i ] MaxSize. i==-
{
2 )Lreturni;}next } return0;
{
} i// 头部插入
void
HeadInsert
( *)
if
(
) ;printfStaticList (L"请输入插入的数据:"
{
) ;Lfflush
{
DataType x(
stdin);scanf(
"%c",&);
// 获取新结点的下标位置int=GetFreeNodeIndex (x);
if
( free_node 0 )// 设置新结点的数据L[]
. =free_node > ;// 新结点指向链表的第一个结点
{
[
L]free_node.=data [ x0
]
L.free_node;// 头结点指向新结点,使得新结点成为链表的第一个结点next [ L0].=next;
printf
L("插入成功!\n");next } free_nodeelse
printf("插入失败! 链表空间已满!\n");
}
}
{
elseprintf("插入失败! 链表已销毁!\n")
;
}
}
{
// 尾部插入voidTailInsert(*
)
if
(
) int;StaticList ;Lprintf
{
( "请输入插入的数据:"L)
{
; ifflush
DataType x(
stdin);scanf(
"%c",&);
int=GetFreeNodeIndex( )x;if
( free_node 0 )intL=0
; // 查找尾结点下标free_node > while(
{
[ tail_index ] .0
)
= [L]tail_index.;next > }// 设置新结点数据
{
tail_index [ L]tail_index.=next;
// 新结点指针域设置为空
[
L]free_node.=data - x1
;
L//尾结点指向新结点,使得新结点成为链表的最后一个结点free_node[]next . =;printf
(
L"插入成功!\n"tail_index);next } free_nodeelse
printf("插入失败! 链表空间已满\n");
}
}
{
elseprintf("插入失败! 链表已销毁!\n")
;
}
}
{
// 按位置插入voidLocateInsert(*
)
if
(
) int,StaticList ;L;
{
printf (L"请输入插入的数据和插入位置:"
{
) i; kscanf
DataType x(
"%d %c",&,&
);int= GetFreeNodeIndexk( )x;if
( free_node 0 &&0L)int
= 0k > ; // 查找链表中第(k-1)个结点 free_node > while(
{
( insert_index -- )&&
[
].0)k= [ L]insert_index.;next > }// 插入新结点
{
insert_index if L(insert_index==0next)
// 设置新结点数据
[
] .k = ;// 新结点指向第k个结点下标
{
[
L]free_node.=data [ x]
.
L;free_node// 第(k-1)个结点指向新结点[next ] L.insert_index=;nextprintf
(
L"插入成功!\n"insert_index);next } free_nodeelse
printf("插入失败! 插入位置不合法!\n");
}
}
{
elseprintf("插入失败! 插入位置不合法/链表空间已满!\n")
;
}
}
{
elseprintf("插入失败! 链表已销毁!\n")
;
}
}
{
// 头部删除voidHeadDelete(*
)
if
(
) if(StaticList [L0
{
] .L0
{
) intL;// 获取第一个结点=[next > 0]
{
. first_index;
// 头结点指向第二个结点
first_index [ L0].=next[
]
L.;// 初始化第一个结点[next ] L.first_index=';'next[
]
L.first_index=-data 2 ;printf
L(first_index"删除成功!\n")next ; }elseprintf
("删除失败! 链表为空!\n");}
}
else
{
printf("删除失败! 链表已销毁!\n");
}
}
// 尾部删除
{
voidTailDelete(*)
if
(
)
if ([StaticList 0L]
{
. 0L)
{
int =L0,=0next > ;// 查询倒数第一个结点(i)和倒数第二个结点(j)
{
while i ( [] j . 0)
=
; =L[i].next > ;}
{
j // 倒数第二个结点指向-1 i[
i ] L.i=-next1
;
// 初始化最后一个结点
L[j].next = ';'[]
.
L=i-2data ; printf(
L"删除成功!\n"i);next } elseprintf(
"插入失败! 链表为空!\n");}}
else
printf
{
("插入失败! 链表已销毁!\n");}
}
// 按位置删除
void
{
LocateDelete(*)if
(
)
int
; printf(StaticList "请输入删除的数据位置:"L)
{
; scanfL(
{
"%d" k,
&);if(
0&&[0 ]k.0
) intk > = 0 L,=0;next > // 查询第(j = k-1)个结点和第(i = k)个结点while
{
( i ( --) j && []
.
0 )=k;= [ L]i.;next > }if
{
j ( i<
i 0 L)i// 第(k-1)个结点指向第(k+1)个结点[next]
.
= [k ] .;
{
// 初始化第k个结点
L[j].next = L';'i[]next.
=
L-i2;data printf ("删除成功!\n"
L)i;}next else printf("删除失败! 删除位置不合法!\n"
);}}else
printf
(
{
"删除失败! 链表为空!\n");}}
else
printf
(
{
"删除失败! 链表已销毁!\n");}}
// 修改链表
void
ListModify
{
(*)if(
)
int
;
; printf(StaticList "请输入需要修改的位置和修改后的数据:"L)
{
; scanfL(
{
"%d %c" k,
DataType x&
,&);if
(0)int =k0 ;x// 查询第i个结点位置while
( (k > --)
{
&& index [ ].
0
) =[k]. ; L}indexif(next > <0
{
index ) L[index].next=
;
printf (k "修改成功!\n" );
{
L}indexelseprintfdata ( x"修改失败! 修改位置不合法!\n"
);}}else
printf
(
{
"修改失败! 修改位置不合法!\n");}}
else
printf
(
{
"链表已销毁!\n");}}
// 遍历链表
void
DisplayList
{
(*)if(
)
if
(
[ 0]StaticList .L0
{
) intL=
{
[ 0L].;whilenext > (0
{
) index printf L(,[]next.
);index > =[
{
]."%c->"; L}indexprintf(data"null\n")
index ; L}indexelseprintfnext(
"链表为空!\n"
);}}else
printf
(
{
"遍历失败! 链表已销毁!\n");}}
// 求链表长度
void
ListLength
{
(*)if(
)
int
=
0 ,=StaticList 0L;
{
while (L[
{
] index . 0) length ++ ;=
[ ]L.index;}next > printf(
{
length"链表长度length = %d\n",
index ) L;index}elsenextprintf
(
"链表已销毁!\n");} length}// 判断链表是否为空
void
ListEmpty
{
(*)if(
)
if
(
[ 0]StaticList .L0
{
) printfL(
{
"链表非空!\n" )L;}elseprintfnext > ("链表为空!\n"
{
);}}else
printf
(
{
"链表已销毁!\n");}}
// 清空链表
void
ClearList
{
(*)if(
)
if
(
[ 0]StaticList .L0
{
) intL=
{
[ 0L].,=next > [0
{
] i . L;// 依次清除结点while(next0 j ) L// j:用于暂存下一个结点=[]next.
;
// 初始化结点i [i > ].
{
=
j - L2i;// i:移动到下一个结点next=
;
L}i[0next ] .=-
1
i ; jprintf
(
L"链表已清空!\n");}next else printf("链表为空!\n"
);}}else
printf
(
{
"链表已销毁!\n");}}
// 销毁链表
void
DestroyList
{
(**)free
(
*
)
; (*StaticList )=LNULL
{
;printf(L"链表已销毁!\n")
;}L// 打印静态链表数组 void DisplayArr(
*)if()
int
;
printf ("***************************\n"StaticList )L;
{
printf (L"下标:\t"
{
) i;
for(=0;
<;++)printf
( "%d\t"i , ); i } MaxSizeprintf i("\n数据域:\t"
{
);for( i=0
;
<;++)if
( [i ] .) i printf MaxSize( i"%c\t",
{
[ ]L.i);data}
{
elseprintf("-\t" L)i;}data}printf
(
"\n指针域:\t"
{
);for(=
0
;
<;++)printf
( "%d\t"i , [] i . MaxSize) i;}
{
printf("\n***************************\n") L;i}elsenextprintf(
"链表已销毁!\n"
);}}int
main
(
{
)printf("*********************************\n")
;
printf
( "其他 | 0:退出\t1:初始化\n");
{
printf("插入 | 2:头插\t3:尾插\t4:按位插\n");
printf("删除 | 5:头删\t6:尾删\t7:按位删\n");
printf("查询 | 8:修改\t9:遍历\t10:求表长\n");
printf("其他 | 11:表空\t12:清空\t13:销毁\n");
printf("测试 | 14:打印静态链表数组\n");
printf("*********************************\n");
int;*;InitList
(&);while
( k1
StaticList )Lprintf
("请输入 *** 作序号:")L;scanf
( "%d",&
{
);if()
switch()case 1k:InitList
( &k)
{
; breakk;
{
// 插入 case2:HeadInsert(L); break;
case
3 :TailInsert()L;break ;case
4 :LocateInsert()L;break ;// 删除
case 5:HeadDelete(L); break;
case
6 :TailDelete()L;break ;case
7 :LocateDelete()L;break ;// 查询
case 8:ListModify(L); break;
case
9 :DisplayList()L;break ;case
10 :ListLength()L;break ;// 其他
case 11:ListEmpty(L); break;
case
12 :ClearList()L;break ;case
13 :DestroyList(&L); break;
case 14:DisplayArr()L;break;default
: break;}}Lelsebreak ;}
}system("pause"
)
;
return
{
0;
}
2.2 测试结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)