数据结构与算法基础-学习-04-线性表之链式表-查找元素返回位置、查找元素返回指针、插入元素等实现
创始人
2024-02-28 15:37:47
0

一、测试环境

名称
cpu12th Gen Intel® Core™ i7-12700H
操作系统CentOS Linux release 7.9.2009 (Core)
内存3G
逻辑核数2
gcc 版本4.8.5 20150623

二、函数介绍

线性表之链式表的相关函数包括之前篇章《数据结构与算法基础-学习-03-线性表之链式表-初始化、销毁、清理、获取长度、判断为空、获取元素等实现》写的,都以此最新的篇幅为准。

1、CopyElemTypeData

(1)用途

将结构体Src中的数据复制到结构体Dest中。

(2)函数定义

Status CopyElemTypeData(ElemType *Dest, ElemType *Src)
{printf("Copy Elem Type Data\n");strcpy(Dest->StudentNum,Src->StudentNum);strcpy(Dest->StudentName,Src->StudentName);Dest->StudentScore = Src->StudentScore;Dest->NextPointer  = Src->NextPointer;PrintPretty();return SuccessFlag;
}

(3)参数说明

参数名说明
Dest目的端结构体。
Src源端结构体。

2、CmpElemType

(1)用途

比较两个结构体E1、E2是否相等。

(2)函数定义

Status CmpElemType(ElemType *E1, ElemType *E2)
{printf("Compare Struct ElemType\n");JudgeElemTypePointerIsNull(E1);JudgeElemTypePointerIsNull(E2);if(strcmp(E1->StudentNum,E2->StudentNum) != 0){return FailFlag;}if(strcmp(E1->StudentName,E2->StudentName) != 0){return FailFlag;}if((E1->StudentScore) != (E2->StudentScore)){return FailFlag;}return SuccessFlag;
}

(3)参数说明

参数名说明
E1需要比较的结构体1。
E2需要比较的结构体2。

3、LocateElemPointer

(1)用途

在链表L中找到与E相等的结构体返回对应指针。

(2)函数定义

ElemType * LocateElemPointer(LinkList *L, ElemType E)
{printf("Locate Element Pointer\n");JudgePointerNull(L);ElemType *p = L->ElemArray->NextPointer;int i = 0;while(p){if(CmpElemType(p,&E) == SuccessFlag){i++;printf("Pointer : %p, Locate Link List Elem Success\n",p);PrintPretty();return p;}p = p->NextPointer;i++;}if(i != L->ElemArrayLen){printf("ElemArrayLen != Actual Link List Len, Exception Exit!!!\n");exit(ExceptionExitFlag);}printf("Locate Link List Elem Fail!!!\n");PrintPretty();return NULL;
}

(3)参数说明

参数名说明
L需要搜索的链式表。
E需要查找的数据。

4、LocateElemPosition

(1)用途

在链表L中找到与E相等的结构体返回对应位置。

(2)函数定义

int LocateElemPosition(LinkList *L, ElemType E)
{printf("Locate Element Position\n");JudgePointerNull(L);ElemType *p = L->ElemArray->NextPointer;int i = 0;while(p){if(CmpElemType(p,&E) == SuccessFlag){i++;printf("Position : %d, Locate Link List Elem Success\n",i);PrintPretty();return i;}p = p->NextPointer;i++;}if(i != L->ElemArrayLen){printf("ElemArrayLen != Actual Link List Len, Exception Exit!!!\n");exit(ExceptionExitFlag);}printf("Locate Link List Elem Fail!!!\n");PrintPretty();return 0;
}

(3)参数说明

参数名说明
L需要搜索的链式表。
E需要查找的数据。

5、InsertLinkListElem

(1)用途

在链表L的ElemPosition位置插入元素VarElem。

(2)函数定义

//在插入数据时,不能直接用传入参数VarElem对链表L进行指针赋值,也就是注释掉的两行,会导致后续ClearLinkListElem执行时,提示:double free or corruption (out)。
//ClearLinkListElem代码中并没有多次free,改为注释两行上面的五行,问题得到解决。
Status InsertLinkListElem(LinkList *L, int ElemPosition, ElemType *VarElem)
{JudgePointerNull(L);printf("ElemPosition : %d\n",ElemPosition);PrintElemType(VarElem);if(ElemPosition < 1 || ElemPosition > L->ElemArrayLen + 1){printf("Error ,Need 1 <= ElemPosition <= %d\n",L->ElemArrayLen + 1);PrintPretty();return FailFlag;}int i = 0;ElemType *p = L->ElemArray;while(p){if(i == ElemPosition - 1){break;}p = p->NextPointer;i++;}ElemType *TmpElem = (ElemType *)MyMalloc(sizeof(ElemType));InitElemType(TmpElem);CopyElemTypeData(TmpElem,VarElem);TmpElem->NextPointer = p->NextPointer;p->NextPointer = TmpElem;//VarElem->NextPointer = p->NextPointer;//p->NextPointer = VarElem;L->ElemArrayLen++;printf("Insert Data Success\n");PrintPretty();return SuccessFlag;
}

(3)参数说明

参数名说明
L需要插入数据的链式表。
ElemPosition需要插入的位置。
VarElem需要插入的数据。

三、测试代码

1、LinearTable_LinkList.c

#include 
#include 
#include 
#include "LinearTable_LinkList.h"void PrintPretty()
{printf("*********************************\n");
}void PrintPretty_V1()
{printf("################\n");
}void *MyMalloc(size_t size)
{void *Result = (void *)malloc(size);if(Result == NULL){printf("malloc Function Exec Fail , Out Of Memory ,Exit!!!\n");exit(ExceptionExitFlag);}return Result;
}void JudgePointerNull(LinkList *L)
{if(!L){printf("Pointer Is Null ,Exit !\n");exit(ExceptionExitFlag);}
}void JudgeElemTypePointerIsNull(ElemType *E)
{if(!E){printf("Pointer Is Null ,Exit !\n");exit(ExceptionExitFlag);}
}Status InitElemType(ElemType *E)
{JudgeElemTypePointerIsNull(E);memset(E->StudentNum , '\0', sizeof(char) * StudentNumLen);memset(E->StudentName, '\0', sizeof(char) * StudentNameLen);E->StudentScore = 0;E->NextPointer  = NULL;printf("Init ElemType Success\n");PrintPretty();return SuccessFlag;
}Status InitLinkList(LinkList *L)
{JudgePointerNull(L);//L = (LinkList *)MyMalloc(sizeof(LinkList));L->ElemArray = (ElemType *)MyMalloc(sizeof(ElemType));InitElemType(L->ElemArray);L->ElemArrayLen = 0;printf("Init LinkList Success\n");PrintPretty();return SuccessFlag;
}void PrintLinkList(LinkList *L)
{printf("Print Link List\n");JudgePointerNull(L);printf("Link List Pointer     : %p\n",L);PrintPretty_V1();ElemType *p = L->ElemArray;while(p){printf("CurrentPointer        : %p\n",p);printf("StudentNum            : %s\n",p->StudentNum);printf("StudentName           : %s\n",p->StudentName);printf("StudentScore          : %d\n",p->StudentScore);printf("NextPointer           : %p\n",p->NextPointer);PrintPretty_V1();p = p->NextPointer;}printf("ElemArrayLen          : %d\n",L->ElemArrayLen);PrintPretty();
}void PrintElemType(ElemType *E)
{printf("Print Elem Type\n");JudgeElemTypePointerIsNull(E);printf("StudentNum            : %s\n",E->StudentNum);printf("StudentName           : %s\n",E->StudentName);printf("StudentScore          : %d\n",E->StudentScore);printf("NextPointer           : %p\n",E->NextPointer);PrintPretty();
}int JudgeLinkListIsEmpty(LinkList *L)
{JudgePointerNull(L);if(L->ElemArrayLen == 0){printf("Link List Is Empty\n");PrintPretty();return SuccessFlag;}else{printf("Link List Is Not Empty\n");PrintPretty();return FailFlag;}
}void DestroyLinkList(LinkList *L)
{printf("Start Destroy Link List\n");JudgePointerNull(L);ElemType *p = L->ElemArray;ElemType *q = NULL;while(p){q = p->NextPointer;printf("Free Pointer          : %p\n",p);free(p);p = q;}L->ElemArrayLen = 0;free(L);printf("Free Link List Pointer: %p\n",L);L = NULL;printf("Destroy Link List Success !!!\n");PrintPretty();
}Status ClearLinkListElem(LinkList *L)
{printf("Start Clear Link List Elem\n");JudgePointerNull(L);L->ElemArrayLen = 0;ElemType *p = L->ElemArray->NextPointer;ElemType *q = NULL;while(p){q = p->NextPointer;printf("Free Pointer          : %p\n",p);free(p);p = q;}L->ElemArray->NextPointer = NULL;printf("Clear Link List Elem Success !!!\n");PrintPretty();return SuccessFlag;
}int GetLinkListLen(LinkList *L)
{JudgePointerNull(L);printf("Get Link List Len     : %d\n",L->ElemArrayLen);PrintPretty();return L->ElemArrayLen;
}Status CopyElemTypeData(ElemType *Dest, ElemType *Src)
{printf("Copy Elem Type Data\n");strcpy(Dest->StudentNum,Src->StudentNum);strcpy(Dest->StudentName,Src->StudentName);Dest->StudentScore = Src->StudentScore;Dest->NextPointer  = Src->NextPointer;PrintPretty();return SuccessFlag;
}int GetLinkListElem(LinkList *L, int ElemPosition, ElemType *VarElem)
{JudgePointerNull(L);if(ElemPosition < 1 || ElemPosition > L->ElemArrayLen){printf("Error ElemPosition : %d, Need 1 <= ElemPosition <= ElemArrayLen(%d)\n",ElemPosition,L->ElemArrayLen);PrintPretty();return FailFlag;}int i;ElemType *p = L->ElemArray;for(i=1; i<=ElemPosition; i++){p = p->NextPointer;}CopyElemTypeData(VarElem,p);PrintElemType(VarElem);printf("ElemPosition          : %d ,Get Data Success\n",ElemPosition);PrintPretty();return SuccessFlag;
}Status CmpElemType(ElemType *E1, ElemType *E2)
{printf("Compare Struct ElemType\n");JudgeElemTypePointerIsNull(E1);JudgeElemTypePointerIsNull(E2);if(strcmp(E1->StudentNum,E2->StudentNum) != 0){return FailFlag;}if(strcmp(E1->StudentName,E2->StudentName) != 0){return FailFlag;}if((E1->StudentScore) != (E2->StudentScore)){return FailFlag;}return SuccessFlag;
}ElemType * LocateElemPointer(LinkList *L, ElemType E)
{printf("Locate Element Pointer\n");JudgePointerNull(L);ElemType *p = L->ElemArray->NextPointer;int i = 0;while(p){if(CmpElemType(p,&E) == SuccessFlag){i++;printf("Pointer : %p, Locate Link List Elem Success\n",p);PrintPretty();return p;}p = p->NextPointer;i++;}if(i != L->ElemArrayLen){printf("ElemArrayLen != Actual Link List Len, Exception Exit!!!\n");exit(ExceptionExitFlag);}printf("Locate Link List Elem Fail!!!\n");PrintPretty();return NULL;
}int LocateElemPosition(LinkList *L, ElemType E)
{printf("Locate Element Position\n");JudgePointerNull(L);ElemType *p = L->ElemArray->NextPointer;int i = 0;while(p){if(CmpElemType(p,&E) == SuccessFlag){i++;printf("Position : %d, Locate Link List Elem Success\n",i);PrintPretty();return i;}p = p->NextPointer;i++;}if(i != L->ElemArrayLen){printf("ElemArrayLen != Actual Link List Len, Exception Exit!!!\n");exit(ExceptionExitFlag);}printf("Locate Link List Elem Fail!!!\n");PrintPretty();return 0;
}//在插入数据时,不能直接用传入参数VarElem对链表L进行指针赋值,也就是注释掉的两行,会导致后续ClearLinkListElem执行时,提示:double free or corruption (out)。
//ClearLinkListElem代码中并没有多次free,改为注释两行上面的五行,问题得到解决。
Status InsertLinkListElem(LinkList *L, int ElemPosition, ElemType *VarElem)
{JudgePointerNull(L);printf("ElemPosition : %d\n",ElemPosition);PrintElemType(VarElem);if(ElemPosition < 1 || ElemPosition > L->ElemArrayLen + 1){printf("Error ,Need 1 <= ElemPosition <= %d\n",L->ElemArrayLen + 1);PrintPretty();return FailFlag;}int i = 0;ElemType *p = L->ElemArray;while(p){if(i == ElemPosition - 1){break;}p = p->NextPointer;i++;}ElemType *TmpElem = (ElemType *)MyMalloc(sizeof(ElemType));InitElemType(TmpElem);CopyElemTypeData(TmpElem,VarElem);TmpElem->NextPointer = p->NextPointer;p->NextPointer = TmpElem;//VarElem->NextPointer = p->NextPointer;//p->NextPointer = VarElem;L->ElemArrayLen++;printf("Insert Data Success\n");PrintPretty();return SuccessFlag;
}

2、LinearTable_LinkList.h

#ifndef LinearTable_LinkList_H
#define LinearTable_LinkList_H#define InsertDataArrayLen 6#define ExceptionExitFlag -1
#define SuccessFlag        1
#define FailFlag           0
#define ElemArrayMaxLen   10
#define StudentNumLen      8
#define StudentNameLen     8typedef int Status;typedef struct ElemType
{char             StudentNum[StudentNumLen];char             StudentName[StudentNameLen];int              StudentScore;struct ElemType *NextPointer;
}ElemType;typedef struct 
{ElemType *ElemArray;int      ElemArrayLen;
}LinkList;void *MyMalloc(size_t size);
Status InitElemType(ElemType *E);
Status InitLinkList(LinkList *L);
void JudgePointerNull(LinkList *L);
void JudgeElemTypePointerIsNull(ElemType *E);
void PrintLinkList(LinkList *L);
int JudgeLinkListIsEmpty(LinkList *L);
void DestroyLinkList(LinkList *L);
Status ClearLinkListElem(LinkList *L);
int GetLinkListLen(LinkList *L);
Status CopyElemTypeData(ElemType *Dest, ElemType *Src);
int GetLinkListElem(LinkList *L, int ElemPosition, ElemType *VarElem);
void PrintElemType(ElemType *E);
Status CmpElemType(ElemType *E1, ElemType *E2);
ElemType * LocateElemPointer(LinkList *L, ElemType E);
int LocateElemPosition(LinkList *L, ElemType E);
Status InsertLinkListElem(LinkList *L, int ElemPosition, ElemType *VarElem);void PrintPretty();
void PrintPretty_V1();
#endif

3、main.c

#include 
#include 
#include 
#include "LinearTable_LinkList.h"int main()
{LinkList *L = (LinkList *)MyMalloc(sizeof(LinkList));ElemType *VarElem = (ElemType *)MyMalloc(sizeof(ElemType));ElemType *InsertElemArray = (ElemType *)MyMalloc(sizeof(ElemType) * InsertDataArrayLen);int i;for(i=0; iInitElemType(&(InsertElemArray[i]));strcpy(InsertElemArray[i].StudentNum ,"X666");strcpy(InsertElemArray[i].StudentName,"Sun");InsertElemArray[i].StudentScore = i + 100;}InitLinkList(L);PrintLinkList(L);for(i=0; iInsertLinkListElem(L, 1, &(InsertElemArray[i]));}PrintLinkList(L);GetLinkListElem(L, InsertDataArrayLen - 1, VarElem);//PrintElemType(VarElem);LocateElemPointer(L,*VarElem);LocateElemPosition(L,*VarElem);PrintElemType(VarElem);JudgeLinkListIsEmpty(L);GetLinkListLen(L);ClearLinkListElem(L);PrintLinkList(L);DestroyLinkList(L);free(VarElem);free(InsertElemArray);L               = NULL;VarElem         = NULL;InsertElemArray = NULL;return SuccessFlag;
}

4、makefile

CC = gcc
CFLAG_EXEC = -Wall -O3
CFLAG_ALIAS = -o
RM_COMM = rm -rfall : mainmain : $(CC) $(CFLAG_EXEC) LinearTable_LinkList.c main.c $(CFLAG_ALIAS) Test_LinearTable_LinkListclean : $(RM_COMM) Test_LinearTable_LinkList

四、编译测试

[gbase@czg2 LinearTable_LinkList]$ make clean
rm -rf Test_LinearTable_LinkList[gbase@czg2 LinearTable_LinkList]$ make
gcc -Wall -O3 LinearTable_LinkList.c main.c -o Test_LinearTable_LinkList[gbase@czg2 LinearTable_LinkList]$ ./Test_LinearTable_LinkList 
Init ElemType Success
*********************************
Init ElemType Success
*********************************
Init ElemType Success
*********************************
Init ElemType Success
*********************************
Init ElemType Success
*********************************
Init ElemType Success
*********************************
Init ElemType Success
*********************************
Init LinkList Success
*********************************
Print Link List
Link List Pointer     : 0x1552010
################
CurrentPointer        : 0x1552130
StudentNum            : 
StudentName           : 
StudentScore          : 0
NextPointer           : (nil)
################
ElemArrayLen          : 0
*********************************
ElemPosition : 1
Print Elem Type
StudentNum            : X666
StudentName           : Sun
StudentScore          : 100
NextPointer           : (nil)
*********************************
Init ElemType Success
*********************************
Copy Elem Type Data
*********************************
Insert Data Success
*********************************
ElemPosition : 1
Print Elem Type
StudentNum            : X666
StudentName           : Sun
StudentScore          : 101
NextPointer           : (nil)
*********************************
Init ElemType Success
*********************************
Copy Elem Type Data
*********************************
Insert Data Success
*********************************
ElemPosition : 1
Print Elem Type
StudentNum            : X666
StudentName           : Sun
StudentScore          : 102
NextPointer           : (nil)
*********************************
Init ElemType Success
*********************************
Copy Elem Type Data
*********************************
Insert Data Success
*********************************
ElemPosition : 1
Print Elem Type
StudentNum            : X666
StudentName           : Sun
StudentScore          : 103
NextPointer           : (nil)
*********************************
Init ElemType Success
*********************************
Copy Elem Type Data
*********************************
Insert Data Success
*********************************
ElemPosition : 1
Print Elem Type
StudentNum            : X666
StudentName           : Sun
StudentScore          : 104
NextPointer           : (nil)
*********************************
Init ElemType Success
*********************************
Copy Elem Type Data
*********************************
Insert Data Success
*********************************
ElemPosition : 1
Print Elem Type
StudentNum            : X666
StudentName           : Sun
StudentScore          : 105
NextPointer           : (nil)
*********************************
Init ElemType Success
*********************************
Copy Elem Type Data
*********************************
Insert Data Success
*********************************
Print Link List
Link List Pointer     : 0x1552010
################
CurrentPointer        : 0x1552130
StudentNum            : 
StudentName           : 
StudentScore          : 0
NextPointer           : 0x1552250
################
CurrentPointer        : 0x1552250
StudentNum            : X666
StudentName           : Sun
StudentScore          : 105
NextPointer           : 0x1552220
################
CurrentPointer        : 0x1552220
StudentNum            : X666
StudentName           : Sun
StudentScore          : 104
NextPointer           : 0x15521f0
################
CurrentPointer        : 0x15521f0
StudentNum            : X666
StudentName           : Sun
StudentScore          : 103
NextPointer           : 0x15521c0
################
CurrentPointer        : 0x15521c0
StudentNum            : X666
StudentName           : Sun
StudentScore          : 102
NextPointer           : 0x1552190
################
CurrentPointer        : 0x1552190
StudentNum            : X666
StudentName           : Sun
StudentScore          : 101
NextPointer           : 0x1552160
################
CurrentPointer        : 0x1552160
StudentNum            : X666
StudentName           : Sun
StudentScore          : 100
NextPointer           : (nil)
################
ElemArrayLen          : 6
*********************************
Copy Elem Type Data
*********************************
Print Elem Type
StudentNum            : X666
StudentName           : Sun
StudentScore          : 101
NextPointer           : 0x1552160
*********************************
ElemPosition          : 5 ,Get Data Success
*********************************
Locate Element Pointer
Compare Struct ElemType
Compare Struct ElemType
Compare Struct ElemType
Compare Struct ElemType
Compare Struct ElemType
Pointer : 0x1552190, Locate Link List Elem Success
*********************************
Locate Element Position
Compare Struct ElemType
Compare Struct ElemType
Compare Struct ElemType
Compare Struct ElemType
Compare Struct ElemType
Position : 5, Locate Link List Elem Success
*********************************
Print Elem Type
StudentNum            : X666
StudentName           : Sun
StudentScore          : 101
NextPointer           : 0x1552160
*********************************
Link List Is Not Empty
*********************************
Get Link List Len     : 6
*********************************
Start Clear Link List Elem
Free Pointer          : 0x1552250
Free Pointer          : 0x1552220
Free Pointer          : 0x15521f0
Free Pointer          : 0x15521c0
Free Pointer          : 0x1552190
Free Pointer          : 0x1552160
Clear Link List Elem Success !!!
*********************************
Print Link List
Link List Pointer     : 0x1552010
################
CurrentPointer        : 0x1552130
StudentNum            : 
StudentName           : 
StudentScore          : 0
NextPointer           : (nil)
################
ElemArrayLen          : 0
*********************************
Start Destroy Link List
Free Pointer          : 0x1552130
Free Link List Pointer: 0x1552010
Destroy Link List Success !!!
*********************************

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...