
- 线性表的链式存储结构(单链表)
- 单链表的定义
- 单链表的相关 *** 作实现
- 初始化
- 依次对单链表中的每个数据元素输出
- 在单链表中指定位置之前插入新的数据元素
- 删除线性表中指定的数据元素
- 尾插的实现
- 新增 *** 作
- 返回单链表中元素的个数
- 头插的实现
- 返回指定位序的值
- 返回第一个满足指定数据元素的位序
- 整表删除
- 链式存储的代码实现
- 样例测试输出
- 链式存储的优缺点
- 写在最后
单链表的定义这里是数据结构个人学习的笔记记录,如有问题欢迎指正说明
n个结点链结成一个链表。每个结点由数据域和指针域两部分组成,在此处我们之研究结点只含一个指针域的链表,即单链表。
结点的表示方法:
typedef struct LinkNode
{
char data;
struct LinkNode *next;
}LNode,*LinkList,*NodePtr;
单链表的相关 *** 作实现 初始化我们把链表中的第一个结点的存储位置叫做头指针,整个链表的存取必须从头指针开始。为了方便 *** 作,我们还可以在单链表的第一个结点前附设一个结点,称为头结点。注意头结点不是必不可少的。头结点和头指针的异同如下图:
/* 初始化 */
LinkList initLinkList(){
NodePtr tempHeader=(NodePtr)malloc(sizeof(LNode));
tempHeader->data=';'=
tempHeader->nextNULL;return
; tempHeader}
/* 依次对L的每个数据元素输出 */
依次对单链表中的每个数据元素输出
ListTraverse
Status ()LinkList L=
{
LinkList p;L->nextwhile
()pvisit
{
()p->data;//vist函数为输出值=
p;p->next}
printf
("\n");return
; OK}
/* 在单链表中指定位置之前插入新的数据元素 */
在单链表中指定位置之前插入新的数据元素
void
insertElement (,NodePtr paraHeaderchar, paraCharint) paraPosition,{
NodePtr p;q=
p;paraHeaderfor
(int= i0;<i;paraPosition++i)={
p;p->nextif
(==pNULL)printf{
("The postion %d is beyond the scope of the list.",)paraPosition;return
;}
}
=
q()NodePtrmalloc(sizeof()LNode);=
q->data;paraCharprintf
("linking\r\n");=
q->next;p->next=
p->next;q}
/* 删除线性表的指定位置的数据元素 */
删除线性表中指定的数据元素
void
deleteElement (,NodePtr paraHeaderchar) paraChar,{
NodePtr p;q=
p;paraHeaderwhile
((!=p->nextNULL)&&(!=p->next->data)paraChar)={
p;p->next}
if
(==p->nextNULL)printf{
("Cannot delete %c\r\n",)paraChar;return
;}
=
q;p->next=
p->next;q->nextfree
()q;}
void
尾插的实现
appendElement (,NodePtr paraHeaderchar ) paraChar,{
NodePtr p; q// Step 1. Construct a new node.
=
q ( )NodePtrmalloc(sizeof()LNode);=
q->data ; paraChar=
q->next NULL ;// Step 2. Search to the tail.
=
p ; paraHeaderwhile
( !=p->next NULL )= {
p ; p->next}
// Of while// Step 3. Now add/link.
=
p->next ; q}
/* 返回单链表中数据元素个数 */
新增 *** 作
返回单链表中元素的个数
int
ListLength ()NodePtr paraHeaderint
{
= i0;=
NodePtr paraNew;paraHeader->nextwhile
()paraNew++
{
i;=
paraNew;paraNew->next}
return
; i}
/* 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
头插的实现
void
CreateListHead (*LinkList ,Lint) n;
{
LinkList pint
; isrand
(time(0));*
=L()LinkListmalloc(sizeof()Node);(
*)L=->nextNULL;for
(=i0;<i;n++i)=
{
p()LinkListmalloc(sizeof()Node);=
p->datarand()%100+1;=
p->next(*)L;->next(
*)L=->next;p}
}
/* 返回线性表中第i个数据元素的值 */
返回指定位序的值
char
GetElement (,NodePtr paraHeaderint) iint
{
= j1;;
NodePtr p=
p;paraHeader->nextwhile
(&&p<j)i=
{
p;p->next++
;j}
if
(!||p)j>iprintf
{
("Invalid number!\n");return
- 1;}
return
; p->data}
/* 返回单链表中第1个与paraChar满足关系的数据元素的位序。 */
返回第一个满足指定数据元素的位序
/* 若这样的数据元素不存在,则返回值为-1 */
char
LocateElement (,NodePtr paraHeaderchar) paraCharint
{
= i0;=
NodePtr p;paraHeader->nextwhile
()p++
{
i;if
(==p->data)paraCharreturn
; i=
p;p->next}
return
- 1;}
/* 初始条件:链式线性表L已存在。 *** 作结果:将L重置为空表 */
整表删除
ClearList
Status (*LinkList )L,
{
LinkList p;q=
p(*)L;->nextwhile
()p=
{
q;p->nextfree
()p;=
p;q}
(
*)L=->nextNULL;return
; OK}
#
链式存储的代码实现
include#
includetypedef
struct LinkNode char{
; datastruct
LinkNode * ;next}
,LNode*,LinkList*;NodePtrinitLinkList
LinkList ()={
NodePtr tempHeader()NodePtrmalloc(sizeof()LNode);=
tempHeader->data';'=NULL
tempHeader->next;return;
} tempHeadervoid
printList
( )=NodePtr paraHeader;{
NodePtr pwhileparaHeader->next(
!=NULLp)printf({
"%c",);p->data=;
p}p->nextprintf
(
"\r\n");}void
insertElement
( ,charNodePtr paraHeader,int paraChar), paraPosition;{
NodePtr p=q;
pforparaHeader(
int=0 i;<;i++paraPosition)i=;{
pifp->next(
==NULLp)printf({
"The postion %d is beyond the scope of the list.",);paraPositionreturn;
}}
=
(
q)mallocNodePtr(sizeof())LNode;=;
q->dataprintfparaChar(
"linking\r\n");=;
q->next=p->next;
p->next}qvoid
deleteElement
( ,charNodePtr paraHeader), paraChar;{
NodePtr p=q;
pwhileparaHeader(
(!=NULLp->next)&&(!=)p->next->data)paraChar=;{
p}p->nextif
(
==NULLp->next)printf({
"Cannot delete %c\r\n",);paraCharreturn;
}=
;
q=p->next;
p->nextfreeq->next(
);q}/*尾插*/
void
appendElement
( ,charNodePtr paraHeader) , paraChar;{
NodePtr p// Step 1. Construct a new node. q=
(
q ) mallocNodePtr(sizeof())LNode;=;
q->data = paraCharNULL
q->next ; // Step 2. Search to the tail.=
;
p while paraHeader(
!= NULLp->next ) =; {
p } p->next// Of while
// Step 3. Now add/link.=
;
p->next } q/*头插*/
void
headElement
( ,charNodePtr paraHeader), paraChar;{
NodePtr p=q;
p=paraHeader(
q)mallocNodePtr(sizeof())LNode;=;
q->data=paraChar;
q->next=p->next;
p->next}q/* 返回线性表中第i个数据元素的值 */
char
GetElement
( ,intNodePtr paraHeader)int i=
{
1 j;;=
NodePtr p;
pwhileparaHeader->next(
&&<p)j=i;
{
p++p->next;
}jif
(
!||)pprintfj>i(
{
"Invalid number!\n");return-
1 ;}return
;
} p->data/* 返回单链表中第1个与paraChar满足关系的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为-1 */
char
LocateElement
( ,charNodePtr paraHeader)int paraChar=
{
0 i;=;
NodePtr pwhileparaHeader->next(
)++p;
{
iif(
==)p->datareturnparaChar;
= i;
p}p->nextreturn
-
1 ;}/* 初始条件:链式线性表L已存在。 *** 作结果:返回L中数据元素个数 */
int
ListLength
( )intNodePtr paraHeader=
{
0 i;=;
NodePtr paraNewwhileparaHeader->next(
)++paraNew;
{
i=;
paraNew}paraNew->nextreturn
;
} i/* 初始条件:链式线性表L已存在。 *** 作结果:将L重置为空表 */
void
ClearList
( ),NodePtr paraHeader;
{
NodePtr p=q;
pwhileparaHeader->next(
)=p;
{
qfreep->next(
);p=;
p}q=
NULL
paraHeader->next;}void
appendInsertDeleteTest
( )// Step 1. Initialize an empty list.={
initLinkList
LinkList tempList ( );printList(
);tempList// Step 2. Add some characters.appendElement
(
,'H'tempList) ;appendElement(
,'e'tempList) ;appendElement(
,'l'tempList) ;appendElement(
,'l'tempList) ;appendElement(
,'o'tempList) ;appendElement(
,'!'tempList) ;headElement(
,'w'tempList);printList(
);tempListprintf(
"The sixth element is %c\n",GetElement(,6tempList));printf(
"'e' is the %d of the list\n",LocateElement(,'e'tempList));printf(
"Length of the list is %d\n",ListLength())tempList;// Step 3. Delete some characters (the first occurrence).deleteElement
(
,'e'tempList) ;deleteElement(
,'a'tempList) ;deleteElement(
,'o'tempList) ;printList(
);tempList// Step 4. Insert to a given position.insertElement
(
,'o'tempList, 1) ;printList(
);tempListClearList(
);tempListprintf(
"Length of the list is %d\n",ListLength())tempList;}// Of appendInsertDeleteTest
voidbasicAddressTest
( ),;{
LNode tempNode1. tempNode2=
tempNode14data ; .=
tempNode1NULLnext ; .=
tempNode26data ; .=
tempNode2NULLnext ; printf(
"The first node: %d, %d, %d\r\n",&,
&tempNode1. ,tempNode1&data. )tempNode1;nextprintf(
"The second node: %d, %d, %d\r\n",&,
&tempNode2. ,tempNode2&data. )tempNode2;next.=
tempNode1&next ; }tempNode2int
main
( )appendInsertDeleteTest({
);basicAddressTest(
);}!
'e'
样例测试输出
wHello3
The sixth element is o
7 is the delete of the list
Length of the list is !
Cannot ! a
wHll0
linking
woHll:
Length of the list is 6421984
The first node, 6421984, 6421992: 6421968
The second node, 6421968, 6421976
链式存储的优缺点
写在最后优点:存储空间可自由扩充
插入、删除等 *** 作不必移动数据,修改效率较高
缺点:读写效率不高,必须采用顺序读取
通过对单链表结构和顺序存储结构不同功能时间复杂度的分析,可以得出以下结论:
1,若线性表需要频繁查找,很少进行插入和删除 *** 作时,宜采用顺序存储结构。
2.当线性表中元素个数未知时,宜采用链式存储结构。
噢对了,欢迎移步我另一篇实现方法(手动狗头)
https://blog.csdn.net/AHuRui/article/details/124453661?utm_source=app&app_version=5.3.1
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)