文章目录
声明:线性表的实现使用的是.cpp文件。
- 由于我使用的是vs2010,vs2010的编译器不支持函数返回值bool类型,并且不能这样定义for(int i= 0; i < 10; i++),必须在函数的开头声明i=0。为了编写的方便,我使用的是.cpp文件,没有使用.c文件。虽然是c++文件,但是内容是c语言。如果有需要.c文件的,请自行修改这两个地方就可以了。
1. 线性表的分类
* 按物理结构分
1. 线性表物理结构是顺序结构:称为顺序表
* 按数组是否动态分配
1. 数组动态分配的顺序表
2. 数组静态态分配的顺序表
2. 线性表物理结构是链式结构:称为链表
1. 单链表
2. 双向链表
3. 循环链表
1. 循环单链表
2. 循环双链表
* 注意:以上链表都可以分为带头结点和不带头结点两种。
2. 数组静态分配的顺序表
2.1 目录结构
2.2 SeqList.h
//声明顺序表的最大长度
#define MAX_ISZE 255
// 1. 定义数据元素
typedef struct {
int age;
char * name;
} ElemType;
// 2. 定义顺序表
typedef struct {
ElemType datas[MAX_ISZE];
int length;
} SeqList;
/**
* func:初始化顺序表
* @seqList:顺序表
*/
void initSeqList(SeqList * seqList);
/**
* func:销毁顺序表
* @seqList:顺序表
*/
void destroySeqList(SeqList * seqList);
/**
* func:返回顺序表的长度
* @seqList:顺序表
*/
int length(SeqList * seqList);
/**
* func:定义在指定下标处添加元素
* @seqList:顺序表
* @index:指定的下标
* @elemType:要插入的元素
*/
bool insertElem(SeqList * seqList, int index, ElemType elemType);
/**
* func:定义删除指定下标的元素
* @seqList:顺序表
* @index:指定的下标
* return: 返回删除的元素
*/
bool deleteElem(SeqList * seqList, int index, ElemType * x);
/**
* func:定义修改某个下标的元素
* @seqList:顺序表
* @index:指定的下标
* @elemType:要修改成的元素
*/
bool updateElem(SeqList * seqList, int index, ElemType elemType);
/**
* func:定义查找某个下标的元素
* @seqList:顺序表
* @index:指定的下标
*/
bool selectElem(SeqList * seqList, int index, ElemType * x);
/**
* func:打印顺序表的所有元素
* @seqList:顺序表
* @index:指定的下标
*/
void printfSeqList(SeqList * seqList);
/**
* func:打印一个ElemType类型的元素
* @elem:要打印的元素
*/
void printElem(ElemType elem);
2.3 SeqList.cpp
#include <stdio.h>
#include <stdlib.h>
#include "SeqList.h"
/**
* func:初始化链表,将一个数组的所有数据放入一个链表中
* @seqList:顺序表
* @elemArray:存放数据的数组
* @length:elemArray数组存放数据的长度
*/
void initSeqList(SeqList * seqList) {
//将顺序表的长度设置为0,否则回随机分配个值
seqList->length = 0;
}
/**
* func:销毁顺序表
* @seqList:顺序表
*/
void destroySeqList(SeqList * seqList) {
// 由于静态数组无法手动释放,所以将顺序表长度置为0表示释放顺序表
seqList->length = 0;
}
/**
* func:返回顺序表的长度
* @seqList:顺序表
*/
int length(SeqList * seqList) {
return seqList->length;
}
/**
* func:定义在指定下标处添加元素
* @seqList:顺序表
* @index:指定的下标
* @elemType:要插入的元素
*/
bool insertElem(SeqList * seqList, int index, ElemType elemType) {
// 1. 判断传入的下标是否合法
if (index<0 || index>=MAX_ISZE) {
printf("您传入的下标越界!\n");
return false;
}
// 2. 判断顺序表空间是否还足够
if (seqList->length+1 > MAX_ISZE) {
printf("链表空间不足!\n");
return false;
}
// 3. 将index的后续元素后移
for (int i = seqList->length-1; i >= index; i--) {
seqList->datas[i+1] = seqList->datas[i];
}
// 4. 修改index处的数据元素
seqList->datas[index] = elemType;
// 5. 顺序表长度加1
seqList->length++;
return true;
}
/**
* func:定义删除指定下标的元素
* @seqList:顺序表
* @index:指定的下标
* return: 返回删除的元素
*/
bool deleteElem(SeqList * seqList, int index, ElemType * x) {
// 1. 判断传入的下标是否合法
if (index<0 || index>=MAX_ISZE) {
printf("您传入的下标越界!\n");
return false;
}
// 2. 判断顺序表是否为空
if (0 == length(seqList)) {
printf("顺序表为空,无法删除元素!\n");
return false;
}
// 3. 存放要删除的元素
*x = seqList->datas[index];
// 4. 将index的后续元素前移
for (int i = index; i < seqList->length-1; i++) {
seqList->datas[i] = seqList->datas[i+1];
}
// 5. 线性表长度减1
seqList->length--;
return true;
}
/**
* func:定义修改某个下标的元素
* @seqList:顺序表
* @index:指定的下标
* @elemType:要修改成的元素
*/
bool updateElem(SeqList * seqList, int index, ElemType elemType) {
// 1. 判断传入的下标是否合法
if (index<0 || index>=MAX_ISZE) {
printf("您传入的下标越界!\n");
return false;
}
// 2. 判断顺序表是否为空
if (0 == length(seqList)) {
printf("顺序表为空,无法更改元素!\n");
return false;
}
// 3. 修改顺序表index处的元素
seqList->datas[index] = elemType;
return true;
}
/**
* func:定义查找某个下标的元素
* @seqList:顺序表
* @index:指定的下标
*/
bool selectElem(SeqList * seqList, int index, ElemType * x) {
// 1. 判断传入的下标是否合法
if (index<0 || index>=MAX_ISZE) {
printf("您传入的下标越界!\n");
return false;
}
// 2. 判断顺序表是否为空
if (0 == length(seqList)) {
printf("顺序表为空,无法更改元素!\n");
return false;
}
*x = seqList->datas[index];
return true;
}
/**
* func:打印顺序表的所有元素
* @seqList:顺序表
* @index:指定的下标
*/
void printfSeqList(SeqList * seqList) {
for (int i = 0; i < seqList->length; i++) {
printElem(seqList->datas[i]);
}
}
/**
* func:打印一个ElemType类型的元素
* @elem:要打印的元素
*/
void printElem(ElemType elem) {
printf("姓名:%s, 年龄:%d\n", elem.name, elem.age);
}
2.4 main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "SeqList.h"
void main() {
ElemType temp;
ElemType elemArray[10];
// 声明顺序表
SeqList seqList;
// 初始化顺序表
initSeqList(&seqList);
// 构造数组元素
elemArray[0].name = "张三";
elemArray[0].age = 13;
elemArray[1].name = "李四";
elemArray[1].age = 14;
elemArray[2].name = "王五";
elemArray[2].age = 15;
//为顺序表增加一些值
printf("[##############在顺序表的0,1,2位置插入元素##############]\n");
insertElem(&seqList, 0, elemArray[0]);
insertElem(&seqList, 1, elemArray[1]);
insertElem(&seqList, 2, elemArray[2]);
printfSeqList(&seqList);
printf("当前顺序表长度为:%d\n", length(&seqList));
//删
printf("[###################删除index=1元素###################]\n");
deleteElem(&seqList, 1, &temp);
printf("删除的元素为:\n");
printElem(temp);
printf("顺序表元素为:\n");
printfSeqList(&seqList);
//改
printf("[###################更改index=0元素###################]\n");
temp.name = "帅帅";
temp.age = 20;
updateElem(&seqList, 0, temp);
printf("顺序表元素为:\n");
printfSeqList(&seqList);
//查
printf("[###################查看index=1元素###################]\n");
selectElem(&seqList, 1, &temp);
printElem(temp);
//销毁顺序表
destroySeqList(&seqList);
}
2.5 程序运行结果
2.6 几个注意点
- 由于静态数组无法手动释放,所以在销毁顺序表的函数中,将顺序表长度置为0表示释放顺序表。
- 使用顺序表时,每声明一个顺序表都需要及时的初始化顺序表。(将length置为0)
- 元素的删除和添加时要及时的修改顺序表长度。
- 在进行元素的删除和添加时有一个小结论,顺序表需要移动的元素,是从元素移动的方向开始移动。
- 顺序表添加元素示意图:
- 顺序表删除元素示意图:
3. 数组动态分配的顺序表
3.1 项目结构
3.2 SeqList.h
//声明顺序表的最大长度
#define MAX_ISZE 2
// 1. 定义数据元素
typedef struct {
int age;
char * name;
} ElemType;
// 2. 定义顺序表
typedef struct {
ElemType * datas;
int length;
} SeqList;
/**
* func:初始化顺序表
* @seqList:顺序表
*/
void initSeqList(SeqList * seqList);
/**
* func:销毁顺序表
* @seqList:顺序表
*/
void destroySeqList(SeqList * seqList);
/**
* func:动态的扩充顺序表的容量,每次扩充是上次容量的两倍
* @seqList:顺序表
*/
void enlarge(SeqList * seqList);
/**
* func:定义在指定下标处添加元素
* @seqList:顺序表
* @index:指定的下标
* @elemType:要插入的元素
*/
bool insertElem(SeqList * seqList, int index, ElemType elemType);
/**
* func:定义删除指定下标的元素
* @seqList:顺序表
* @index:指定的下标
*/
bool deleteElem(SeqList * seqList, int index, ElemType * x);
/**
* func:定义修改某个下标的元素
* @seqList:顺序表
* @index:指定的下标
* @elemType:要修改成的元素
*/
bool updateElem(SeqList * seqList, int index, ElemType elemType);
/**
* func:定义查找某个下标的元素
* @seqList:顺序表
* @index:指定的下标
*/
bool selectElem(SeqList * seqList, int index, ElemType * x);
/**
* func:打印顺序表的所有元素
* @seqList:顺序表
* @index:指定的下标
*/
void printfSeqList(SeqList * seqList);
/**
* func:打印一个ElemType类型的元素
* @elem:要打印的元素
*/
void printElem(ElemType elem);
/**
* func:返回顺序表的长度
* @seqList:顺序表
*/
int length(SeqList * seqList);
3.3 SeqList.cpp
#include <stdio.h>
#include <stdlib.h>
#include "SeqList.h"
/**
* func:初始化链表,将一个数组的所有数据放入一个链表中
* @seqList:顺序表
* @elemArray:存放数据的数组
* @length:elemArray数组存放数据的长度
*/
void initSeqList(SeqList * seqList) {
// 将顺序表的长度设置为0,否则回随机分配个值
seqList->length = 0;
// 为顺序表动态分配数组
seqList->datas = (ElemType *)malloc(MAX_ISZE * sizeof(ElemType));
}
/**
* func:销毁顺序表
* @seqList:顺序表
*/
void destroySeqList(SeqList * seqList) {
seqList->length = 0;
if (seqList->datas != NULL) {
free(seqList->datas);
seqList->datas = NULL;
}
}
/**
* func:返回顺序表的长度
* @seqList:顺序表
*/
int length(SeqList * seqList) {
return seqList->length;
}
/**
* func:动态的扩充顺序表的容量,每次扩充是上次容量的两倍
* @seqList:顺序表
*/
void enlarge(SeqList * seqList) {
ElemType * temp = seqList->datas;
// 动态开辟空间为原来两倍的数组
printf("空间不够,分配一次空间,大小为:%d\n", seqList->length * 2);
seqList->datas = (ElemType *)malloc(seqList->length * 2 * sizeof(ElemType));
// 将元素复制到新的数组中
for(int i = 0; i < seqList->length; i++)
seqList->datas[i] = temp[i];
// 手动释放数组内存
free(temp);
temp = NULL;
}
/**
* func:定义在指定下标处添加元素
* @seqList:顺序表
* @index:指定的下标
* @elemType:要插入的元素
*/
bool insertElem(SeqList * seqList, int index, ElemType elemType) {
// 1. 判断传入的下标是否合法
if (index<0 || index>MAX_ISZE) {
printf("您传入的下标越界!\n");
return false;
}
// 2. 判断顺序表空间是否还足够
if (seqList->length+1 > MAX_ISZE) {
//顺序表空间不足,动态开辟数组
enlarge(seqList);
}
// 3. 将index的后续元素后移
for (int i = seqList->length-1; i >= index; i--) {
seqList->datas[i+1] = seqList->datas[i];
}
// 4. 修改index处的数据元素
seqList->datas[index] = elemType;
// 5. 顺序表长度加+
seqList->length++;
return true;
}
/**
* func:定义删除指定下标的元素
* @seqList:顺序表
* @index:指定的下标
* @x:记录要删除的元素
*/
bool deleteElem(SeqList * seqList, int index, ElemType * x) {
// 1. 判断传入的下标是否合法
if (index<0 || index>=MAX_ISZE) {
printf("您传入的下标越界!\n");
return false;
}
// 2. 判断顺序表是否为空
if (0 == length(seqList)) {
printf("顺序表为空!\n");
return false;
}
// 3. 存放要删除的元素
*x = seqList->datas[index];
// 3. 将index的后续元素前移
for (int i = index; i < seqList->length-1; i++) {
seqList->datas[i] = seqList->datas[i+1];
}
// 4. 线性表长度加1
seqList->length--;
return true;
}
/**
* func:定义修改某个下标的元素
* @seqList:顺序表
* @index:指定的下标
* @elemType:要修改成的元素
*/
bool updateElem(SeqList * seqList, int index, ElemType elemType) {
// 1. 判断传入的下标是否合法
if (index<0 || index>=MAX_ISZE) {
printf("您传入的下标越界!\n");
return false;
}
// 2. 判断顺序表是否为空
if (0 == length(seqList)) {
printf("顺序表为空, 无法更改元素!\n");
return false;
}
// 2. 修改顺序表index处的元素
seqList->datas[index] = elemType;
return true;
}
/**
* func:定义查找某个下标的元素
* @seqList:顺序表
* @index:指定的下标
*/
bool selectElem(SeqList * seqList, int index, ElemType * x) {
// 1. 判断传入的下标是否合法
if (index<0 || index>=MAX_ISZE) {
printf("您传入的下标越界!\n");
return false;
}
// 2. 判断顺序表是否为空
if (0 == length(seqList)) {
printf("顺序表为空, 无法查看元素!\n");
return false;
}
*x = seqList->datas[index];
return true;
}
/**
* func:打印顺序表的所有元素
* @seqList:顺序表
* @index:指定的下标
*/
void printfSeqList(SeqList * seqList) {
for (int i = 0; i < seqList->length; i++) {
printElem(seqList->datas[i]);
}
}
/**
* func:打印一个ElemType类型的元素
* @elem:要打印的元素
*/
void printElem(ElemType elem) {
printf("姓名:%s, 年龄:%d\n", elem.name, elem.age);
}
3.4 main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "SeqList.h"
void main() {
ElemType temp;
ElemType elemArray[10];
// 声明顺序表
SeqList seqList;
// 初始化顺序表
initSeqList(&seqList);
// 构造数组元素
elemArray[0].name = "张三";
elemArray[0].age = 13;
elemArray[1].name = "李四";
elemArray[1].age = 14;
elemArray[2].name = "王五";
elemArray[2].age = 15;
//为顺序表增加一些值
printf("[##############在顺序表的0,1,2位置插入元素##############]\n");
insertElem(&seqList, 0, elemArray[0]);
insertElem(&seqList, 1, elemArray[1]);
insertElem(&seqList, 2, elemArray[2]);
printfSeqList(&seqList);
printf("当前顺序表长度为:%d\n", length(&seqList));
//删
printf("[###################删除index=1元素###################]\n");
deleteElem(&seqList, 1, &temp);
printf("删除的元素为:\n");
printElem(temp);
printf("顺序表元素为:\n");
printfSeqList(&seqList);
//改
printf("[###################更改index=0元素###################]\n");
temp.name = "帅帅";
temp.age = 20;
updateElem(&seqList, 0, temp);
printf("顺序表元素为:\n");
printfSeqList(&seqList);
//查
printf("[###################查看index=1元素###################]\n");
selectElem(&seqList, 1, &temp);
printElem(temp);
//销毁顺序表
destroySeqList(&seqList);
}
3.5 运行结果
3.6 几个注意点
1. 补充一些动态分配内存的一些知识。
1. 使用malloc()函数可以动态在堆中分配内存,这些动态分配的内存只有两种情况下被释放:
1. 手动使用free()函数释放。
2. 程序结束时才会释放。
2. free()函数用来手动释放堆内存,其有几个需要注意的地方:
1. free()函数只能释放动态分配的内存。如果是静态的,比如int a[2] = {1, 2, 3}, 就不能使用free(a)释放。
2. 如果将动态分配后地址的首地址给free(),他会将以这个地址为首的动态分配的地址全释放。
比如动态分配了一个数组 int * a = (int *)malloc(sizeof(int)*3); 使用free(a);
会将整个数组的内存全释放,而不是只释放一个单元。
2. 结构体变量间能够直接赋值,像基本类型一样。
ElemType a, b; //ElemType是结构体引用类型
a.age = 15;
a.name = "张三";
b = a; //可以这样
3. 使用malloc时,一定要注意后边是前边的整数倍。
数组动态分配的顺序表与数组静态分配的顺序表差别不大,主要是在初始化、顺序表的释放以及空间不足时,处理的方法不一样。其他都一样。
4. 单链表的实现(带头结点)
4.1 项目结构
4.2 LinkList.h
// 定义抽象数据类型
typedef struct {
char name[20];
int age;
}ElemType;
// 定义结点
typedef struct LNode{
ElemType data;
struct LNode * next;
} LNode;
// 定义链表
typedef struct {
int length;
struct LNode head;
} LinkList;
/**
* func:初始化链表
* @linkList:链表头结点
*/
void initLinkList(LinkList * linkList);
/**
* func:释放链表
* @linkList:链表头结点
*/
void destroyList(LinkList * linkList);
/**
* func:在给定某节点的地址,在该节点的后面插入元素(后插)
* @index:给定某节点的地址
* @node:要插入的结点的地址
*/
void beforeInsertNode(LinkList * linkList, LNode * index, LNode * node);
/**
* func:在给定某节点的地址,在该节点的前面插入元素(前插)
* @index:给定某节点的地址
* @node:要插入的结点的地址
*/
void afterInsertNode(LinkList * linkList, LNode * index, LNode * node);
/**
* func:在链表末尾添加结点
* @node:要插入的结点的地址
*/
void insertNode(LinkList * linkList, LNode * node);
/**
* func:申请一个结点,并完善该节点的消息
*/
LNode * applyNode();
/**
* func:删除链表指定下标的元素
* @linkList:链表头结点
* @node:要删除的节点的地址
*/
void deleteNode(LinkList * linkList, LNode * node);
/**
* func:修改某节点的内容
* @node:要修改的节点的地址
*/
void updateNode(LNode * node);
/**
* func:判断两个结点的数据部分是否相等
* @node1:要判断的结点的地址
* @node2:要判断的结点的地址
*/
bool isEqual(LNode * node1, LNode * node2);
/**
* func:查找某个节点的位置,返回其地址
* @linkList:链表头结点
*/
LNode * selectNode(LinkList * linkList);
/**
* func:得到链表的长度
* @linkList:链表头结点
*/
int getLength(LinkList * linkList);
/**
* func:判断链表是否为空
* @linkList:链表头结点
*/
bool isEmpty(LinkList * linkList);
/**
* func:打印某个结点信息
* @node:要打印的链表的结点
*/
void printfNode(LNode * node);
/**
* func:打印整个链表的信息
* @linkList:链表头结点
*/
void printfLinkList(LinkList * linkList);
4.3 LinkList.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LinkList.h"
/**
* func:初始化链表
* @linkList:链表头结点
*/
void initLinkList(LinkList * linkList) {
linkList->length = 0;
linkList->head.next = NULL;
}
/**
* func:释放链表
* @linkList:链表头结点
*/
void destroyList(LinkList * linkList) {
// 用一个指针指向头结点
LNode * temp = NULL;
LNode * p = &linkList->head;
// 如果链表不为空,则让其到第一个结点
if (p->next != NULL)
p = p->next;
// 遍历链表,释放结点
while (p->next != NULL) {
p = p->next;
temp = p;
free(temp);
}
linkList->length = 0;
}
/**
* func:在给定某节点的地址,在该节点的后面插入元素(后插)
* @index:给定某节点的地址
* @node:要插入的结点的地址
*/
void afterInsertNode(LinkList * linkList, LNode * index, LNode * node) {
node->next = index->next;
index->next = node;
// 链表长度加1
linkList->length++;
}
/**
* func:在给定某节点的地址,在该节点的前面插入元素(前插)
* @index:给定某节点的地址
* @node:要插入的结点的地址
*/
void beforeInsertNode(LinkList * linkList, LNode * index, LNode * node) {
// 先交换数据
ElemType temp;
temp = index->data;
index->data = node->data;
node->data = temp;
//再利用尾插
afterInsertNode(linkList, index, node);
}
/**
* func:在链表末尾添加结点
* @node:要插入的结点的地址
*/
void insertNode(LinkList * linkList, LNode * node) {
LNode * p = &linkList->head;
// 找到最后一个结点
while (p->next != NULL)
p = p->next;
p->next = node;
// 链表长度加1
linkList->length++;
}
/**
* func:申请一个结点,并完善该节点的消息
*/
LNode * applyNode() {
LNode * node = (LNode *)malloc(sizeof(LNode));
node->next = NULL;
printf("正在开辟一个新的结点...\n");
printf("请输入姓名:");
scanf("%s", node->data.name);
printf("请输入年龄:");
scanf("%d", &node->data.age);
printf("新结点开辟成功!\n");
return node;
}
/**
* func:删除链表中指定结点地址的元素
* @linkList:链表头结点
* @node:要删除的节点的地址
*/
void deleteNode(LinkList * linkList, LNode * node) {
LNode * t;
// 交换元素
ElemType temp;
temp = node->data;
node->data = node->next->data;
node->next->data = temp;
// 删除结点
t = node->next;
node->next = t->next;
free(t);
// 链表长度减1
linkList->length--;
}
/**
* func:修改某节点的内容
* @node:要修改的节点的地址
*/
void updateNode(LNode * node) {
printf("正在修改一个结点...\n");
printf("原姓名为:%s\n请输入新的姓名:", node->data.name);
scanf("%s", node->data.name);
printf("原年龄为:%d\n请输入年龄:", node->data.age);
scanf("%d", &node->data.age);
printf("结点修改成功!\n");
}
/**
* func:判断两个结点的数据部分是否相等
* @node1:要判断的结点的地址
* @node2:要判断的结点的地址
*/
bool isEqual(LNode * node1, LNode * node2) {
if (strcmp(node1->data.name, node2->data.name) == 0 && node1->data.age == node2->data.age)
return true;
else
return false;
}
/**
* func:查找某个节点的位置,返回其地址
* @linkList:链表头结点
*/
LNode * selectNode(LinkList * linkList) {
// 先接受用户信息
LNode node;
printf("请输入要查找的姓名:");
scanf("%s", node.data.name);
printf("请输入要查找的年龄:");
scanf("%d", &node.data.age);
LNode * p = &linkList->head;
while (p->next != NULL) {
p = p->next;
if (isEqual(p, &node))
return p;
}
return NULL;
}
/**
* func:得到链表的长度
* @linkList:链表头结点
*/
int getLength(LinkList * linkList) {
return linkList->length;
}
/**
* func:判断链表是否为空
* @linkList:链表头结点
*/
bool isEmpty(LinkList * linkList) {
if (linkList->length >0) //或者 linkList->head.next != NULL
return false;
else
return true;
}
/**
* func:打印某个结点信息
* @node:要打印的链表的结点
*/
void printfNode(LNode * node) {
printf("\t姓名:%s\t年龄:%d\n", node->data.name, node->data.age);
}
/**
* func:打印整个链表的信息
* @linkList:链表头结点
*/
void printfLinkList(LinkList * linkList) {
LNode * p = &linkList->head;
int i = 1;
while (p->next != NULL) {
p = p->next;
printf("第%d个结点信息为:", i);
printfNode(p);
i++;
}
}
4.4 main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"
void main() {
// 声明并初始化链表
LinkList linkList;
initLinkList(&linkList);
// 开辟三个结点
for (int i = 0; i < 3; i++) {
insertNode(&linkList, applyNode());
}
printfLinkList(&linkList);
int length = getLength(&linkList);
printf("链表的长度为%d\n", length);
// 开辟一个结点,分别前插在某个元素的前面
LNode * t1 = applyNode();
LNode * index = selectNode(&linkList); // 查看元素
beforeInsertNode(&linkList, index, t1);
printfLinkList(&linkList);
length = getLength(&linkList);
printf("链表的长度为%d\n", length);
//开辟一个结点,分别尾插在某个元素的后面
LNode * t2 = applyNode();
index = selectNode(&linkList); // 查看元素
afterInsertNode(&linkList, index, t2);
printfLinkList(&linkList);
length = getLength(&linkList);
printf("链表的长度为%d\n", length);
// 更改index结点
updateNode(index);
printfLinkList(&linkList);
length = getLength(&linkList);
printf("链表的长度为%d\n", length);
// 删除index结点
deleteNode(&linkList, index);
printfLinkList(&linkList);
length = getLength(&linkList);
printf("链表的长度为%d\n", length);
// 释放链表
destroyList(&linkList);
}