目录
1.带头结点的双链表的初始化,判断链表是否为空,前插,后插,按位序插,删除后继节点,按位查找,按之查找,清空链表,销毁链表,遍历打印列表操作
2. 循环单链表初始化,判空,判断是否为尾节点
3.循环双链表初始化,判空,判断是否为尾节点,插入,删除后继元素,打印链表内容操作
4.静态链表的初始化,查找空节点,按位查找,按位插入,按位删除,遍历打印操作
注意!!!以下代码是在c++环境中写的c代码,用了c++代码的&
1.带头结点的双链表的初始化,判断链表是否为空,前插,后插,按位序插,删除后继节点,按位查找,按之查找,清空链表,销毁链表,遍历打印列表操作
代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
//带头结点的双链表
//定义结构体
typedef struct DNode {
int data;
struct DNode* prior, * next;
}DNode,*DLinklist;
//添加函数原型的声明
bool InitDLinkList(DLinklist& L);
bool Empty(DLinklist L);
bool InsertNextDNode(DNode* p, DNode* s);
bool InsertPriorDNode(DNode* p, DNode* s);
bool InsertDNode(DLinklist& L, int i, DNode* s);
void PrintDList(DNode* L);
bool DeleteNextDNode(DNode* p);
DNode* GetElem(DLinklist L, int i);
DNode* LocateElem(DLinklist L, int e);
void ClearDList(DLinklist& L);
void DestroyDList(DLinklist& L);
//初始化双链表
bool InitDLinkList(DLinklist &L) {
L = (DNode*)malloc(sizeof(DNode)); //申请了一片空间做为头节点,并且头指针L指向这个节点
if (L == NULL) {
printf("内存分配失败");
return false;
}
L->prior = NULL; //头结点的前向指针永远指向NULL
L->next = NULL; //头结点的下一个节点暂时还没有节点
return true;
}
//判断链表是否为空
bool Empty(DLinklist L) {
if (L->next == NULL)
return true;
else
return false;
}
//后插操作,在p节点后插入s节点
bool InsertNextDNode(DNode *p,DNode *s) {
if (p == NULL || s == NULL) //非法参数
return false;
s->next=p->next;
if(p->next!=NULL) //如果p不是最后一个节点
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
//双链表的前插操作,在p节点前插入节点s
bool InsertPriorDNode(DNode *p,DNode *s) {
if (p == NULL || s == NULL) //非法参数
return false;
DNode* q = p->prior; //找到p的前一个结点,在他后面进行后插
InsertNextDNode(q, s);
return true;
}
//实现按位序插入,实现逻辑,找到当前位序的前一个节点,在其后进行后插
bool InsertDNode(DLinklist &L, int i, DNode* s) {
DNode *p= GetElem(L, (i - 1));
//进行后插
InsertNextDNode(p, s);
return true;
}
// 打印双链表
void PrintDList(DNode* L) {
DNode* p = L->next; // 跳过头节点
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
}
//删除p节点后的后继节点
bool DeleteNextDNode(DNode* p) {
if (p == NULL || p->next == NULL)
return false;
DNode* q = p->next;
p->next = q->next;
if (q->next != NULL)
q->next->prior = p;
free(q);
return true;
}
//按位查询双链表,查询第i个位置的节点,并返回该节点
DNode* GetElem(DLinklist L,int i) {
DNode* p = L;
int j = 0;
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
if (p == NULL) // 如果p为空,说明i值过大
return NULL;
return p;
}
//按值查找
DNode* LocateElem(DLinklist L,int e) {
DNode* p = L->next; //聪第一个结点开始遍历,因为头结点的数据为NULL,无意义。
while (p != NULL && p->data!=e) {
p = p->next;
}
return p;
}
//清空双链表
void ClearDList(DLinklist &L) {
while (L->next != NULL) {
DeleteNextDNode(L);
}
}
//销毁双链表
void DestroyDList(DLinklist &L) {
ClearDList(L);
free(L); //释放头结点
L = NULL; //头指针指向NULL,使其链表结构彻底销毁
}
int main() {
DLinklist L;
InitDLinkList(L);
//检查双链表是否为空
printf("当前双链表是否为空:%s\n",Empty(L)?"是":"否");
// 验证后插操作
DNode* node1 = (DNode*)malloc(sizeof(DNode));
node1->data = 1;
InsertNextDNode(L, node1);
printf("后插节点1后双链表的内容:\n");
PrintDList(L);
// 验证按位序插入操作
DNode* node2 = (DNode*)malloc(sizeof(DNode));
node2->data = 2;
InsertDNode(L, 2, node2);
printf("按位序插入节点2后双链表的内容:\n");
PrintDList(L);
// 验证前插操作
DNode* node3 = (DNode*)malloc(sizeof(DNode));
node3->data = 3;
InsertPriorDNode(node2, node3);
printf("前插节点3后双链表的内容:\n");
PrintDList(L);
// 验证按值查找操作
int value = 2;
DNode* result = LocateElem(L, value);
if (result != NULL) {
printf("找到值为%d的节点地址为:%d\n", value,result);
}
else {
printf("未找到值为%d的节点\n", value);
}
// 清空双链表
ClearDList(L);
printf("清空双链表后:\n");
PrintDList(L);
// 销毁双链表
DestroyDList(L);
if (L == NULL) {
printf("双链表已销毁\n");
}
else {
printf("双链表销毁失败\n");
}
return 0;
}
结果:
2. 循环单链表初始化,判空,判断是否为尾节点
代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
//循环单链表
//定义单链表结构体
typedef struct LNode {
int data;
struct LNode* next;
}LNode,*LinkList;
//添加函数原型的声明
bool InitList(LinkList& L);
bool Empty(LinkList L);
bool IsTail(LinkList L, LNode* p);
//链表初始化
bool InitList(LinkList &L) {
//关于链表初始化是否需要将data设置为空的说法,回答如下:
//主要是确保链表存在并且指针正确设置。
//即头结点已经被分配内存并且 next 指针指向自己(循环链表)或 NULL(普通链表)。不需要设置data域为空
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = L;
return true;
}
//链表判空操作,判断链表是否为空
bool Empty(LinkList L) {
if (L->next == L)
return true;
else
return false;
}
//判断节点p是否为尾节点
bool IsTail(LinkList L,LNode *p) {
if (p->next == L)
return true;
else
return false;
}
int main() {
LinkList L; //定义一个单链表
InitList(L);
//判空操作验证
printf("该循环链表是否为空:%s\n", Empty(L) ? "是" : "否");
//是否为尾节点验证
LNode *p= (LNode*)malloc(sizeof(LNode));
L->next = p;
p->next = L;
printf("该节点是否为尾节点:%s\n", IsTail(L,p) ? "是" : "否");
return 0;
}
结果:
3.循环双链表初始化,判空,判断是否为尾节点,插入,删除后继元素,打印链表内容操作
代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
//循环双链表
//定义单链表结构体
typedef struct LNode {
int data;
struct LNode *next,*prior;
}DNode, *DLinkList;
//函数原型的声明
bool InitDLinkList(DLinkList& L);
bool Empty(DLinkList L);
bool IsTail(DLinkList L, DNode* p);
bool InsertNextDNode(DNode* p, DNode* s);
bool DeleteDNode(LNode* p);
void PrintList(DLinkList L);
//初始化双链表
bool InitDLinkList(DLinkList &L) {
L = (DNode*)malloc(sizeof(DNode));
if (L == NULL)
return false;
L->next = L;
L->prior = L;
return true;
}
//判空操作
bool Empty(DLinkList L) {
if (L->next == L)
return true;
else
return false;
}
//判断节点p是否为尾节点
bool IsTail(DLinkList L, DNode *p) {
if (p->next == L)
return true;
else
return false;
}
//插入节点,在p节点后插入s节点
bool InsertNextDNode(DNode* p, DNode* s) {
if (p == NULL || s == NULL) {
return false; // 如果 p 或 s 为空,则插入失败
}
p->next->prior = s;
s->next=p->next;
p->next = s;
s->prior = p;
return true;
}
//删除p节点的后继节点q
bool DeleteDNode(LNode *p) {
if (p == NULL || p->next == NULL)
return false;
DNode* q = p->next;
p->next = q->next;
q->next->prior = p;
free(q);
return true;
}
// 打印链表内容
void PrintList(DLinkList L) {
DNode* p = L->next;
while (p != L) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main() {
DLinkList L;
InitDLinkList(L);
// 判空操作验证
printf("该循环双链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入节点测试
DNode* node1 = (DNode*)malloc(sizeof(DNode));
node1->data = 1;
InsertNextDNode(L, node1);
DNode* node2 = (DNode*)malloc(sizeof(DNode));
node2->data = 2;
InsertNextDNode(node1, node2);
DNode* node3 = (DNode*)malloc(sizeof(DNode));
node3->data = 3;
InsertNextDNode(node2, node3);
// 打印链表内容验证插入操作
printf("链表内容: ");
PrintList(L);
// 是否为尾节点验证
printf("node3 是否为尾节点:%s\n", IsTail(L, node3) ? "是" : "否");
// 删除节点测试
DeleteDNode(node1); // 删除 node1 的后继节点 node2
// 打印链表内容验证删除操作
printf("删除 node2 后链表内容: ");
PrintList(L);
// 释放内存
free(node1);
free(node3);
free(L);
return 0;
}
结果:
4.静态链表的初始化,查找空节点,按位查找,按位插入,按位删除,遍历打印操作
代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#define MaxSize 10
// 静态链表定义
typedef struct {
int data; // 存储数据元素
int next; // 下一个元素的数组下标
} SLinkList[MaxSize];
//函数原型声明
bool InitSList(SLinkList& s);
int FindFreeNode(SLinkList s);
int FindLocate(SLinkList s, int i);
bool Insert(SLinkList& s, int i, int e);
int DeleteSNode(SLinkList& s, int i);
void PrintList(SLinkList s);
// 初始化链表
bool InitSList(SLinkList& s) {
if (s == NULL)
return false;
s[0].next = -1; // 头节点,next指向-1表示空链表
for (int i = 1; i < MaxSize; i++) {
s[i].next = -2; // -2表示空闲节点
}
return true;
}
// 找到第一个空闲的元素,并返回它的下标
int FindFreeNode(SLinkList s) {
for (int i = 0; i < MaxSize; i++) {
if (s[i].next == -2) {
return i;
}
}
return -1; // 没有空闲节点
}
// 找到位序为i的元素,并返回它的下标
int FindLocate(SLinkList s, int i) {
int pos = 0; // 指向头节点
for (int j = 0; j < i && pos != -1; j++) {
pos = s[pos].next;
}
return pos;
}
// 按位插入,在位序为i的位置插入值为e的节点
bool Insert(SLinkList& s, int i, int e) {
if (i < 1 || i > MaxSize - 1) return false; // 插入位置无效
int prev = FindLocate(s, i - 1); // 找到位序i-1的位置
if (prev == -1) return false; // 插入位置无效
int freeNode = FindFreeNode(s); // 找到一个空闲节点
if (freeNode == -1) return false; // 没有空闲节点
s[freeNode].data = e;
s[freeNode].next = s[prev].next;
s[prev].next = freeNode;
return true;
}
// 删除位序为i的节点,并返回删除节点的值
int DeleteSNode(SLinkList& s, int i) {
if (i < 1 || i >= MaxSize) return -1; // 删除位置无效
int prev = FindLocate(s, i - 1); // 找到位序i-1的位置
if (prev == -1 || s[prev].next == -1) return -1; // 删除位置无效
int delNode = s[prev].next; // 要删除的节点
int e = s[delNode].data; // 获取删除节点的数据
s[prev].next = s[delNode].next; // 跳过要删除的节点
s[delNode].next = -2; // 将删除的节点标记为空闲节点
return e;
}
// 打印链表中的元素
void PrintList(SLinkList s) {
int pos = s[0].next; // 从头节点的下一个节点开始
while (pos != -1) {
printf("%d -> ", s[pos].data);
pos = s[pos].next;
}
printf("NULL\n");
}
int main() {
SLinkList s;
if (InitSList(s)) {
Insert(s, 1, 10);
Insert(s, 2, 20);
Insert(s, 1, 5);
printf("初始链表: ");
PrintList(s);
int deletedValue = DeleteSNode(s, 2);
printf("删除位序为2的节点后: ");
PrintList(s);
printf("删除的值: %d\n", deletedValue);
}
else {
printf("链表初始化失败\n");
}
return 0;
}
结果:
结束~
有收获的宝宝留个赞赞再走吧~
不胜感激~