文章目录
1.1 线性表的顺序存储
1.1.1 线性表的实现 — 静态分配
功能 | 说明 |
---|---|
initSqList(SeqList *L) | 初始化顺序表 |
ListInsert(SeqList *L,int i,int e) | 插入(在顺序表L中的第i个位置插入e) |
ListDelete(SeqList *L,int i,int *e) | 删除(删除顺序表L中的第i个元素并利用传过来的变量 *e 返回删除的数据) |
GetElem(SeqList &L,int i) | 按位查找(查找顺序表L的第i个元素) |
LocateElem(SeqList *L, int e) | 按值查找(在顺序表L中查找e,并返回其位序) |
printSeqList(SeqList *L) | 打印顺序表 |
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxLength 10 // 设置数组的最大长度为 10
// 定义一个顺序表结构体
typedef struct{
int data[MaxLength];
int length; // 记录顺序表当前的长度
}SeqList;
// 基本功能————初始化顺序表
void initSeqList(SeqList *L){
L->length = 0;
}
// 基本功能————插入(在顺序表L中的第i个位置插入e)
void ListInsert(SeqList *L,int i,int e){
if (i<1 || i>L->length + 1){
printf("位序i不合法,插入错误!");
}else if (L->length >= MaxLength){
printf("当前存储容量已满,不能插入!");
}else {
for(int j = L->length - 1;j >= i - 1;j--)
L->data[j + 1] = L->data[j];
L->data[i-1] = e;
(*L).length++;
printf("插入成功!\n");
}
}
// 基本功能————删除(删除顺序表L中的第i个元素并利用传过来的变量 *e 返回删除的数据)
int ListDelete(SeqList *L,int i,int *e){
if (i<1 || i>L->length + 1){
return 0;
}
*e = L->data[i-1];
for(int j = i;j<L->length;j++)
L->data[j-1] = L->data[j];
(*L).length--;
return 1;
}
// 基本功能————按位查找(查找顺序表L的第i个元素)
int GetElem(SeqList *L,int i){
if (i<1 || i>L->length + 1){
printf("不存在该位置的元素!");
return 0;
}
return L->data[i - 1];
}
// 基本功能————按值查找(在顺序表L中查找e,并返回其位序)
int LocateElem(SeqList *L, int e){
for(int i = 0; i < L->length; i++){
if(L->data[i] == e)
return i + 1;
return 0;
}
}
// 基本功能————打印顺序表
void printSeqList(SeqList *L){
// 尝试违规读取顺序表中的所有数据
// for(int i = 0;i<MaxLength;i++){
// printf("data[%d]=%d\n", i, L->data[i]);
// }
for(int i = 0;i < L->length;i++){
printf("data[%d]=%d\n", i, L->data[i]);
}
}
int main(){
SeqList L; // 声明一个顺序表
initSeqList(&L); // 初始化顺序表
ListInsert(&L,1,100);
ListInsert(&L,2,98);
ListInsert(&L,3,50);
printSeqList(&L); // 打印顺序表
int e = -1;
if(ListDelete(&L,1,&e) == 1){
printf("删除的数据为%d\n",e);
}else{
printf("位序i不合法,删除错误!");
}
printf("%d是第%d个数据\n",98,LocateElem(&L , 98));
printSeqList(&L); // 打印顺序表
}
1.1.2 线性表的实现 — 动态分配
功能 | 说明 |
---|---|
initSeqList(SeqList *L) | 初始化顺序表 |
IncreaseSize(SeqList *L, int len) | 动态添加数组的长度 |
ListInsert(SeqList *L,int i,int e) | 插入(在顺序表L中的第i个位置插入e) |
ListDelete(SeqList *L,int i,int *e) | 删除(删除顺序表L中的第i个元素并利用传过来的变量 *e 返回删除的数据) |
GetElem(SeqList *L,int i) | 按位查找(查找顺序表L的第i个元素) |
LocateElem(SeqList *L, int e) | 按值查找(在顺序表L中查找e,并返回其位序) |
printSeqList(SeqList *L) | 打印顺序表 |
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define InitLength 10 // 设置初始数组的长度为 10
// 定义一个顺序表结构体
typedef struct {
int* data; // 指向动态分配数组的指针
int MaxLength; // 顺序表的最大长度
int length; // 记录顺序表当前的长度
}SeqList;
// 基本功能————初始化顺序表
void initSeqList(SeqList *L){
L->data = (int*)malloc(InitLength * sizeof(int)); // 动态分配数组的空间 (10个)
L->length = 0;
L->MaxLength = InitLength;
}
// 动态添加数组的长度
void IncreaseSize(SeqList *L, int len){
int* p = L->data; // 定义一个指针 p 指向指针 data 所指向的位置
L->data = (int*)malloc((L->MaxLength+len)*sizeof(int)); // 分配新的内存空间,并让指针 data 指向它
for(int i = 0 ; i < L->length ; i++){
// L->data[i] = p[i]; // 将数据复制到新区域
*(L->data+i) = *(p + i); // 与上面的一句话是等价的
// 理解:
// 数组 a[] 中 a 就是一个指针,一个指向数组首地址的不能更改的常量指针
// 所以当一个指针指向数组后,那么相当于这个数组有了一个新的名字
// 即 a[] 等价于 p[]
}
L->MaxLength += len;
free(p);
}
// 基本功能————插入(在顺序表L中的第i个位置插入e)
void ListInsert(SeqList *L,int i,int e){
if (i<1 || i>L->length + 1){
printf("位序i不合法,插入错误!");
}else if (L->length >= L->MaxLength){
printf("当前存储容量已满,不能插入!");
}else {
for(int j = L->length - 1;j >= i - 1;j--)
L->data[j + 1] = L->data[j];
L->data[i-1] = e;
(*L).length++;
printf("插入成功!\n");
}
}
// 基本功能————删除(删除顺序表L中的第i个元素并利用传过来的变量 *e 返回删除的数据)
int ListDelete(SeqList *L,int i,int *e){
if (i<1 || i>L->length + 1){
return 0;
}
*e = L->data[i-1];
for(int j = i;j<L->length;j++)
L->data[j-1] = L->data[j];
(*L).length--;
return 1;
}
// 基本功能————按位查找(查找顺序表L的第i个元素)
int GetElem(SeqList *L,int i) {
if (i<1 || i>L->length + 1){
return 0;
}
return L->data[i - 1];
}
// 基本功能————按值查找(在顺序表L中查找e,并返回其位序)
int LocateElem(SeqList *L, int e){
for(int i = 0; i < L->length; i++){
if(L->data[i] == e)
return i + 1;
return 0;
}
}
// 基本功能————打印顺序表
void printSeqList(SeqList *L){
// 尝试违规读取顺序表中的所有数据
// for(int i = 0;i<L->MaxLength;i++){
// printf("data[%d]=%d\n", i, L->data[i]);
// }
for(int i = 0;i < L->length;i++){
printf("data[%d]=%d\n", i, L->data[i]);
}
}
int main(){
SeqList L; // 声明一个顺序表
initSeqList(&L); // 初始化顺序表
IncreaseSize(&L , 5); // 扩容
ListInsert(&L , 1 , 123); // 插入数据
ListInsert(&L , 2 , 78);
ListInsert(&L , 3 , 98);
int e = -1; // 删除元素
ListDelete(&L , 2 , &e);
printf("删除的元素是:%d\n", e);
printSeqList(&L); // 打印顺序表
}
1.2 线性表的链式存储
1.2.1 单链表
1.2.1.1 带头节点的单链表
功能 | 说明 |
---|---|
InitList(LinkList *L) | 初始化**(有区别)** |
Empty(LinkList L) | 判断单链表是否为空**(有区别)** |
ListInsert(LinkList L, int i, int e) | 按位序插入(在 L 的第 i 个节点插入元素 e)(有区别) |
ListDelete(LinkList L, int i) | 按位序删除(删除表 L 中的第 i 个节点的元素)(有区别) |
GetElem(LinkList L, int i) | 按位查找(返回表 L 中的第 i 个节点的元素)(有区别) |
LocateElem(LinkList L, int e) | 按值查找(返回表 L 中的存储着e的元素)(有区别) |
Length(LinkList L) | 求表的长度**(有区别)** |
PrintList(LinkList L) | 打印单链表 |
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct LNode{
// 定义一个单链表的节点类型
int data; // 每个节点的数据域
struct LNode* next; // 每个节点的指针域,指针指向下一个节点
}LNode, *LinkList;
// LNode* 强调的是节点 LinkList 强调的是单链表
// 初始化(带头节点)
void InitList(LinkList *L){
*L = (LNode*)malloc(sizeof(LNode)); // 分配一个头节点 (头节点是不存储数据的)
if(*L == NULL){
printf("分配空间失败!\n");
}else{
(*L)->next = NULL;
printf("分配空间成功!\n");
}
}
// 判断单链表是否为空(带头节点)
void Empty(LinkList L){
if (L->next == NULL){
printf("单链表为空!\n");
}else{
printf("单链表不为空!\n");
}
}
// 按位序插入(带头节点)
// 在 L 的第 i 个节点插入元素 e
void ListInsert(LinkList L, int i, int e){
// 如果要插入的位置小于1则报错
if(i<1){
printf("位序i不合法,插入错误!");
exit(1);
}
LNode* p = L; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 0; // 记录当前p指向的是第几个节点
while(p != NULL && j < i - 1){
// 找到插入的位置
p = p->next;
j++;
}
// 如果要插入的位置大于 L 的实际长度,则报错
if (p == NULL){
printf("位序i不合法,插入错误!");
exit(1);
}
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL){
printf("分配空间失败!!!");
exit(1);
}
s->data = e; // 插入元素
s->next = p->next;
p->next = s;
printf("插入成功!\n");
}
// 按位序删除(带头节点)
// 删除表 L 中的第 i 个节点的元素
void ListDelete(LinkList L, int i){
// 如果要删除的位置小于1则报错
if(i<1){
printf("位序i不合法,删除错误!");
exit(1);
}
LNode* p = L; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 0; // 记录当前p指向的是第几个节点
while(p != NULL && j < i - 1){
// 找要删除的元素的前一个节点
p = p->next;
j++;
}
// 如果要删除的位置大于 L 的实际长度,则报错
if (p == NULL || p->next == NULL){
printf("位序i不合法,删除错误!");
exit(1);
}
LNode* q = p->next; // 定义一个指针指向要删除的节点
p->next = q->next;
free(q);
printf("删除成功!\n");
}
// 按位序查找(带头节点)
// 返回表 L 中的第 i 个节点的元素
LNode* GetElem(LinkList L, int i){
// 如果要查找的位置小于1则报错
if(i<1){
printf("查找的位置不正确!");
exit(1);
}
LNode* p = L; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 0; // 记录当前p指向的是第几个节点
while(p != NULL && j < i){
// 找到第i个节点
p = p->next;
j++;
}
return p;
}
// 按值查找(带头节点)
// 返回表 L 中的存储着e的元素
LNode* LocateElem(LinkList L, int e){
LNode* p = L->next; // 指针p指向第一个节点
while(p != NULL && p->data != e){
// 当找到或未找到(p指向NULL)时停下
p = p->next;
}
return p;
}
// 求表的长度(带头节点)
int Length(LinkList L){
int len = 0;
LNode* p = L;
while(p->next != NULL){
p = p->next;
len++;
}
return len;
}
// 打印单链表
void PrintList(LinkList L){
LNode* p = L->next; // p指向实际存储数据的第一个节点
while(p != NULL){
printf("%d\n",p->data);
p = p->next;
}
}
void main(){
LinkList L; // 声明一个指向单链表的指针
InitList(&L);
Empty(L);
ListInsert(L ,1 ,78);
ListInsert(L ,2 ,48);
ListInsert(L ,3 ,12345);
PrintList(L);
ListDelete(L ,2);
PrintList(L);
}
1.2.1.2 不带头结点的单链表
功能 | 说明 |
---|---|
InitList(LinkList *L) | 初始化**(有区别)** |
Empty(LinkList L) | 判断单链表是否为空**(有区别)** |
ListInsert(LinkList L, int i, int e) | 按位序插入(在 L 的第 i 个节点插入元素 e)(有区别) |
PrintList(LinkList L) | 打印单链表 |
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct LNode{
// 定义一个单链表的节点类型
int data; // 每个节点的数据域
struct LNode* next; // 每个节点的指针域,指针指向下一个节点
}LNode, *LinkList;
// LNode* 强调的是节点 LinkList 强调的是单链表
// 初始化(不带头节点)
void InitList(LinkList *L){
*L = NULL; // 空表,没有任何节点
}
// 判断单链表是否为空(不带头节点)
int Empty(LinkList L){
if (L == NULL){
printf("单链表为空!");
}else{
printf("单链表不为空!");
}
}
// 按位序插入(不带头节点)
// 在 L 的第 i 个节点插入元素 e
void ListInsert(LinkList* L, int i, int e){
// 如果要插入的位置小于1则报错
if(i<1){
printf("位序i不合法,插入错误!");
exit(1);
}else if(i == 1){
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = *L;
*L = s;
printf("插入成功!\n");
return;
}
LNode* p = *L; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 1; // 记录当前p指向的是第几个节点
while(p != NULL && j < i - 1){
// 找到插入的位置
p = p->next;
j++;
}
// 如果要插入的位置大于 L 的实际长度,则报错
if (p == NULL){
printf("位序i不合法,插入错误!");
exit(1);
}
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL){
printf("分配空间失败!!!");
exit(1);
}
s->data = e; // 插入元素
s->next = p->next;
p->next = s;
printf("插入成功!!\n");
}
// 打印单链表
void PrintList(LinkList L){
while(L != NULL){
printf("%d\n",L->data);
L = L->next;
}
}
void main(){
LinkList L; // 声明一个指向单链表的指针
InitList(&L);
ListInsert(&L ,1 ,78);
ListInsert(&L ,2 ,48);
ListInsert(&L ,3 ,12345);
PrintList(L);
}
1.2.1.3 前插操作
没有区别 带/不带 头节点都适用
// 前插操作:在p节点之前插入元素e
void InsertPriorNode(LNode* p, int e){
if (p == NULL){
printf("插入失败!");
}
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL){
printf("分配空间失败!");
}
s->data = p->data;
s->next = p->next;
p->next = s;
p->data = e;
printf("插入成功!\n");
}
1.2.1.4 后插操作
没有区别 带/不带 头节点都适用
// 后插操作:在p节点之后插入e
void InsertNextNode(LNode* p, int e){
if (p == NULL){
printf("插入失败!");
}
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL){
printf("分配空间失败!");
}
s->data = e;
s->next = p->next;
p->next = s;
printf("插入成功!\n");
}
1.2.1.5 删除指定节点(有bug)
如果删除的是最后一个节点的话,将会无法删除(程序不会报错,但也不会达到预期目的)
(可能会想,我单独将这一种情况进行判断不就好了吗?注意:删除最后一个节点,就是将该节点的前驱指向NULL,请问能实现吗?(直接free掉最后一个节点是不行的))
// 删除指定的节点
void DeleteNode(LNode* p){
if (p == NULL){
printf("删除失败!\n");
}
LNode* q = p->next; // 定义一个指针q指向要删除的节点的后继节点
p->data = q->data; // 将后继节点的数据赋值给要删除的节点
p->next = q->next; // 让要删除的节点指向后继节点的后继节点
free(q); // 释放后继节点的存储空间
printf("删除成功!\n");
}
1.2.1.6 单链表的建立
1.2.1.6.1 头插法
LinkList CreatListHead(){
LinkList L = (LNode*)malloc(sizeof(LNode)); // 头节点
if (L == NULL){
printf("分配空间失败!!!");
exit(1);
}
L->next = NULL; // 如果不初始化,可能会有脏数据,即指向一个未知的区域
LNode* s; // 用于暂存需要添加的数据
int x = 0;
printf("请输入你想要添加的数据:");
scanf("%d", &x);
while(x != 9999){
// 输入9999表示结束
s = (LNode*)malloc(sizeof(LNode));
if (s == NULL){
printf("分配空间失败!!!");
exit(1);
}
s->data = x;
s->next = L->next;
L->next = s;
printf("请输入你想要添加的数据:");
scanf("%d", &x);
}
return L;
}
1.2.1.6.2 尾插法
LinkList CreatListTail(){
LinkList L = (LNode*)malloc(sizeof(LNode)); // 头节点
if (L == NULL){
printf("分配空间失败!!!");
exit(1);
}
L->next = NULL; // 初始化
LNode* s; // 用于暂存需要添加的数据
LNode* r = L; // r永远指向尾部,即尾指针
int x = 0;
printf("请输入你想要添加的数据:");
scanf("%d", &x);
while(x != 9999){
// 输入9999表示结束
s = (LNode*)malloc(sizeof(LNode));
if (s == NULL){
printf("分配空间失败!!!");
exit(1);
}
s->data = x;
s->next = r->next;
r->next = s;
r = s; // 尾指针指向最后一个节点
printf("请输入你想要添加的数据:");
scanf("%d", &x);
}
return L;
}
1.2.2 双链表
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct DNode{
// 定义一个双链表的节点类型
int data; // 每个节点的数据域
struct DNode* prior,* next; // 前驱和后继指针
}DNode, *DLinkList;
// 初始化(带头节点)
void DInitList(DLinkList *L){
*L = (DNode*)malloc(sizeof(DNode)); // 分配一个头节点 (头节点是不存储数据的)
if(*L == NULL){
printf("分配空间失败!\n");
}else{
(*L)->next = NULL;
(*L)->prior = NULL;
printf("分配空间成功!\n");
}
}
// 判断双链表是否为空(带头节点)
void Empty(DLinkList L){
if (L->next == NULL){
printf("单链表为空!\n");
}else{
printf("单链表不为空!\n");
}
}
// 按位序插入(带头节点)
// 在 L 的第 i 个节点后插入元素 e
void DListInsert(DLinkList L, int i, int e){
// 如果要插入的位置小于1则报错
if(i<1){
printf("位序i不合法,插入错误!");
exit(1);
}
DNode* p = L; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 0; // 记录当前p指向的是第几个节点
while(p != NULL && j < i - 1){
// 找到插入的位置
p = p->next;
j++;
}
// 如果要插入的位置大于 L 的实际长度,则报错
if (p == NULL){
printf("位序i不合法,插入错误!");
exit(1);
}
DNode* s = (DNode*)malloc(sizeof(DNode));
if (s == NULL){
printf("分配空间失败!!!");
exit(1);
}
s->data = e;
s->next = p->next; // 插入元素
if(p->next != NULL)
p->next->prior = s->next;
s->prior = p->next;
p->next = s;
printf("插入成功!\n");
}
// 按位序删除(带头节点)
// 删除表 L 中的第 i 个节点的元素
void DListDelete(DLinkList L, int i){
// 如果要删除的位置小于1则报错
if(i<1){
printf("位序i不合法,删除错误!");
exit(1);
}
DNode* p = L; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 0; // 记录当前p指向的是第几个节点
while(p != NULL && j < i - 1){
// 找要删除的元素的前一个节点
p = p->next;
j++;
}
// 如果要删除的位置大于 L 的实际长度,则报错
if (p == NULL || p->next == NULL){
printf("位序i不合法,删除错误!");
exit(1);
}
DNode* q = p->next; // 定义一个指针指向要删除的节点
p->next = q->next;
if(q->next!=NULL){
p->next->prior = p;
}
free(q);
printf("删除成功!\n");
}
// 打印双链表
void DPrintList(DLinkList L){
DNode* p = L->next; // p指向实际存储数据的第一个节点
while(p != NULL){
printf("%d\n",p->data);
p = p->next;
}
}
void main(){
DLinkList L; // 声明一个指向双链表的指针
DInitList(&L);
DListInsert(L ,1 ,78);
DListInsert(L ,2 ,48);
DListInsert(L ,3 ,12345);
DPrintList(L);
DListDelete(L ,2);
DPrintList(L);
}
1.2.3 双向链表
1.2.3.1 循环单链表
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode {
// 定义一个单链表的节点类型
int data; // 每个节点的数据域
struct LNode *next; // 每个节点的指针域,指针指向下一个节点
} LNode, *LinkList;
// 初始化循环单链表(带头节点)
void InitList(LinkList *L) {
*L = (LNode *) malloc(sizeof(LNode)); // 分配一个头节点 (头节点是不存储数据的)
if (*L == NULL) {
printf("分配空间失败!\n");
} else {
(*L)->next = *L;
printf("分配空间成功!\n");
}
}
// 判断循环单链表是否为空(带头节点)
void Empty(LinkList L) {
if (L->next == L) {
printf("单链表为空!\n");
} else {
printf("单链表不为空!\n");
}
}
// 求表的长度(带头节点)
int Length(LinkList L) {
int len = 0;
LNode *p = L;
while (p->next != L) {
p = p->next;
len++;
}
return len;
}
// 按位序插入(带头节点)
// 在 L 的第 i 个节点插入元素 e
void ListInsert(LinkList L, int i, int e) {
// 如果要插入的位置小于1或者超出最大长度则报错
if (i < 1) {
printf("位序i不合法,插入错误!");
exit(1);
}
if (i == 1) {
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == NULL) {
printf("分配空间失败!!!");
exit(1);
}
s->data = e; // 插入元素
s->next = L;
L->next = s;
printf("插入成功!\n");
} else {
LNode *p = L->next; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 1; // 记录当前p指向的是第几个节点
while (p != L && j < i - 1) {
// 找到插入的位置
p = p->next;
j++;
}
// 如果要插入的位置大于 L 的实际长度,则报错
if (p == L) {
printf("位序i超过了循环单链表的最大长度,插入错误!");
exit(1);
}
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == NULL) {
printf("分配空间失败!!!");
exit(1);
}
s->data = e; // 插入元素
s->next = p->next;
p->next = s;
printf("插入成功!\n");
}
}
// 按位序删除(带头节点)
// 删除表 L 中的第 i 个节点的元素
void ListDelete(LinkList L, int i) {
// 如果要删除的位置小于1则报错
if (i < 1) {
printf("位序i不合法,删除错误!");
exit(1);
}
LNode *p = L->next; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 1; // 记录当前p指向的是第几个节点
while (p != L && j < i - 1) {
// 找要删除的元素的前一个节点
p = p->next;
j++;
}
// 如果要删除的位置大于 L 的实际长度,则报错
if (p == L) {
printf("位序i不合法,删除错误!");
exit(1);
}
LNode *q = p->next; // 定义一个指针指向要删除的节点
p->next = q->next;
free(q);
printf("删除成功!\n");
}
// 按位序查找(带头节点)
// 返回表 L 中的第 i 个节点的元素
LNode *GetElem(LinkList L, int i) {
// 如果要查找的位置小于1则报错
if (i < 1) {
printf("查找的位置不正确!");
exit(1);
}
LNode *p = L->next; // 指针p指向当前扫描到的节点(初始化指向第一个节点)
int j = 1; // 记录当前p指向的是第几个节点
while (p != L && j < i) {
// 找到第i个节点
p = p->next;
j++;
}
return p;
}
// 按值查找(带头节点)
// 返回表 L 中的存储着e的元素
LNode *LocateElem(LinkList L, int e) {
LNode *p = L->next; // 指针p指向第一个节点
while (p != L && p->data != e) {
// 当找到或未找到(p指向NULL)时停下
p = p->next;
}
return p;
}
// 打印循环单链表
void PrintList(LinkList L) {
LNode *p = L->next; // p指向实际存储数据的第一个节点
while (p != L) {
printf("%d\n", p->data);
p = p->next;
}
}
void main() {
LinkList L; // 声明一个指向单链表的指针
InitList(&L);
Empty(L);
// ListDelete(L, 1); // 按位序删除
ListInsert(L, 1, 78);
ListInsert(L, 2, 48);
ListInsert(L, 2, 12345);
printf("%d\n", Length(L));
printf("%d\n", LocateElem(L, 12345)->data); // 按值查找
printf("第2个元素为:%d\n", GetElem(L, 2)->data); // 安位序查找
PrintList(L);
ListDelete(L, 2); // 按位序删除
PrintList(L);
}
1.2.3.2 循环双链表
1.3 线性表的销毁
如果线性表是用数组实现的,那么将不需要手动回收,系统会自动回收。
如果线性表是使用了malloc函数实现的,那么将需要手动回收(free函数)。