一、测试环境
名称 | 值 |
cpu | 12th Gen Intel(R) Core(TM) i7-12700H |
操作系统 | CentOS Linux release 7.9.2009 (Core) |
内存 | 3G |
逻辑核数 | 2 |
gcc 版本 | 4.8.5 20150623 |
二、时间效率比较
查找头节点 | 查找尾节点 | 查找指定节点的前驱节点 | |
带头结点的单链表 | 时间复杂度O(1) | 时间复杂度O(n) | 无法找到 |
带头结点的单向循环链表 | 时间复杂度O(1) | 时间复杂度O(n) | 时间复杂度O(n) |
带头结点的尾指针单向循环链表 | 时间复杂度O(1) | 时间复杂度O(1) | 时间复杂度O(n) |
带头节点的双向循环链表 | 时间复杂度O(1) | 时间复杂度O(1) | 时间复杂度O(1) |
三、函数介绍
1、InitDuElemType
(1)用途
初始化数据节点。
(2)函数定义
Status InitDuElemType(DuElemType *E)
{
JudgeAllNullPointer(E);
memset(E->StudentNum , '\0', sizeof(char) * StudentNumLen);
memset(E->StudentName, '\0', sizeof(char) * StudentNameLen);
E->StudentScore = 0;
E->PriorPointer = NULL;
E->NextPointer = NULL;
return SuccessFlag;
}
(3)参数说明
参数名 | 说明 |
E | 需要初始化的DuElemType *类型数据节点。 |
2、InitDuLinkList
(1)用途
初始化双向循环链表。
(2)函数定义
Status InitDuLinkList(DuLinkList *L)
{
JudgeAllNullPointer(L);
L->ElemArray = (DuElemType *)MyMalloc(sizeof(DuElemType));
InitDuElemType(L->ElemArray);
L->ElemArray->PriorPointer = L->ElemArray;
L->ElemArray->NextPointer = L->ElemArray;
L->ElemArrayLen = 0;
printf("Init Double LinkList Success\n");
PrintPretty();
return SuccessFlag;
}
(3)参数说明
参数名 | 说明 |
L | 需要初始化的DuLinkList *类型双向循环链表。 |
3、CopyDuElemTypeData
(1)用途
将Src中的数据复制到Dest中。
(2)函数定义
Status CopyDuElemTypeData(DuElemType *Dest, DuElemType *Src)
{
strcpy(Dest->StudentNum,Src->StudentNum);
strcpy(Dest->StudentName,Src->StudentName);
Dest->StudentScore = Src->StudentScore;
return SuccessFlag;
}
(3)参数说明
参数名 | 说明 |
Dest | 需要复制数据的DuElemType *类型目的端节点。 |
Src | 有复制数据的DuElemType *类型源端节点。 |
4、InsertDuLinkListElem
(1)用途
将数据DE插入到L的指定位置DuElemPosition。
(2)函数定义
Status InsertDuLinkListElem(DuLinkList *L, int DuElemPosition, DuElemType DE)
{
printf("Insert DuElement\n");
JudgeAllNullPointer(L);
if(DuElemPosition < 1 || DuElemPosition > L->ElemArrayLen + 1)
{
printf("DuElemPosition : %d, ElemArrayLen : %d, DuElemPosition Need >= 1 And <= ElemArrayLen + 1\n",DuElemPosition,L->ElemArrayLen);
return FailFlag;
}
DuElemType *p = L->ElemArray;
int i = 0;
while(p)
{
if(i == DuElemPosition - 1)
{
DuElemType* NewNode = (DuElemType*)MyMalloc(sizeof(DuElemType));
CopyDuElemTypeData(NewNode, &DE);
NewNode->NextPointer = p->NextPointer;
NewNode->PriorPointer = p;
p->NextPointer->PriorPointer = NewNode;
p->NextPointer = NewNode;
L->ElemArrayLen++;
printf("Insert Double Link List Elem Success\n");
PrintPretty();
return SuccessFlag;
}
p = p->NextPointer;
i++;
}
printf("Insert Double Link List Elem Fail!!!\n");
PrintPretty();
return FailFlag;
}
(3)参数说明
参数名 | 说明 |
L | 需要插入数据的双向循环链表。 |
DuElemPosition | 需要插入的节点位置。 |
DE | 需要插入的数据。 |
5、PrintDuLinkList
(1)用途
打印双向循环链表的内容。
(2)函数定义
void PrintDuLinkList(DuLinkList *L)
{
printf("Print Link List\n");
JudgeAllNullPointer(L);
printf("Link List Pointer : %p\n",L);
PrintPretty_V1();
DuElemType *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("PriorPointer : %p\n",p->PriorPointer);
printf("NextPointer : %p\n",p->NextPointer);
PrintPretty_V1();
p = p->NextPointer;
if(p == L->ElemArray)
{
printf("Double Cycle Link List Printf End\n");
break;
}
}
printf("ElemArrayLen : %d\n",L->ElemArrayLen);
PrintPretty();
}
(3)参数说明
参数名 | 说明 |
L | 需要打印的双向循环链表。 |
6、DeleteDuLinkListElem
(1)用途
删除双向循环链表L指定位置ElemPosition的数据,将删除的数据赋予输出参数DelVarElem。
(2)函数定义
Status DeleteDuLinkListElem(DuLinkList *L, int ElemPosition, DuElemType *DelVarElem)
{
JudgeAllNullPointer(L);
printf("ElemPosition : %d\n",ElemPosition);
if(ElemPosition < 1 || ElemPosition > L->ElemArrayLen)
{
printf("Error ,Need 1 <= ElemPosition <= %d\n",L->ElemArrayLen);
PrintPretty();
return FailFlag;
}
int i = 0;
DuElemType *p = L->ElemArray;
while(p)
{
if(i == ElemPosition - 1)
{
DuElemType *TmpDelElem = p->NextPointer;
CopyDuElemTypeData(DelVarElem,p->NextPointer);
p->NextPointer->NextPointer->PriorPointer = p;
p->NextPointer = p->NextPointer->NextPointer;
free(TmpDelElem);
TmpDelElem = NULL;
break;
}
p = p->NextPointer;
i++;
}
L->ElemArrayLen--;
printf("Delete Data Success\n");
PrintPretty();
return SuccessFlag;
}
(3)参数说明
参数名 | 说明 |
L | 需要删除的双向循环链表。 |
ElemPosition | 需要删除的数据位置。 |
DelVarElem | 输出参数,会赋予删除的数据。 |
7、DestroyDuLinkList
(1)用途
销毁双向循环链表L。
(2)函数定义
void DestroyDuLinkList(DuLinkList *L)
{
printf("Start Destroy Double Link List\n");
JudgeAllNullPointer(L);
DuElemType *p = L->ElemArray;
DuElemType *q = NULL;
while(p)
{
q = p->NextPointer;
free(p);
p = q;
if(p == L->ElemArray)
{
printf("Double Cycle Link List ");
break;
}
}
L->ElemArrayLen = 0;
free(L);
L = NULL;
printf("Destroy Success !!!\n");
PrintPretty();
}
(3)参数说明
参数名 | 说明 |
L | 需要销毁的双向循环链表。 |
四、测试代码
1、LinearTable_LinkList.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#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;
if(p == L->ElemArray)
{
printf("Cycle Link List Printf End\n");
break;
}
}
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;
free(p);
//printf("Free Pointer : %p\n",p);
p = q;
if(p == L->ElemArray)
{
printf("Cycle Link List ");
break;
}
}
L->ElemArrayLen = 0;
free(L);
//printf("Free Link List Pointer: %p\n",L);
L = NULL;
printf("Destroy 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)
{
strcpy(Dest->StudentNum,Src->StudentNum);
strcpy(Dest->StudentName,Src->StudentName);
Dest->StudentScore = Src->StudentScore;
Dest->NextPointer = Src->NextPointer;
return SuccessFlag;
}
Status CopyElemTypeDataNoNextP(ElemType *Dest, ElemType *Src)
{
strcpy(Dest->StudentNum,Src->StudentNum);
strcpy(Dest->StudentName,Src->StudentName);
Dest->StudentScore = Src->StudentScore;
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\n",p);
printf("Locate Link List Elem Success\n");
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\n",i);
printf("Locate Link List Elem Success\n");
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;
}
//Status InsertLinkListElem(LinkList *L, int ElemPosition, ElemType *VarElem)
//在插入数据时,不能直接用传入参数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;
}
Status DeleteLinkListElem(LinkList *L, int ElemPosition, ElemType *DelVarElem)
{
JudgePointerNull(L);
printf("ElemPosition : %d\n",ElemPosition);
if(ElemPosition < 1 || ElemPosition > L->ElemArrayLen)
{
printf("Error ,Need 1 <= ElemPosition <= %d\n",L->ElemArrayLen);
PrintPretty();
return FailFlag;
}
int i = 0;
ElemType *p = L->ElemArray;
while(p)
{
if(i == ElemPosition - 1)
{
break;
}
p = p->NextPointer;
i++;
}
ElemType *TmpDelElem = p->NextPointer;
CopyElemTypeData(DelVarElem,TmpDelElem);
//DelVarElem = TmpDelElem; //虽然这样方便,但怕出现问题,就用上面的方法把。
//PrintElemType(DelVarElem);
p->NextPointer = TmpDelElem->NextPointer;
free(TmpDelElem);
TmpDelElem = NULL;
L->ElemArrayLen--;
printf("Delete Data Success\n");
PrintPretty();
return SuccessFlag;
}
Status CreateHeadLinkList(LinkList *L, int LinkListLen)
{
JudgePointerNull(L);
if(LinkListLen < 1)
{
printf("LinkListLen Need >= 1\n");
return FailFlag;
}
printf("Create Empty Head Insert Link List Len : %d\n",LinkListLen);
int i;
InitLinkList(L);
ElemType *InsertElem = (ElemType *)MyMalloc(sizeof(ElemType));
InitElemType(InsertElem);
for(i=1; i<=LinkListLen; i++)
{
//ElemType *InsertElem = (ElemType *)MyMalloc(sizeof(ElemType));
InsertLinkListElem(L, 1, *InsertElem);
//free(InsertElem);
//InsertElem = NULL;
}
free(InsertElem);
InsertElem = NULL;
printf("Create Empty Head Insert Link List Success\n");
PrintPretty();
return SuccessFlag;
}
Status CreateHeadLinkList_V1(LinkList *L, int LinkListLen)
{
JudgePointerNull(L);
if(LinkListLen < 1)
{
printf("LinkListLen Need >= 1\n");
return FailFlag;
}
printf("Create Empty Head Insert Link List Len : %d\n",LinkListLen);
int i;
InitLinkList(L);
for(i=1; i<=LinkListLen; i++)
{
ElemType *InsertElem = (ElemType *)MyMalloc(sizeof(ElemType));
InitElemType(InsertElem);
InsertElem->NextPointer = L->ElemArray->NextPointer;
L->ElemArray->NextPointer = InsertElem;
(L->ElemArrayLen)++;
}
printf("Create Empty Head Insert Link List Success\n");
PrintPretty();
return SuccessFlag;
}
void ComputeProcedureTime(Status Func(LinkList *, int), LinkList *L, int LinkListLen)
{
printf("========================================\n");
struct timeval start,end;
unsigned long TotalTime;
gettimeofday(&start, NULL);
Func(L, LinkListLen);
gettimeofday(&end, NULL);
TotalTime = end.tv_sec - start.tv_sec;
printf("Elapsed Time : %ld s\n",TotalTime);
}
Status CreateTailLinkList(LinkList *L, int LinkListLen)
{
JudgePointerNull(L);
if(LinkListLen < 1)
{
printf("LinkListLen Need >= 1\n");
return FailFlag;
}
printf("Create Empty Tail Insert Link List Len : %d\n",LinkListLen);
int i;
InitLinkList(L);
ElemType *CurNode = L->ElemArray;
for(i=1; i<=LinkListLen; i++)
{
ElemType *InsertElem = (ElemType *)MyMalloc(sizeof(ElemType));
InitElemType(InsertElem);
CurNode->NextPointer = InsertElem;
CurNode = InsertElem;
(L->ElemArrayLen)++;
}
printf("Create Empty Tail Insert Link List Success\n");
PrintPretty();
return SuccessFlag;
}
Status CreateCycleLinkList(LinkList *L, int LinkListLen)
{
JudgePointerNull(L);
if(LinkListLen < 1)
{
printf("Cycle Link List Len Need >= 1\n");
return FailFlag;
}
printf("Create Empty Cycle Link List Len : %d\n",LinkListLen);
int i;
InitLinkList(L);
ElemType *CurNode = L->ElemArray;
for(i=1; i<=LinkListLen; i++)
{
ElemType *InsertElem = (ElemType *)MyMalloc(sizeof(ElemType));
InitElemType(InsertElem);
CurNode->NextPointer = InsertElem;
CurNode = InsertElem;
(L->ElemArrayLen)++;
}
CurNode->NextPointer = L->ElemArray;
printf("Create Empty Cycle Link List Success\n");
PrintPretty();
return SuccessFlag;
}
Status CreateCycleTailLinkList(LinkList *L, int LinkListLen)
{
JudgePointerNull(L);
if(LinkListLen < 1)
{
printf("Cycle Tail Link List Len Need >= 1\n");
return FailFlag;
}
printf("Create Empty Cycle Tail Link List Len : %d\n",LinkListLen);
int i;
InitLinkList(L);
ElemType *CurNode = L->ElemArray;
for(i=1; i<=LinkListLen; i++)
{
ElemType *InsertElem = (ElemType *)MyMalloc(sizeof(ElemType));
InitElemType(InsertElem);
CurNode->NextPointer = InsertElem;
CurNode = InsertElem;
(L->ElemArrayLen)++;
}
CurNode->NextPointer = L->ElemArray;
L->ElemArray = CurNode;
L->ElemArrayLen = LinkListLen;
printf("Create Empty Cycle Tail Link List Success\n");
PrintPretty();
return SuccessFlag;
}
Status UpdateCycleTailLinkListElem(LinkList *L, int Position, ElemType UpdateElem)
{
JudgePointerNull(L);
if(Position < 1 || Position > L->ElemArrayLen)
{
printf("Position Need >= 1 and <= %d\n",L->ElemArrayLen);
return FailFlag;
}
if(Position == L->ElemArrayLen)
{
CopyElemTypeDataNoNextP(L->ElemArray, &UpdateElem);
printf("Update Cycle Tail Link List Elem Success\n");
return SuccessFlag;
}
int i;
ElemType *TmpNode = L->ElemArray->NextPointer;
for(i=1; i<= Position; i++)
{
TmpNode = TmpNode->NextPointer;
}
CopyElemTypeDataNoNextP(TmpNode, &UpdateElem);
printf("Update Cycle Tail Link List Elem Success\n");
PrintPretty();
return SuccessFlag;
}
LinkList *Connect2CycleTailLinkList(LinkList *L1, LinkList *L2)
{
JudgePointerNull(L1);
JudgePointerNull(L2);
printf("Connect 2 Cycle Tail Link List ");
LinkList *NewCTLinkList = (LinkList *)MyMalloc(sizeof(LinkList));
//NewCTLinkList->ElemArray = (ElemType *)MyMalloc(sizeof(ElemType));
NewCTLinkList->ElemArrayLen = (L1->ElemArrayLen) + (L2->ElemArrayLen);
NewCTLinkList->ElemArray = L2->ElemArray;
ElemType *L1Head = L1->ElemArray->NextPointer;
ElemType *L2Head = L2->ElemArray->NextPointer;
L2->ElemArray->NextPointer = L1Head;
L1->ElemArray->NextPointer = L2Head->NextPointer;
free(L2Head);
L1->ElemArray = NULL;
L2->ElemArray = NULL;
L1->ElemArrayLen = 0;
L2->ElemArrayLen = 0;
printf("Success \n");
PrintPretty();
return NewCTLinkList;
}
void JudgeAllNullPointer(void* P)
{
if(!P)
{
printf("Pointer Is Null ,Exit !\n");
exit(ExceptionExitFlag);
}
}
Status InitDuElemType(DuElemType *E)
{
JudgeAllNullPointer(E);
memset(E->StudentNum , '\0', sizeof(char) * StudentNumLen);
memset(E->StudentName, '\0', sizeof(char) * StudentNameLen);
E->StudentScore = 0;
E->PriorPointer = NULL;
E->NextPointer = NULL;
return SuccessFlag;
}
Status InitDuLinkList(DuLinkList *L)
{
JudgeAllNullPointer(L);
L->ElemArray = (DuElemType *)MyMalloc(sizeof(DuElemType));
InitDuElemType(L->ElemArray);
L->ElemArray->PriorPointer = L->ElemArray;
L->ElemArray->NextPointer = L->ElemArray;
L->ElemArrayLen = 0;
printf("Init Double LinkList Success\n");
PrintPretty();
return SuccessFlag;
}
Status CmpDuElemType(DuElemType *E1, DuElemType *E2)
{
JudgeAllNullPointer(E1);
JudgeAllNullPointer(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;
}
Status CopyDuElemTypeData(DuElemType *Dest, DuElemType *Src)
{
strcpy(Dest->StudentNum,Src->StudentNum);
strcpy(Dest->StudentName,Src->StudentName);
Dest->StudentScore = Src->StudentScore;
return SuccessFlag;
}
Status InsertDuLinkListElem(DuLinkList *L, int DuElemPosition, DuElemType DE)
{
printf("Insert DuElement\n");
JudgeAllNullPointer(L);
if(DuElemPosition < 1 || DuElemPosition > L->ElemArrayLen + 1)
{
printf("DuElemPosition : %d, ElemArrayLen : %d, DuElemPosition Need >= 1 And <= ElemArrayLen + 1\n",DuElemPosition,L->ElemArrayLen);
return FailFlag;
}
DuElemType *p = L->ElemArray;
int i = 0;
while(p)
{
if(i == DuElemPosition - 1)
{
DuElemType* NewNode = (DuElemType*)MyMalloc(sizeof(DuElemType));
CopyDuElemTypeData(NewNode, &DE);
NewNode->NextPointer = p->NextPointer;
NewNode->PriorPointer = p;
p->NextPointer->PriorPointer = NewNode;
p->NextPointer = NewNode;
L->ElemArrayLen++;
printf("Insert Double Link List Elem Success\n");
PrintPretty();
return SuccessFlag;
}
p = p->NextPointer;
i++;
}
if(i != L->ElemArrayLen)
{
printf("ElemArrayLen != Actual Link List Len, Exception Exit!!!\n");
exit(ExceptionExitFlag);
}
printf("Insert Double Link List Elem Fail!!!\n");
PrintPretty();
return FailFlag;
}
void PrintDuLinkList(DuLinkList *L)
{
printf("Print Link List\n");
JudgeAllNullPointer(L);
printf("Link List Pointer : %p\n",L);
PrintPretty_V1();
DuElemType *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("PriorPointer : %p\n",p->PriorPointer);
printf("NextPointer : %p\n",p->NextPointer);
PrintPretty_V1();
p = p->NextPointer;
if(p == L->ElemArray)
{
printf("Double Cycle Link List Printf End\n");
break;
}
}
printf("ElemArrayLen : %d\n",L->ElemArrayLen);
PrintPretty();
}
Status DeleteDuLinkListElem(DuLinkList *L, int ElemPosition, DuElemType *DelVarElem)
{
JudgeAllNullPointer(L);
printf("ElemPosition : %d\n",ElemPosition);
if(ElemPosition < 1 || ElemPosition > L->ElemArrayLen)
{
printf("Error ,Need 1 <= ElemPosition <= %d\n",L->ElemArrayLen);
PrintPretty();
return FailFlag;
}
int i = 0;
DuElemType *p = L->ElemArray;
while(p)
{
if(i == ElemPosition - 1)
{
DuElemType *TmpDelElem = p->NextPointer;
CopyDuElemTypeData(DelVarElem,p->NextPointer);
p->NextPointer->NextPointer->PriorPointer = p;
p->NextPointer = p->NextPointer->NextPointer;
free(TmpDelElem);
TmpDelElem = NULL;
break;
}
p = p->NextPointer;
i++;
}
L->ElemArrayLen--;
printf("Delete Data Success\n");
PrintPretty();
return SuccessFlag;
}
void DestroyDuLinkList(DuLinkList *L)
{
printf("Start Destroy Double Link List\n");
JudgeAllNullPointer(L);
DuElemType *p = L->ElemArray;
DuElemType *q = NULL;
while(p)
{
q = p->NextPointer;
free(p);
p = q;
if(p == L->ElemArray)
{
printf("Double Cycle Link List ");
break;
}
}
L->ElemArrayLen = 0;
free(L);
L = NULL;
printf("Destroy Success !!!\n");
PrintPretty();
}
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 StudentNumLen 8
#define StudentNameLen 8
typedef int Status;
typedef struct ElemType
{
char StudentNum[StudentNumLen];
char StudentName[StudentNameLen];
int StudentScore;
struct ElemType *NextPointer;
}ElemType;
typedef struct
{
ElemType *ElemArray;
int ElemArrayLen;
}LinkList;
typedef struct DuElemType
{
char StudentNum[StudentNumLen];
char StudentName[StudentNameLen];
int StudentScore;
struct DuElemType *PriorPointer;
struct DuElemType *NextPointer;
}DuElemType;
typedef struct
{
DuElemType *ElemArray;
int ElemArrayLen;
}DuLinkList;
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);
Status CopyElemTypeDataNoNextP(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);
Status DeleteLinkListElem(LinkList *L, int ElemPosition, ElemType *DelVarElem);
Status CreateHeadLinkList(LinkList *L, int LinkListLen);
Status CreateHeadLinkList_V1(LinkList *L, int LinkListLen);
Status CreateTailLinkList(LinkList *L, int LinkListLen);
Status CreateCycleLinkList(LinkList *L, int LinkListLen);
Status CreateCycleTailLinkList(LinkList *L, int LinkListLen);
Status UpdateCycleTailLinkListElem(LinkList *L, int Position, ElemType UpdateElem);
LinkList *Connect2CycleTailLinkList(LinkList *L1, LinkList *L2);
void JudgeAllNullPointer(void* P);
Status InitDuElemType(DuElemType *E);
Status InitDuLinkList(DuLinkList *L);
Status CmpDuElemType(DuElemType *E1, DuElemType *E2);
Status CopyDuElemTypeData(DuElemType *Dest, DuElemType *Src);
Status InsertDuLinkListElem(DuLinkList *L, int DuElemPosition, DuElemType DE);
void PrintDuLinkList(DuLinkList *L);
Status DeleteDuLinkListElem(DuLinkList *L, int ElemPosition, DuElemType *DelVarElem);
void DestroyDuLinkList(DuLinkList *L);
void ComputeProcedureTime(Status Func(LinkList *, int), LinkList *L, int LinkListLen);
void PrintPretty();
void PrintPretty_V1();
#endif
3、main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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);
ElemType *DelVarElem = (ElemType *)MyMalloc(sizeof(ElemType));
int i;
for(i=0; i<InsertDataArrayLen; i++)
{
InitElemType(&(InsertElemArray[i]));
strcpy(InsertElemArray[i].StudentNum ,"X666");
strcpy(InsertElemArray[i].StudentName,"Sun");
InsertElemArray[i].StudentScore = i + 100;
}
InitLinkList(L);
//PrintLinkList(L);
for(i=0; i<InsertDataArrayLen; i++)
{
InsertLinkListElem(L, 1, InsertElemArray[i]);
}
PrintLinkList(L);
GetLinkListElem(L, InsertDataArrayLen - 1, VarElem);
//PrintElemType(VarElem);
LocateElemPointer(L,*VarElem);
LocateElemPosition(L,*VarElem);
//PrintElemType(VarElem);
JudgeLinkListIsEmpty(L);
DeleteLinkListElem(L, InsertDataArrayLen, DelVarElem);
DeleteLinkListElem(L, InsertDataArrayLen / 2, DelVarElem);
DeleteLinkListElem(L, 1, DelVarElem);
PrintLinkList(L);
GetLinkListLen(L);
ClearLinkListElem(L);
//PrintLinkList(L);
DestroyLinkList(L);
free(VarElem);
//free(InsertElemArray);
free(DelVarElem);
L = NULL;
VarElem = NULL;
//InsertElemArray = NULL;
DelVarElem = NULL;
//测试单链表建立-头插法,尾插法
int LinkListLen = InsertDataArrayLen;
LinkList *H = (LinkList *)MyMalloc(sizeof(LinkList));
ComputeProcedureTime(CreateHeadLinkList,H, LinkListLen);
//PrintLinkList(H);
DestroyLinkList(H);
H = NULL;
LinkList *H1 = (LinkList *)MyMalloc(sizeof(LinkList));
ComputeProcedureTime(CreateHeadLinkList_V1,H1, LinkListLen);
//PrintLinkList(H1);
DestroyLinkList(H1);
H1 = NULL;
LinkList *H2 = (LinkList *)MyMalloc(sizeof(LinkList));
ComputeProcedureTime(CreateTailLinkList,H2, LinkListLen);
//PrintLinkList(H2);
DestroyLinkList(H2);
H2 = NULL;
//测试单链表建立-循环链表返回头指针
//循环链表只改造了PrintLinkList和DestroyLinkList,其他方法不一定适用。
LinkList *C = (LinkList *)MyMalloc(sizeof(LinkList));
CreateCycleLinkList(C, LinkListLen);
PrintLinkList(C);
DestroyLinkList(C);
C = NULL;
//测试单链表建立-尾指针循环链表
//循环链表只改造了PrintLinkList和DestroyLinkList,其他方法不一定适用。
LinkList *CT = (LinkList *)MyMalloc(sizeof(LinkList));
CreateCycleTailLinkList(CT, LinkListLen);
for(i=0; i<LinkListLen; i++)
{
UpdateCycleTailLinkListElem(CT, i+1, InsertElemArray[i]);
}
PrintLinkList(CT);
LinkList *CT1 = (LinkList *)MyMalloc(sizeof(LinkList));
CreateCycleTailLinkList(CT1, LinkListLen);
for(i=LinkListLen-1; i>=0; i--)
{
UpdateCycleTailLinkListElem(CT1, i+1, InsertElemArray[i]);
}
PrintLinkList(CT1);
//尾指针循环链表-两表链接
LinkList *CT2 = Connect2CycleTailLinkList(CT,CT1);
PrintLinkList(CT2);
DestroyLinkList(CT1);
CT1 = NULL;
DestroyLinkList(CT);
CT = NULL;
DestroyLinkList(CT2);
CT2 = NULL;
//双向循环链表
DuElemType *InsertDuElemArray = (DuElemType *)MyMalloc(sizeof(DuElemType) * InsertDataArrayLen);
DuElemType *DelVarDuElem = (DuElemType *)MyMalloc(sizeof(DuElemType));
for(i=0; i<InsertDataArrayLen; i++)
{
InitDuElemType(&(InsertDuElemArray[i]));
strcpy(InsertDuElemArray[i].StudentNum ,"X666");
strcpy(InsertDuElemArray[i].StudentName,"Sun");
InsertDuElemArray[i].StudentScore = i + 100;
}
DuLinkList *DL = (DuLinkList*)malloc(sizeof(DuLinkList));
InitDuLinkList(DL);
for(i=0; i<InsertDataArrayLen; i++)
{
InsertDuLinkListElem(DL, 1, InsertDuElemArray[i]);
}
PrintDuLinkList(DL);
DeleteDuLinkListElem(DL, InsertDataArrayLen, DelVarDuElem);
DeleteDuLinkListElem(DL, InsertDataArrayLen/2, DelVarDuElem);
DeleteDuLinkListElem(DL, 1, DelVarDuElem);
PrintDuLinkList(DL);
DestroyDuLinkList(DL);
free(InsertDuElemArray);
InsertDuElemArray = NULL;
free(InsertElemArray);
InsertElemArray = NULL;
free(DelVarDuElem);
DelVarDuElem = NULL;
return SuccessFlag;
}
4、makefile
CC = gcc
CFLAG_EXEC = -Wall -O3
CFLAG_ALIAS = -o
RM_COMM = rm -rf
all : main
main :
$(CC) $(CFLAG_EXEC) LinearTable_LinkList.c main.c $(CFLAG_ALIAS) Test_LinearTable_LinkList
clean :
$(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 LinkList Success
*********************************
Print Link List
Link List Pointer : 0x1e9f010
################
CurrentPointer : 0x1e9f160
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f280
################
CurrentPointer : 0x1e9f280
StudentNum : X666
StudentName : Sun
StudentScore : 105
NextPointer : 0x1e9f250
################
CurrentPointer : 0x1e9f250
StudentNum : X666
StudentName : Sun
StudentScore : 104
NextPointer : 0x1e9f220
################
CurrentPointer : 0x1e9f220
StudentNum : X666
StudentName : Sun
StudentScore : 103
NextPointer : 0x1e9f1f0
################
CurrentPointer : 0x1e9f1f0
StudentNum : X666
StudentName : Sun
StudentScore : 102
NextPointer : 0x1e9f1c0
################
CurrentPointer : 0x1e9f1c0
StudentNum : X666
StudentName : Sun
StudentScore : 101
NextPointer : 0x1e9f190
################
CurrentPointer : 0x1e9f190
StudentNum : X666
StudentName : Sun
StudentScore : 100
NextPointer : (nil)
################
ElemArrayLen : 6
*********************************
ElemPosition : 5 ,Get Data Success
*********************************
Locate Element Pointer
Pointer : 0x1e9f1c0
Locate Link List Elem Success
*********************************
Locate Element Position
Position : 5
Locate Link List Elem Success
*********************************
Link List Is Not Empty
*********************************
ElemPosition : 6
Delete Data Success
*********************************
ElemPosition : 3
Delete Data Success
*********************************
ElemPosition : 1
Delete Data Success
*********************************
Print Link List
Link List Pointer : 0x1e9f010
################
CurrentPointer : 0x1e9f160
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f250
################
CurrentPointer : 0x1e9f250
StudentNum : X666
StudentName : Sun
StudentScore : 104
NextPointer : 0x1e9f1f0
################
CurrentPointer : 0x1e9f1f0
StudentNum : X666
StudentName : Sun
StudentScore : 102
NextPointer : 0x1e9f1c0
################
CurrentPointer : 0x1e9f1c0
StudentNum : X666
StudentName : Sun
StudentScore : 101
NextPointer : (nil)
################
ElemArrayLen : 3
*********************************
Get Link List Len : 3
*********************************
Start Clear Link List Elem
Clear Link List Elem Success !!!
*********************************
Start Destroy Link List
Destroy Success !!!
*********************************
========================================
Create Empty Head Insert Link List Len : 6
Init LinkList Success
*********************************
Create Empty Head Insert Link List Success
*********************************
Elapsed Time : 0 s
Start Destroy Link List
Destroy Success !!!
*********************************
========================================
Create Empty Head Insert Link List Len : 6
Init LinkList Success
*********************************
Create Empty Head Insert Link List Success
*********************************
Elapsed Time : 0 s
Start Destroy Link List
Destroy Success !!!
*********************************
========================================
Create Empty Tail Insert Link List Len : 6
Init LinkList Success
*********************************
Create Empty Tail Insert Link List Success
*********************************
Elapsed Time : 0 s
Start Destroy Link List
Destroy Success !!!
*********************************
Create Empty Cycle Link List Len : 6
Init LinkList Success
*********************************
Create Empty Cycle Link List Success
*********************************
Print Link List
Link List Pointer : 0x1e9f010
################
CurrentPointer : 0x1e9f160
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f130
################
CurrentPointer : 0x1e9f130
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f220
################
CurrentPointer : 0x1e9f220
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f280
################
CurrentPointer : 0x1e9f280
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f250
################
CurrentPointer : 0x1e9f250
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f1f0
################
CurrentPointer : 0x1e9f1f0
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f1c0
################
CurrentPointer : 0x1e9f1c0
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f160
################
Cycle Link List Printf End
ElemArrayLen : 6
*********************************
Start Destroy Link List
Cycle Link List Destroy Success !!!
*********************************
Create Empty Cycle Tail Link List Len : 6
Init LinkList Success
*********************************
Create Empty Cycle Tail Link List Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
Print Link List
Link List Pointer : 0x1e9f010
################
CurrentPointer : 0x1e9f160
StudentNum : X666
StudentName : Sun
StudentScore : 105
NextPointer : 0x1e9f1c0
################
CurrentPointer : 0x1e9f1c0
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f1f0
################
CurrentPointer : 0x1e9f1f0
StudentNum : X666
StudentName : Sun
StudentScore : 100
NextPointer : 0x1e9f250
################
CurrentPointer : 0x1e9f250
StudentNum : X666
StudentName : Sun
StudentScore : 101
NextPointer : 0x1e9f280
################
CurrentPointer : 0x1e9f280
StudentNum : X666
StudentName : Sun
StudentScore : 102
NextPointer : 0x1e9f220
################
CurrentPointer : 0x1e9f220
StudentNum : X666
StudentName : Sun
StudentScore : 103
NextPointer : 0x1e9f130
################
CurrentPointer : 0x1e9f130
StudentNum : X666
StudentName : Sun
StudentScore : 104
NextPointer : 0x1e9f160
################
Cycle Link List Printf End
ElemArrayLen : 6
*********************************
Create Empty Cycle Tail Link List Len : 6
Init LinkList Success
*********************************
Create Empty Cycle Tail Link List Success
*********************************
Update Cycle Tail Link List Elem Success
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Update Cycle Tail Link List Elem Success
*********************************
Print Link List
Link List Pointer : 0x1e9f2b0
################
CurrentPointer : 0x1e9f390
StudentNum : X666
StudentName : Sun
StudentScore : 105
NextPointer : 0x1e9f030
################
CurrentPointer : 0x1e9f030
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f190
################
CurrentPointer : 0x1e9f190
StudentNum : X666
StudentName : Sun
StudentScore : 100
NextPointer : 0x1e9f2d0
################
CurrentPointer : 0x1e9f2d0
StudentNum : X666
StudentName : Sun
StudentScore : 101
NextPointer : 0x1e9f300
################
CurrentPointer : 0x1e9f300
StudentNum : X666
StudentName : Sun
StudentScore : 102
NextPointer : 0x1e9f330
################
CurrentPointer : 0x1e9f330
StudentNum : X666
StudentName : Sun
StudentScore : 103
NextPointer : 0x1e9f360
################
CurrentPointer : 0x1e9f360
StudentNum : X666
StudentName : Sun
StudentScore : 104
NextPointer : 0x1e9f390
################
Cycle Link List Printf End
ElemArrayLen : 6
*********************************
Connect 2 Cycle Tail Link List Success
*********************************
Print Link List
Link List Pointer : 0x1e9f3c0
################
CurrentPointer : 0x1e9f390
StudentNum : X666
StudentName : Sun
StudentScore : 105
NextPointer : 0x1e9f1c0
################
CurrentPointer : 0x1e9f1c0
StudentNum :
StudentName :
StudentScore : 0
NextPointer : 0x1e9f1f0
################
CurrentPointer : 0x1e9f1f0
StudentNum : X666
StudentName : Sun
StudentScore : 100
NextPointer : 0x1e9f250
################
CurrentPointer : 0x1e9f250
StudentNum : X666
StudentName : Sun
StudentScore : 101
NextPointer : 0x1e9f280
################
CurrentPointer : 0x1e9f280
StudentNum : X666
StudentName : Sun
StudentScore : 102
NextPointer : 0x1e9f220
################
CurrentPointer : 0x1e9f220
StudentNum : X666
StudentName : Sun
StudentScore : 103
NextPointer : 0x1e9f130
################
CurrentPointer : 0x1e9f130
StudentNum : X666
StudentName : Sun
StudentScore : 104
NextPointer : 0x1e9f160
################
CurrentPointer : 0x1e9f160
StudentNum : X666
StudentName : Sun
StudentScore : 105
NextPointer : 0x1e9f190
################
CurrentPointer : 0x1e9f190
StudentNum : X666
StudentName : Sun
StudentScore : 100
NextPointer : 0x1e9f2d0
################
CurrentPointer : 0x1e9f2d0
StudentNum : X666
StudentName : Sun
StudentScore : 101
NextPointer : 0x1e9f300
################
CurrentPointer : 0x1e9f300
StudentNum : X666
StudentName : Sun
StudentScore : 102
NextPointer : 0x1e9f330
################
CurrentPointer : 0x1e9f330
StudentNum : X666
StudentName : Sun
StudentScore : 103
NextPointer : 0x1e9f360
################
CurrentPointer : 0x1e9f360
StudentNum : X666
StudentName : Sun
StudentScore : 104
NextPointer : 0x1e9f390
################
Cycle Link List Printf End
ElemArrayLen : 12
*********************************
Start Destroy Link List
Destroy Success !!!
*********************************
Start Destroy Link List
Destroy Success !!!
*********************************
Start Destroy Link List
Cycle Link List Destroy Success !!!
*********************************
Init Double LinkList Success
*********************************
Insert DuElement
Insert Double Link List Elem Success
*********************************
Insert DuElement
Insert Double Link List Elem Success
*********************************
Insert DuElement
Insert Double Link List Elem Success
*********************************
Insert DuElement
Insert Double Link List Elem Success
*********************************
Insert DuElement
Insert Double Link List Elem Success
*********************************
Insert DuElement
Insert Double Link List Elem Success
*********************************
Print Link List
Link List Pointer : 0x1e9f3c0
################
CurrentPointer : 0x1e9f330
StudentNum :
StudentName :
StudentScore : 0
PriorPointer : 0x1e9f300
NextPointer : 0x1e9f220
################
CurrentPointer : 0x1e9f220
StudentNum : X666
StudentName : Sun
StudentScore : 105
PriorPointer : 0x1e9f330
NextPointer : 0x1e9f130
################
CurrentPointer : 0x1e9f130
StudentNum : X666
StudentName : Sun
StudentScore : 104
PriorPointer : 0x1e9f220
NextPointer : 0x1e9f160
################
CurrentPointer : 0x1e9f160
StudentNum : X666
StudentName : Sun
StudentScore : 103
PriorPointer : 0x1e9f130
NextPointer : 0x1e9f190
################
CurrentPointer : 0x1e9f190
StudentNum : X666
StudentName : Sun
StudentScore : 102
PriorPointer : 0x1e9f160
NextPointer : 0x1e9f2d0
################
CurrentPointer : 0x1e9f2d0
StudentNum : X666
StudentName : Sun
StudentScore : 101
PriorPointer : 0x1e9f190
NextPointer : 0x1e9f300
################
CurrentPointer : 0x1e9f300
StudentNum : X666
StudentName : Sun
StudentScore : 100
PriorPointer : 0x1e9f2d0
NextPointer : 0x1e9f330
################
Double Cycle Link List Printf End
ElemArrayLen : 6
*********************************
ElemPosition : 6
Delete Data Success
*********************************
ElemPosition : 3
Delete Data Success
*********************************
ElemPosition : 1
Delete Data Success
*********************************
Print Link List
Link List Pointer : 0x1e9f3c0
################
CurrentPointer : 0x1e9f330
StudentNum :
StudentName :
StudentScore : 0
PriorPointer : 0x1e9f2d0
NextPointer : 0x1e9f130
################
CurrentPointer : 0x1e9f130
StudentNum : X666
StudentName : Sun
StudentScore : 104
PriorPointer : 0x1e9f330
NextPointer : 0x1e9f190
################
CurrentPointer : 0x1e9f190
StudentNum : X666
StudentName : Sun
StudentScore : 102
PriorPointer : 0x1e9f130
NextPointer : 0x1e9f2d0
################
CurrentPointer : 0x1e9f2d0
StudentNum : X666
StudentName : Sun
StudentScore : 101
PriorPointer : 0x1e9f190
NextPointer : 0x1e9f330
################
Double Cycle Link List Printf End
ElemArrayLen : 3
*********************************
Start Destroy Double Link List
Double Cycle Link List Destroy Success !!!
*********************************