线性表

顺序表

顺序表的存储结构

// 顺序表的存储结构
#define MAXSIZE 20 // 元素个数的最大值
typedef int ElemType; // ElemType 根据实际情况而定,这里假定为 int
typedef struct {
ElemType data[MAXSIZE]; // 数组
int length; // 数组当前长度
}SqList;

也可以在主函数 main() 中简单定义一个数组, 表示顺序表, 这相当于定义并且初始化:

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
typedef int ElemType;
int main(void) {
// ElemType L[MAXSIZE];
ElemType* L = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
int length = 0;
return 0;
}

在顺序表中插入元素

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
void Inset(int* arr, int location, int elem, int* length) {
// 数组元素后移,
// 从最后一个元素,到第 location 个元素,都要往后移动一位
// location 的合法位置为 1 到 length+1
// 如果在最后一个元素的后面的一个位置插入元素,则 location 为 length+1,循环判断条件不成立,循环一次也不执行,即没有元素需要移动位置
for (int i = (*length) - 1; i >= location - 1; i--) {
arr[i + 1] = arr[i];
}
arr[location - 1] = elem; // 插入新元素
++(*length); // 数组长度加 1
}
int main(void) {
// 假设已经给定了一个数组
int arr[MAXSIZE] = { 1,2,3,4,5 };
int length = 5;
// 打印插入元素之前的数组
printf("插入元素之前的数组: ");
for (int i = 0; i < length; i++) {
printf("%d ", arr[i]);
}
// 进行插入
Inset(arr, 3, 99, &length);
// 打印插入元素之后的数组
printf("\n插入元素之后的数组: ");
for (int i = 0; i < length; i++) {
printf("%d ", arr[i]);
}
return 0;
}

执行结果:

插入元素之前的数组: 1 2 3 4 5
插入元素之后的数组: 1 2 99 3 4 5

在顺序表中删除元素

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
void Delete(int* arr, int location, int* elem, int* length) {
*elem = arr[location - 1]; // 删除的元素的值
// location 的合法位置为 1 到 length
// 数组元素前移,
// 从第 location+1 个元素,到最后一个元素,都要往前移动一位
// 当 location 等于 length 时,循环判断条件不成立,循环不执行,即没有元素需要移动位置
for (int i = location; i <= (*length) - 1; i++) {
arr[i - 1] = arr[i];
}
--(*length); // 数组长度减 1
}
int main(void) {
// 假设已经给定了一个数组
int arr[MAXSIZE] = { 1,2,3,4,5 };
int length = 5;
// 打印插入元素之前的数组
printf("插入元素之前的数组: ");
for (int i = 0; i < length; i++) {
printf("%d ", arr[i]);
}
// 进行删除
int elem; // 用 elem 存储删除的元素的值
Delete(arr, 3, &elem, &length);
// 打印删除元素之后的数组
printf("\n删除元素之后的数组: ");
for (int i = 0; i < length; i++) {
printf("%d ", arr[i]);
}
return 0;
}

执行结果:

插入元素之前的数组: 1 2 3 4 5
删除元素之后的数组: 1 2 4 5

插入和删除元素的平均时间复杂度都是 O(n)。

单链表

单链表的存储结构

// 单链表的存储结构
typedef int ElemType; // 数据域的类型
typedef struct LinkListNode {
ElemType data; // 数据域
struct LinkListNode* next; // 指针域
}LinkListNode; // 结点类型

头插法创建单链表

#include <stdio.h>
#include <stdlib.h>
typedef struct LinkListNode {
int data;
struct LinkListNode* next;
}LinkListNode;
// 头插法创建单链表
void CreatLinkList(LinkListNode** L, int n) {
for (int i = 1; i <= n; i++) {
int data;
printf("输入第 %d 个结点的数据:", i);
LinkListNode* p = (LinkListNode*)malloc(sizeof(LinkListNode));
scanf("%d", &(p->data));
p->next = (*L)->next;
(*L)->next = p;
}
}
void PrintLinkList(LinkListNode* L) {
LinkListNode* p = L->next;
while (p) {
printf("%d\t", p->data);
p = p->next;
}
}
int main(void) {
LinkListNode* L = (LinkListNode*)malloc(sizeof(LinkListNode));
L->next = NULL;
int n = 0;
printf("希望创建的单链表的长度为:");
scanf("%d", &n);
// 创建链表
CreatLinkList(&L, n);
// 打印链表
printf("链表为:\n");
PrintLinkList(L);
return 0;
}

执行结果:

希望创建的单链表的长度为:5
输入第 1 个结点的数据:1
输入第 2 个结点的数据:2
输入第 3 个结点的数据:3
输入第 4 个结点的数据:4
输入第 5 个结点的数据:5
链表为:
5 4 3 2 1

尾插法创建单链表

#include <stdio.h>
#include <stdlib.h>
typedef struct LinkListNode {
int data;
struct LinkListNode* next;
}LinkListNode;
// 尾插法创建单链表
void CreatLinkList(LinkListNode** L, int n) {
LinkListNode* r = *L; // 尾指针
for (int i = 1; i <= n; i++) {
int data;
printf("输入第 %d 个结点的数据:", i);
LinkListNode* p = (LinkListNode*)malloc(sizeof(LinkListNode));
scanf("%d", &(p->data));
p->next = NULL;
r->next = p;
r = p;
}
}
void PrintLinkList(LinkListNode* L) {
LinkListNode* p = L->next;
while (p) {
printf("%d\t", p->data);
p = p->next;
}
}
int main(void) {
LinkListNode* L = (LinkListNode*)malloc(sizeof(LinkListNode));
L->next = NULL;
int n = 0;
printf("希望创建的单链表的长度为:");
scanf("%d", &n);
// 创建链表
CreatLinkList(&L, n);
// 打印链表
printf("链表为:\n");
PrintLinkList(L);
return 0;
}

执行结果:

希望创建的单链表的长度为:5
输入第 1 个结点的数据:1
输入第 2 个结点的数据:2
输入第 3 个结点的数据:3
输入第 4 个结点的数据:4
输入第 5 个结点的数据:5
链表为:
1 2 3 4 5

单链表获取某个结点的值

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LinkListNode {
ElemType data;
struct LinkListNode* next;
}LinkListNode;
// 头插法创建单链表
void CreatLinkList(LinkListNode** L, int n) {
for (int i = 1; i <= n; i++) {
ElemType data;
printf("输入第 %d 个结点的数据:", i);
LinkListNode* p = (LinkListNode*)malloc(sizeof(LinkListNode));
scanf("%d", &(p->data));
p->next = (*L)->next;
(*L)->next = p;
}
}
void PrintLinkList(LinkListNode* L) {
LinkListNode* p = L->next;
while (p) {
printf("%d\t", p->data);
p = p->next;
}
}
ElemType GetNode(LinkListNode* L, int i) {
LinkListNode* p = L->next;
int j = 1;
while (j < i) {
p = p->next;
++j;
}
return p->data;
}
int main(void) {
LinkListNode* L = (LinkListNode*)malloc(sizeof(LinkListNode));
L->next = NULL;
int n = 0;
printf("希望创建的单链表的长度为:");
scanf("%d", &n);
// 创建链表
CreatLinkList(&L, n);
// 打印链表
printf("链表为:\n");
PrintLinkList(L);
int location;
printf("\n想要获取第几个结点的值:");
scanf("%d", &location);
printf("第 %d 个结点的值为:%d\n", location, GetNode(L, location));
return 0;
}

执行结果:

希望创建的单链表的长度为:5
输入第 1 个结点的数据:1
输入第 2 个结点的数据:2
输入第 3 个结点的数据:3
输入第 4 个结点的数据:4
输入第 5 个结点的数据:5
链表为:
5 4 3 2 1
想要获取第几个结点的值:5
第 5 个结点的值为:1

单链表插入结点

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LinkListNode {
ElemType data;
struct LinkListNode* next;
}LinkListNode;
// 头插法创建单链表
void CreatLinkList(LinkListNode** L, int n) {
for (int i = 1; i <= n; i++) {
ElemType data;
printf("输入第 %d 个结点的数据:", i);
LinkListNode* p = (LinkListNode*)malloc(sizeof(LinkListNode));
scanf("%d", &(p->data));
p->next = (*L)->next;
(*L)->next = p;
}
}
void PrintLinkList(LinkListNode* L) {
LinkListNode* p = L->next;
while (p) {
printf("%d\t", p->data);
p = p->next;
}
}
// 插入结点
// 在第 i 个位置插入结点
void Insert(LinkListNode** L, int i, ElemType elem) {
LinkListNode* p = *L;
int j = 0;
while (j < i - 1) {
p = p->next;
j++;
}
LinkListNode* s = (LinkListNode*)malloc(sizeof(LinkListNode));
s->data = elem;
s->next = p->next;
p->next = s;
}
int main(void) {
LinkListNode* L = (LinkListNode*)malloc(sizeof(LinkListNode));
L->next = NULL;
int n = 0;
printf("希望创建的单链表的长度为:");
scanf("%d", &n);
// 创建链表
CreatLinkList(&L, n);
// 打印链表
printf("链表为:\n");
PrintLinkList(L);
// 插入结点
printf("\n输入要插入的结点的位置和新结点的数据值:");
int location;
ElemType data;
scanf("%d %d", &location, &data);
Insert(&L, location, data);
// 打印插入结束的链表
printf("插入结束的链表:\n");
PrintLinkList(L);
return 0;
}

执行结果:

希望创建的单链表的长度为:5
输入第 1 个结点的数据:1
输入第 2 个结点的数据:2
输入第 3 个结点的数据:3
输入第 4 个结点的数据:4
输入第 5 个结点的数据:5
链表为:
5 4 3 2 1
输入要插入的结点的位置和新结点的数据值:3 9
插入结束的链表:
5 4 9 3 2 1

单链表删除结点

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LinkListNode {
ElemType data;
struct LinkListNode* next;
}LinkListNode;
// 头插法创建单链表
void CreatLinkList(LinkListNode** L, int n) {
for (int i = 1; i <= n; i++) {
ElemType data;
printf("输入第 %d 个结点的数据:", i);
LinkListNode* p = (LinkListNode*)malloc(sizeof(LinkListNode));
scanf("%d", &(p->data));
p->next = (*L)->next;
(*L)->next = p;
}
}
void PrintLinkList(LinkListNode* L) {
LinkListNode* p = L->next;
while (p) {
printf("%d\t", p->data);
p = p->next;
}
}
// 删除结点
// 删除第 i 个位置的结点
void Delete(LinkListNode** L, int i, ElemType* elem) {
LinkListNode* p = *L;
int j = 0;
while (j < i - 1) {
p = p->next;
j++;
}
LinkListNode* s = p->next;
p->next = p->next->next;
*elem = s->data;
free(s);
}
int main(void) {
LinkListNode* L = (LinkListNode*)malloc(sizeof(LinkListNode));
L->next = NULL;
int n = 0;
printf("希望创建的单链表的长度为:");
scanf("%d", &n);
// 创建链表
CreatLinkList(&L, n);
// 打印链表
printf("链表为:\n");
PrintLinkList(L);
// 删除结点
printf("\n输入要删除的结点的位置:");
int location;
ElemType data;
scanf("%d", &location);
Delete(&L, location, &data);
// 打印删除结束的链表
printf("删除结束的链表:\n");
PrintLinkList(L);
// 打印被删除元素的值
printf("\n被删除元素的值为:%d\n", data);
return 0;
}

执行结果:

希望创建的单链表的长度为:5
输入第 1 个结点的数据:1
输入第 2 个结点的数据:2
输入第 3 个结点的数据:3
输入第 4 个结点的数据:4
输入第 5 个结点的数据:5
链表为:
5 4 3 2 1
输入要删除的结点的位置:3
删除结束的链表:
5 4 2 1
被删除元素的值为:3

删除单链表

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LinkListNode {
ElemType data;
struct LinkListNode* next;
}LinkListNode;
// 头插法创建单链表
void CreatLinkList(LinkListNode** L, int n) {
for (int i = 1; i <= n; i++) {
ElemType data;
printf("输入第 %d 个结点的数据:", i);
LinkListNode* p = (LinkListNode*)malloc(sizeof(LinkListNode));
scanf("%d", &(p->data));
p->next = (*L)->next;
(*L)->next = p;
}
}
void PrintLinkList(LinkListNode* L) {
LinkListNode* p = L->next;
while (p) {
printf("%d\t", p->data);
p = p->next;
}
}
void Clear(LinkListNode* L, int* length) {
LinkListNode* p = L->next;
LinkListNode* q;
while (p) {
q = p->next;
free(p);
p = q;
--(*length);
}
L->next = NULL;
}
int main(void) {
LinkListNode* L = (LinkListNode*)malloc(sizeof(LinkListNode));
L->next = NULL;
int length = 0;
printf("希望创建的单链表的长度为:");
scanf("%d", &length);
// 创建链表
CreatLinkList(&L, length);
// 打印链表
printf("链表为:\n");
PrintLinkList(L);
// 清空链表
Clear(L, &length);
// 打印清空链表之后的链表长度
printf("\n清空链表之后的链表长度为:%d\n", length);
return 0;
}

执行结果:

希望创建的单链表的长度为:5
输入第 1 个结点的数据:1
输入第 2 个结点的数据:2
输入第 3 个结点的数据:3
输入第 4 个结点的数据:4
输入第 5 个结点的数据:5
链表为:
5 4 3 2 1
清空链表之后的链表长度为:0

循环链表

循环链表 circular link list


双向链表

双向链表 double link list

双向链表的存储结构

// 双向链表的存储结构
typedef int ElemType;
typedef struct DoubleLinkListNode {
ElemType data;
struct DoubleLinkListNode* next;
struct DoubleLinkListNode* prior;
}DoubleLinkListNode;
posted @   有空  阅读(6)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示

目录导航