数据结构之线性表的链式存储2.0

数据结构之线性表的链式存储2.0,第1张

文章目录
  • 线性表的链式存储结构(单链表)
    • 单链表的定义
    • 单链表的相关 *** 作实现
      • 初始化
      • 依次对单链表中的每个数据元素输出
      • 在单链表中指定位置之前插入新的数据元素
      • 删除线性表中指定的数据元素
      • 尾插的实现
    • 新增 *** 作
      • 返回单链表中元素的个数
      • 头插的实现
      • 返回指定位序的值
      • 返回第一个满足指定数据元素的位序
      • 整表删除
    • 链式存储的代码实现
    • 样例测试输出
    • 链式存储的优缺点
    • 写在最后

线性表的链式存储结构(单链表)

这里是数据结构个人学习的笔记记录,如有问题欢迎指正说明

单链表的定义

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

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/langs/791364.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-05
下一篇2022-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存