目录
注意!!!以下代码是在c++环境中写的c代码,用了c++代码的&
1.带头结点的初始化以及检查单链表是否为空
代码:
#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 ) {
//申请一篇空间来存储存储头节点,并使L指向这个节点
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = NULL;
return true;
}
//检查单链表是否为空
bool Empty(LinkList L) {
return (L->next==NULL);
}
int main() {
//定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
return 0;
}
结果:
2.不带头结点的单链表初始化以及表是否为空检查
代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//不带头节点的单链表
//定义结构体变量
typedef struct LNode {
int data;
struct LNode *next;
} LNode,*LinkList;
//初始化单链表
bool InitList(LinkList &L) {
//头指针赋值为空
L = NULL;
return true;
}
//判断单链表是否为空
bool Empty(LinkList L) {
return (L == NULL);
}
int main() {
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n",Empty(L) ? "是":"否");
return 0;
}
结果:
3.带头结点按位序插入
代码:
#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 ) {
//申请一篇空间来存储存储头节点,并使L指向这个节点
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = NULL;
return true;
}
//检查单链表是否为空
bool Empty(LinkList L) {
return (L->next==NULL);
}
//插入,在第i个位置插入元素e
bool InsertList(LinkList& L, int i, int e) {
//判断i范围是否合法
if (i < 1)
return false;
//定义一个指针指向当前扫描的结点,使其刚开始指向头结点(L在初始化的时候指向了头结点),
LNode* p = L;
int j = 0;//定义当前p指向的是第几个结点
while (p != NULL && j < i - 1) {
//此函数是为了寻找第i-1个节点
p = p->next;
j++;
}
//处理当插入位置的前一个节点(即第 i−1 个节点)不存在
if (p == NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
int main() {
//定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
return 0;
}
结果跟上回一样,就不展示了
4.不带头结点的按位序插入
代码:
#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) {
//头指针赋值为空
L = NULL;
return true;
}
//判断单链表是否为空
bool Empty(LinkList L) {
return (L == NULL);
}
bool ListInsert(LinkList& L,int i,int e ) {
if (i < 1)
return false;
//处理在第一个节点处插入
if (i == 1) {
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
return true;
}
//处理在除第一个节点外插入,先找到该节点的前一个节点
LNode* p;//指针p指向当前扫描到的节点
int j = 1;//当前p指向的是第几个节点
p = L;//p指向第1个节点(注意不是头结点)
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
if (p == NULL)//i太大
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
int main() {
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n",Empty(L) ? "是":"否");
return 0;
}
结果和上回一样,就不贴图了
5.带头结点的后插,前插,按位删除,删除固定节点操作
代码:
#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 InsertList(LinkList& L, int i, int e);
bool InsertNestNode(LNode* p, int e);
bool InsertPriorNode(LNode* p, int e);
bool ListDelete(LinkList& L, int i, int& e);
bool DeleteNode(LNode* p, int& e);
bool PrintList(LinkList L);
//初始化
bool InitList(LinkList &L ) {
//申请一篇空间来存储存储头节点,并使L指向这个节点
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = NULL;
return true;
}
//检查单链表是否为空
bool Empty(LinkList L) {
return (L->next==NULL);
}
//插入,在第i个位置插入元素e
bool InsertList(LinkList& L, int i, int e) {
//判断i范围是否合法
if (i < 1)
return false;
//定义一个指针指向当前扫描的结点,使其刚开始指向头结点(L在初始化的时候指向了头结点),
LNode* p = L;
int j = 0;//定义当前p指向的是第几个结点
while (p != NULL && j < i - 1) {
//此函数是为了寻找第i-1个节点
p = p->next;
j++;
}
return InsertNestNode(p, e);
}
//指定节点的后插操作,在p节点之后插入元素e
bool InsertNestNode(LNode *p, int e) {
//处理当插入位置的前一个节点不存在
if (p == NULL)
return false;
LNode* s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next= s;
return true;
}
//前插操作:在p结点前面插入元素e,(还是后插,只是把里面的数据换一下顺序)
bool InsertPriorNode(LNode *p,int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
s->data = p->data; //将p中的元素复制到s中
p->next = s; //新节点s连到p之后
p->data = e; //p中元素覆盖为e
return true;
}
//按位序删除
bool ListDelete(LinkList& L, int i, int& e) {
if (i < 1)
return false;
LNode* p;
p = L;
int j = 0;
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode* q = p->next;
p->next = q->next;
e=q->data;
free(q);
return true;
}
//删除指定节点p
bool DeleteNode(LNode* p, int& e) {
//此方法不能删除最后一个节点!注意,只能传入头指针从头遍历来删除最后的结点
LNode* q = p->next;
if(p == NULL||q==NULL)
return false;
p->data = q->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free (q); //释放后继节点的存储空间
return true;
}
//打印单链表的元素
bool PrintList(LinkList L) {
LNode* p = L;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
return true;
}
int main() {
// 定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入一些元素
InsertList(L, 1, 10);
InsertList(L, 2, 20);
InsertList(L, 3, 30);
InsertList(L, 2, 15); // 插入在第二个位置
printf("链表内容:");
PrintList(L);
// 删除一些元素
int e;
ListDelete(L, 2, e); // 删除第二个位置的元素
printf("删除第二个位置的元素:%d\n", e);
printf("链表内容:");
PrintList(L);
// 在第一个节点前插入元素
InsertPriorNode(L->next, 5);
printf("在第一个节点前插入5:");
PrintList(L);
// 删除指定节点
DeleteNode(L->next, e);
printf("删除第一个节点后的节点,其值为:%d\n", e);
printf("链表内容:");
PrintList(L);
return 0;
}
结果:
6 不带头结点的后插,前插,按位删除,删除固定节点操作,
注:也就按位删除和带头结点的有区别,因为得考虑第一个节点
代码:
#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 InsertList(LinkList& L, int i, int e);
bool InsertNestNode(LNode* p, int e);
bool InsertPriorNode(LNode* p, int e);
bool ListDelete(LinkList& L, int i, int& e);
bool DeleteNode(LNode* p, int& e);
bool PrintList(LinkList L);
//初始化单链表
bool InitList(LinkList &L) {
//头指针赋值为空
L = NULL;
return true;
}
//判断单链表是否为空
bool Empty(LinkList L) {
return (L == NULL);
}
bool InsertList(LinkList& L,int i,int e ) {
if (i < 1)
return false;
//处理在第一个节点处插入
if (i == 1) {
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
return true;
}
//处理在除第一个节点外插入,先找到该节点的前一个节点
LNode* p;//指针p指向当前扫描到的节点
int j = 1;//当前p指向的是第几个节点
p = L;//p指向第1个节点(注意不是头结点)
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
return InsertNestNode(p, e);
}
//后插操作
bool InsertNestNode(LNode* p, int e) {
//处理当插入位置的前一个节点不存在
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//前插操作:在p结点前面插入元素e,(还是后插,只是把里面的数据换一下顺序)
bool InsertPriorNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
s->data = p->data; //将p中的元素复制到s中
p->next = s; //新节点s连到p之后
p->data = e; //p中元素覆盖为e
return true;
}
//按位序删除
bool ListDelete(LinkList& L, int i, int& e) {
if (i < 1)
return false;
// 删除第一个节点的特殊处理
if (i == 1) {
if (L == NULL)
return false;
LNode* q = L;
e = L->data;
L = L->next;
free(q);
return true;
}
LNode* p;
p = L;
int j = 0;
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode* q = p->next;
p->next = q->next;
e = q->data;
free(q);
return true;
}
//删除指定节点p
bool DeleteNode(LNode* p, int& e) {
//此方法不能删除最后一个节点!注意,只能传入头指针从头遍历来删除最后的结点
LNode* q = p->next;
if (p == NULL || q == NULL)
return false;
p->data = q->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放后继节点的存储空间
return true;
}
//打印单链表的元素
bool PrintList(LinkList L) {
LNode* p = L;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
return true;
}
int main() {
// 定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入一些元素
InsertList(L, 1, 10);
InsertList(L, 2, 20);
InsertList(L, 3, 30);
InsertList(L, 2, 15); // 插入在第二个位置
printf("链表内容:");
PrintList(L);
// 删除一些元素
int e;
ListDelete(L, 2, e); // 删除第二个位置的元素
printf("删除第二个位置的元素:%d\n", e);
printf("链表内容:");
PrintList(L);
// 在第一个节点前插入元素
InsertPriorNode(L->next, 5);
printf("在第一个节点前插入5:");
PrintList(L);
// 删除指定节点
DeleteNode(L->next, e);
printf("删除第一个节点后的节点,其值为:%d\n", e);
printf("链表内容:");
PrintList(L);
return 0;
}
结果:
7.带头结点的单链表的查找(按位查找,按值查找,求表长)
代码:
#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 InsertList(LinkList& L, int i, int e);
bool InsertNestNode(LNode* p, int e);
bool InsertPriorNode(LNode* p, int e);
bool ListDelete(LinkList& L, int i, int& e);
bool DeleteNode(LNode* p, int& e);
bool PrintList(LinkList L);
LNode* GetElem(LinkList L, int i);
LNode* LocateElem(LinkList L, int e);
int Length(LinkList L);
//初始化
bool InitList(LinkList& L) {
//申请一篇空间来存储存储头节点,并使L指向这个节点
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = NULL;
return true;
}
//检查单链表是否为空
bool Empty(LinkList L) {
return (L->next == NULL);
}
//插入,在第i个位置插入元素e
bool InsertList(LinkList& L, int i, int e) {
//判断i范围是否合法
if (i < 1)
return false;
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
return InsertNestNode(p, e);
}
//指定节点的后插操作,在p节点之后插入元素e
bool InsertNestNode(LNode* p, int e) {
//处理当插入位置的前一个节点不存在
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//前插操作:在p结点前面插入元素e,(还是后插,只是把里面的数据换一下顺序)
bool InsertPriorNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
s->data = p->data; //将p中的元素复制到s中
p->next = s; //新节点s连到p之后
p->data = e; //p中元素覆盖为e
return true;
}
//按位序删除
bool ListDelete(LinkList& L, int i, int& e) {
if (i < 1)
return false;
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode* q = p->next;
p->next = q->next;
e = q->data;
free(q);
return true;
}
//删除指定节点p
bool DeleteNode(LNode* p, int& e) {
//此方法不能删除最后一个节点!注意,只能传入头指针从头遍历来删除最后的结点
LNode* q = p->next;
if (p == NULL || q == NULL)
return false;
p->data = q->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放后继节点的存储空间
return true;
}
//打印单链表的元素
bool PrintList(LinkList L) {
LNode* p = L->next;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
return true;
}
//按位查找,查找到第i个元素
LNode* GetElem(LinkList L, int i) {
if (i < 0)//这必须是i<0,
//因为考虑到带头结点的调用此函数传入的参数是i-1,所以当插入第一个节点时,GetElem函数里面的i值为0,所以是i<0
//如果写写i<1,则在第一个位置插入则回返回null,最终插入失败。
return NULL;
LNode* p = L;
int j = 0;//j是从0开始的,因为有头结点,默认头结点是第0个结点
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
//按值查找,根据e的值查找到e对应的指针
LNode* LocateElem(LinkList L,int e) {
LNode* p = L->next;
while (p != NULL && p->data != e)
p = p->next;
return p;//找到就返回该节点指针,否则返回NULL
}
//求表的长度
int Length(LinkList L) {
int len = 0;//表长
LNode* p = L;
while (p->next!=NULL) {
p = p->next;
len++;
}
return len;
}
int main() {
// 定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入一些元素
printf("%dhhh\n", InsertList(L, 1, 10));
InsertList(L, 2, 20);
InsertList(L, 3, 30);
InsertList(L, 2, 15); // 插入在第二个位置
printf("链表内容:");
PrintList(L);
// 删除一些元素
int e;
ListDelete(L, 2, e); // 删除第二个位置的元素
printf("删除第二个位置的元素:%d\n", e);
printf("链表内容:\n");
PrintList(L);
// 在第一个节点前插入元素
InsertPriorNode(L->next, 5);
printf("在第一个节点前插入5:");
PrintList(L);
// 删除指定节点
DeleteNode(L->next, e);
printf("删除第一个节点后的节点,其值为:%d\n", e);
printf("链表内容:\n");
PrintList(L);
//按值查找元素的地址
printf("20这个元素的地址为:%d\n", LocateElem(L, 20));
printf("20元素标准地址:%d\n", GetElem(L, 2));
//打印单链表的长度
printf("表长为:%d", Length(L));
return 0;
}
结果:
8.不带头结点的单链表的查找(按位查找,按值查找,求表长)
代码:
#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 InsertList(LinkList& L, int i, int e);
bool InsertNestNode(LNode* p, int e);
bool InsertPriorNode(LNode* p, int e);
bool ListDelete(LinkList& L, int i, int& e);
bool DeleteNode(LNode* p, int& e);
bool PrintList(LinkList L);
LNode* GetElem(LinkList L, int i);
LNode* LocateElem(LinkList L, int e);
int Length(LinkList L);
//初始化单链表
bool InitList(LinkList &L) {
//头指针赋值为空
L = NULL;
return true;
}
//判断单链表是否为空
bool Empty(LinkList L) {
return (L == NULL);
}
bool InsertList(LinkList& L,int i,int e ) {
if (i < 1)
return false;
//处理在第一个节点处插入
if (i == 1) {
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
return true;
}
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
return InsertNestNode(p, e);
}
//后插操作
bool InsertNestNode(LNode* p, int e) {
//处理当插入位置的前一个节点不存在
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//前插操作:在p结点前面插入元素e,(还是后插,只是把里面的数据换一下顺序)
bool InsertPriorNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
s->data = p->data; //将p中的元素复制到s中
p->next = s; //新节点s连到p之后
p->data = e; //p中元素覆盖为e
return true;
}
//按位序删除
bool ListDelete(LinkList& L, int i, int& e) {
if (i < 1)
return false;
// 删除第一个节点的特殊处理
if (i == 1) {
if (L == NULL)
return false;
LNode* q = L;
e = L->data;
L = L->next;
free(q);
return true;
}
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode* q = p->next;
p->next = q->next;
e = q->data;
free(q);
return true;
}
//删除指定节点p
bool DeleteNode(LNode* p, int& e) {
//此方法不能删除最后一个节点!注意,只能传入头指针从头遍历来删除最后的结点
LNode* q = p->next;
if (p == NULL || q == NULL)
return false;
p->data = q->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放后继节点的存储空间
return true;
}
//打印单链表的元素
bool PrintList(LinkList L) {
LNode* p = L;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
return true;
}
//按位查找,查找到第i个元素
LNode* GetElem(LinkList L,int i) {
if (i < 1)
return NULL;
LNode* p = L;
int j = 1;//j是从1开始的,因为没有头结点,直接从第一个节点开始了
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
//按值查找,根据e的值查找到e对应的指针
LNode* LocateElem(LinkList L, int e) {
LNode* p = L->next;
while (p != NULL && p->data != e)
p = p->next;
return p;//找到就返回该节点指针,否则返回NULL
}
//求表的长度
int Length(LinkList L) {
int len = 0;//表长
LNode* p = L;
while (p != NULL) {
p = p->next;
len++;
}
return len;
}
int main() {
// 定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入一些元素
InsertList(L, 1, 10);
InsertList(L, 2, 20);
InsertList(L, 3, 30);
InsertList(L, 2, 15); // 插入在第二个位置
printf("链表内容:");
PrintList(L);
// 删除一些元素
int e;
ListDelete(L, 2, e); // 删除第二个位置的元素
printf("删除第二个位置的元素:%d\n", e);
printf("链表内容:\n");
PrintList(L);
// 在第一个节点前插入元素
InsertPriorNode(L->next, 5);
printf("在第一个节点前插入5:");
PrintList(L);
// 删除指定节点
DeleteNode(L->next, e);
printf("删除第一个节点后的节点,其值为:%d\n", e);
printf("链表内容:\n");
PrintList(L);
//按值查找元素的地址
printf("20这个元素的地址为:%d\n", LocateElem(L, 20));
printf("20元素标准地址:%d\n",GetElem(L,2));
//打印单链表的长度
printf("表长为:%d", Length(L));
return 0;
}
结果:
9.带头结点的尾插法,头插法,清空链表操作
代码:
#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 InsertList(LinkList& L, int i, int e);
bool InsertNestNode(LNode* p, int e);
bool InsertPriorNode(LNode* p, int e);
bool ListDelete(LinkList& L, int i, int& e);
bool DeleteNode(LinkList& L,LNode* p, int& e);
bool PrintList(LinkList L);
LNode* GetElem(LinkList L, int i);
LNode* LocateElem(LinkList L, int e);
int Length(LinkList L);
LinkList List_TailInsert(LinkList& L);
LinkList List_HeadInsert(LinkList& L);
void CleanList(LinkList& L);
//初始化
bool InitList(LinkList& L) {
//申请一篇空间来存储存储头节点,并使L指向这个节点
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = NULL;
return true;
}
//检查单链表是否为空
bool Empty(LinkList L) {
return (L->next == NULL);
}
//插入,在第i个位置插入元素e
bool InsertList(LinkList& L, int i, int e) {
//判断i范围是否合法
if (i < 1)
return false;
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
return InsertNestNode(p, e);
}
//指定节点的后插操作,在p节点之后插入元素e
bool InsertNestNode(LNode* p, int e) {
//处理当插入位置的前一个节点不存在
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL)
return false;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//前插操作:在p结点前面插入元素e,(还是后插,只是把里面的数据换一下顺序)
bool InsertPriorNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
s->data = p->data; //将p中的元素复制到s中
p->next = s; //新节点s连到p之后
p->data = e; //p中元素覆盖为e
return true;
}
//按位序删除
bool ListDelete(LinkList& L, int i, int &e) {
if (i < 1)
return false;
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode* q = p->next;
p->next = q->next;
e = q->data;
free(q);
return true;
}
//删除指定节点p
bool DeleteNode(LinkList& L,LNode* p, int& e) {
if (p == NULL)
return false;
if (p->next == NULL) {
// 如果p是最后一个节点,找到p的前驱节点
LNode* prev = L;
while (prev->next != p) {
prev = prev->next;
}
prev->next = NULL;
e = p->data;
free(p);
return true;
}
else {
LNode* q = p->next;
if (p == NULL || q == NULL)
return false;
p->data = q->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放后继节点的存储空间
return true;
}
}
//打印单链表的元素
bool PrintList(LinkList L) {
printf("当前链表内的元素如下:\n");
LNode* p = L->next;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
return true;
}
//按位查找,查找到第i个元素
LNode* GetElem(LinkList L, int i) {
if (i < 0)//这必须是i<0,
//因为考虑到带头结点的调用此函数传入的参数是i-1,所以当插入第一个节点时,GetElem函数里面的i值为0,所以是i<0
//如果写写i<1,则在第一个位置插入则回返回null,最终插入失败。
return NULL;
LNode* p = L;
int j = 0; //j是从0开始的,因为有头结点,默认头结点是第0个结点
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
//按值查找,根据e的值查找到e对应的指针
LNode* LocateElem(LinkList L,int e) {
LNode* p = L->next;
while (p != NULL && p->data != e)
p = p->next;
return p; //找到就返回该节点指针,否则返回NULL
}
//求表的长度
int Length(LinkList L) {
int len = 0;//表长
LNode* p = L;
while (p->next!=NULL) {
p = p->next;
len++;
}
return len;
}
//尾插法建立单链表 法一r,s指针交替
LinkList List_TailInsert(LinkList &L) {
int x; //定义单链表中的数据类型
L = (LNode*)malloc(sizeof(LNode));
LNode* s, * r = L;
printf("请您输入要插入的元素:");
scanf("%d",&x);
while (x!=9999) { //输入9999表示结束
s= (LNode*)malloc(sizeof(LNode));
s->data = x;
r->next = s; //让s结点指向第一个元素的位置,r还是指向头结点
r = s; //r和s指向一样
printf("请您输入要插入的元素:");
scanf("%d", &x);
}
r->next = NULL;
return L;
}
//头插法创建单链表,每回都在头结点后插
LinkList List_HeadInsert(LinkList &L) {
int x; //定义一个变量来存储要插入的值
LNode* s; //定义在循环外面,能加快程序的运行速度
L = (LNode*)malloc(sizeof(LNode));
L->next = NULL;
printf("请您输入要插入的元素:");
scanf("%d", &x);
while (x!=9999) { //输入9999表示结束
s= (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next= L->next;
L->next = s;
printf("请您输入要插入的元素:");
scanf("%d", &x);
}
return L;
}
//清空表
void CleanList(LinkList &L) {
while (L->next!= NULL) {
int e;
ListDelete(L, 1, e);
printf("删除的元素值为:%d\n", e);
}
PrintList(L);
}
int main() {
// 定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入一些元素
printf("%dhhh\n", InsertList(L, 1, 10));
InsertList(L, 2, 20);
InsertList(L, 3, 30);
InsertList(L, 2, 15); // 插入在第二个位置
printf("链表内容:");
PrintList(L);
// 删除一些元素
int e;
ListDelete(L, 2, e); // 删除第二个位置的元素
printf("删除第二个位置的元素:%d\n", e);
printf("链表内容:\n");
PrintList(L);
// 在第一个节点前插入元素
InsertPriorNode(L->next, 5);
printf("在第一个节点前插入5:");
PrintList(L);
// 删除指定节点
DeleteNode(L,L->next, e);
printf("删除第一个节点后的节点,其值为:%d\n", e);
printf("链表内容:\n");
PrintList(L);
//按值查找元素的地址
printf("20这个元素的地址为:%d\n", LocateElem(L, 20));
printf("20元素标准地址:%d\n", GetElem(L, 2));
//打印单链表的长度
printf("表长为:%d\n", Length(L));
//清空表
printf("下面是清空表操作:\n");
CleanList(L);
// 检查链表是否为空
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
//检验后插法
List_TailInsert(L);
PrintList(L);
//检验头插法
CleanList(L);
List_HeadInsert(L);
PrintList(L);
return 0;
}
结果:
10.不带头结点的尾插法,头插法,清空链表操作
代码:
#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 InsertList(LinkList& L, int i, int e);
bool InsertNestNode(LNode* p, int e);
bool InsertPriorNode(LNode* p, int e);
bool ListDelete(LinkList& L, int i, int& e);
bool DeleteNode(LNode* p, int& e);
bool PrintList(LinkList L);
LNode* GetElem(LinkList L, int i);
LNode* LocateElem(LinkList L, int e);
int Length(LinkList L);
LinkList List_TailInsert(LinkList& L);
LinkList List_HeadInsert(LinkList& L);
void CleanList(LinkList& L);
//初始化单链表
bool InitList(LinkList &L) {
//头指针赋值为空
L = NULL;
return true;
}
//判断单链表是否为空
bool Empty(LinkList L) {
return (L == NULL);
}
bool InsertList(LinkList& L,int i,int e ) {
if (i < 1)
return false;
//处理在第一个节点处插入
if (i == 1) {
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
return true;
}
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
return InsertNestNode(p, e);
}
//后插操作
bool InsertNestNode(LNode* p, int e) {
//处理当插入位置的前一个节点不存在
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//前插操作:在p结点前面插入元素e,(还是后插,只是把里面的数据换一下顺序)
bool InsertPriorNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
s->data = p->data; //将p中的元素复制到s中
p->next = s; //新节点s连到p之后
p->data = e; //p中元素覆盖为e
return true;
}
//按位序删除
bool ListDelete(LinkList& L, int i, int& e) {
if (i < 1)
return false;
// 删除第一个节点的特殊处理
if (i == 1) {
if (L == NULL)
return false;
LNode* q = L;
e = L->data;
L = L->next;
free(q);
return true;
}
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode* q = p->next;
p->next = q->next;
e = q->data;
free(q);
return true;
}
//删除指定节点p
bool DeleteNode(LNode* p, int& e) {
//此方法不能删除最后一个节点!注意,只能传入头指针从头遍历来删除最后的结点
LNode* q = p->next;
if (p == NULL || q == NULL)
return false;
p->data = q->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放后继节点的存储空间
return true;
}
//打印单链表的元素
bool PrintList(LinkList L) {
LNode* p = L;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
return true;
}
//按位查找,查找到第i个元素
LNode* GetElem(LinkList L,int i) {
if (i < 1)
return NULL;
LNode* p = L;
int j = 1;//j是从1开始的,因为没有头结点,直接从第一个节点开始了
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
//按值查找,根据e的值查找到e对应的指针
LNode* LocateElem(LinkList L, int e) {
LNode* p = L->next;
while (p != NULL && p->data != e)
p = p->next;
return p;//找到就返回该节点指针,否则返回NULL
}
//求表的长度
int Length(LinkList L) {
int len = 0;//表长
LNode* p = L;
while (p != NULL) {
p = p->next;
len++;
}
return len;
}
// 尾插法建立不带头节点的单链表
LinkList List_TailInsert(LinkList& L) {
int x; // 定义单链表中的数据类型
LNode* s; // 临时节点
LNode* r = NULL; // 尾指针初始化为空
printf("请您输入要插入的元素:");
scanf("%d", &x);
L = NULL; // 初始化为空表
while (x != 9999) { // 输入9999表示结束
s = (LNode*)malloc(sizeof(LNode));
if (s == NULL) {
printf("内存分配失败!\n");
return L;
}
s->data = x;
s->next = NULL;
if (L == NULL) {
L = s; // 如果链表为空,第一个节点为头节点
}
else {
r->next = s; // 否则,将新节点插入到尾部
}
r = s; // 更新尾指针
printf("请您输入要插入的元素:");
scanf("%d", &x);
}
return L;
}
//头插法创建单链表,每回都在头结点后插
LinkList List_HeadInsert(LinkList& L) {
int x; //定义一个变量来存储要插入的值
LNode* s; //定义在循环外面,能加快程序的运行速度
L = (LNode*)malloc(sizeof(LNode));
L = NULL;
printf("请您输入要插入的元素:");
scanf("%d", &x);
while (x != 9999) { //输入9999表示结束
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = L;
L = s;
printf("请您输入要插入的元素:");
scanf("%d", &x);
}
return L;
}
//清空表
void CleanList(LinkList& L) {
LNode* p;
int e;
while (L != NULL) {
p = L;
L = L->next;
printf("删除的元素值为:%d\n", p->data);
free(p);
}
PrintList(L);
}
int main() {
// 定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入一些元素
InsertList(L, 1, 10);
InsertList(L, 2, 20);
InsertList(L, 3, 30);
InsertList(L, 2, 15); // 插入在第二个位置
printf("链表内容:");
PrintList(L);
// 删除一些元素
int e;
ListDelete(L, 2, e); // 删除第二个位置的元素
printf("删除第二个位置的元素:%d\n", e);
printf("链表内容:\n");
PrintList(L);
// 在第一个节点前插入元素
InsertPriorNode(L->next, 5);
printf("在第一个节点前插入5:");
PrintList(L);
// 删除指定节点
DeleteNode(L->next, e);
printf("删除第一个节点后的节点,其值为:%d\n", e);
printf("链表内容:\n");
PrintList(L);
//按值查找元素的地址
printf("20这个元素的地址为:%d\n", LocateElem(L, 20));
printf("20元素标准地址:%d\n",GetElem(L,2));
//打印单链表的长度
printf("表长为:%d", Length(L));
//清空表
printf("下面是清空表操作:\n");
CleanList(L);
// 检查链表是否为空
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
//检验后插法
List_TailInsert(L);
PrintList(L);
//检验头插法
CleanList(L);
List_HeadInsert(L);
PrintList(L);
return 0;
}
结果:
11.带头结点的单链表的逆置
代码:
#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 InsertList(LinkList& L, int i, int e);
bool InsertNestNode(LNode* p, int e);
bool InsertPriorNode(LNode* p, int e);
bool ListDelete(LinkList& L, int i, int& e);
bool DeleteNode(LinkList& L,LNode* p, int& e);
bool PrintList(LinkList L);
LNode* GetElem(LinkList L, int i);
LNode* LocateElem(LinkList L, int e);
int Length(LinkList L);
LinkList List_TailInsert(LinkList& L);
LinkList List_HeadInsert(LinkList& L);
void CleanList(LinkList& L);
void ReverseList(LinkList& l);
//初始化
bool InitList(LinkList& L) {
//申请一篇空间来存储存储头节点,并使L指向这个节点
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = NULL;
return true;
}
//检查单链表是否为空
bool Empty(LinkList L) {
return (L->next == NULL);
}
//插入,在第i个位置插入元素e
bool InsertList(LinkList& L, int i, int e) {
//判断i范围是否合法
if (i < 1)
return false;
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
return InsertNestNode(p, e);
}
//指定节点的后插操作,在p节点之后插入元素e
bool InsertNestNode(LNode* p, int e) {
//处理当插入位置的前一个节点不存在
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL)
return false;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//前插操作:在p结点前面插入元素e,(还是后插,只是把里面的数据换一下顺序)
bool InsertPriorNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
s->data = p->data; //将p中的元素复制到s中
p->next = s; //新节点s连到p之后
p->data = e; //p中元素覆盖为e
return true;
}
//按位序删除
bool ListDelete(LinkList& L, int i, int &e) {
if (i < 1)
return false;
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode* q = p->next;
p->next = q->next;
e = q->data;
free(q);
return true;
}
//删除指定节点p
bool DeleteNode(LinkList& L,LNode* p, int& e) {
if (p == NULL)
return false;
if (p->next == NULL) {
// 如果p是最后一个节点,找到p的前驱节点
LNode* prev = L;
while (prev->next != p) {
prev = prev->next;
}
prev->next = NULL;
e = p->data;
free(p);
return true;
}
else {
LNode* q = p->next;
if (p == NULL || q == NULL)
return false;
p->data = q->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放后继节点的存储空间
return true;
}
}
//打印单链表的元素
bool PrintList(LinkList L) {
printf("当前链表内的元素如下:\n");
LNode* p = L->next;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
return true;
}
//按位查找,查找到第i个元素
LNode* GetElem(LinkList L, int i) {
if (i < 0)//这必须是i<0,
//因为考虑到带头结点的调用此函数传入的参数是i-1,所以当插入第一个节点时,GetElem函数里面的i值为0,所以是i<0
//如果写写i<1,则在第一个位置插入则回返回null,最终插入失败。
return NULL;
LNode* p = L;
int j = 0; //j是从0开始的,因为有头结点,默认头结点是第0个结点
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
//按值查找,根据e的值查找到e对应的指针
LNode* LocateElem(LinkList L,int e) {
LNode* p = L->next;
while (p != NULL && p->data != e)
p = p->next;
return p; //找到就返回该节点指针,否则返回NULL
}
//求表的长度
int Length(LinkList L) {
int len = 0;//表长
LNode* p = L;
while (p->next!=NULL) {
p = p->next;
len++;
}
return len;
}
//尾插法建立单链表 法一r,s指针交替
LinkList List_TailInsert(LinkList &L) {
int x; //定义单链表中的数据类型
L = (LNode*)malloc(sizeof(LNode));
LNode* s, * r = L;
printf("请您输入要插入的元素:");
scanf("%d",&x);
while (x!=9999) { //输入9999表示结束
s= (LNode*)malloc(sizeof(LNode));
s->data = x;
r->next = s; //让s结点指向第一个元素的位置,r还是指向头结点
r = s; //r和s指向一样
printf("请您输入要插入的元素:");
scanf("%d", &x);
}
r->next = NULL;
return L;
}
//头插法创建单链表,每回都在头结点后插
LinkList List_HeadInsert(LinkList &L) {
int x; //定义一个变量来存储要插入的值
LNode* s; //定义在循环外面,能加快程序的运行速度
L = (LNode*)malloc(sizeof(LNode));
L->next = NULL;
printf("请您输入要插入的元素:");
scanf("%d", &x);
while (x!=9999) { //输入9999表示结束
s= (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next= L->next;
L->next = s;
printf("请您输入要插入的元素:");
scanf("%d", &x);
}
return L;
}
//清空表
void CleanList(LinkList &L) {
int e;
while (L->next!= NULL) {
ListDelete(L, 1, e);
printf("删除的元素值为:%d\n", e);
}
PrintList(L);
}
//逆置双链表
void ReverseList(LinkList& L) {
if (L == NULL || L->next == NULL) {
return; // 链表为空或只有一个元素时,无需逆置
}
LNode* prev = NULL;
LNode* curr = L->next;
LNode* next = NULL;
while (curr != NULL) {
next = curr->next; // 保存下一个节点
curr->next = prev; // 当前节点指向前一个节点
prev = curr; // 前一个节点移动到当前节点
curr = next; // 当前节点移动到下一个节点
}
L->next = prev; // 头节点指向新的头节点
}
int main() {
// 定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入一些元素
printf("%dhhh\n", InsertList(L, 1, 10));
InsertList(L, 2, 20);
InsertList(L, 3, 30);
InsertList(L, 2, 15); // 插入在第二个位置
printf("链表内容:");
PrintList(L);
// 删除一些元素
int e;
ListDelete(L, 2, e); // 删除第二个位置的元素
printf("删除第二个位置的元素:%d\n", e);
printf("链表内容:\n");
PrintList(L);
// 在第一个节点前插入元素
InsertPriorNode(L->next, 5);
printf("在第一个节点前插入5:");
PrintList(L);
// 删除指定节点
DeleteNode(L, L->next, e);
printf("删除第一个节点后的节点,其值为:%d\n", e);
printf("链表内容:\n");
PrintList(L);
//按值查找元素的地址
printf("20这个元素的地址为:%d\n", LocateElem(L, 20));
printf("20元素标准地址:%d\n", GetElem(L, 2));
//打印单链表的长度
printf("表长为:%d\n", Length(L));
//清空表
printf("下面是清空表操作:\n");
CleanList(L);
// 检查链表是否为空
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
//检验后插法
List_TailInsert(L);
PrintList(L);
//检验头插法
CleanList(L);
List_HeadInsert(L);
PrintList(L);
//检验逆置
printf("下面是逆置操作:\n");
ReverseList(L);
PrintList(L);
return 0;
}
结果:
12.不带头结点的单链表逆置操作
代码:
#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 InsertList(LinkList& L, int i, int e);
bool InsertNestNode(LNode* p, int e);
bool InsertPriorNode(LNode* p, int e);
bool ListDelete(LinkList& L, int i, int& e);
bool DeleteNode(LNode* p, int& e);
bool PrintList(LinkList L);
LNode* GetElem(LinkList L, int i);
LNode* LocateElem(LinkList L, int e);
int Length(LinkList L);
LinkList List_TailInsert(LinkList& L);
LinkList List_HeadInsert(LinkList& L);
void CleanList(LinkList& L);
void ReverseList(LinkList& L);
//初始化单链表
bool InitList(LinkList &L) {
//头指针赋值为空
L = NULL;
return true;
}
//判断单链表是否为空
bool Empty(LinkList L) {
return (L == NULL);
}
bool InsertList(LinkList& L,int i,int e ) {
if (i < 1)
return false;
//处理在第一个节点处插入
if (i == 1) {
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
return true;
}
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
return InsertNestNode(p, e);
}
//后插操作
bool InsertNestNode(LNode* p, int e) {
//处理当插入位置的前一个节点不存在
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//前插操作:在p结点前面插入元素e,(还是后插,只是把里面的数据换一下顺序)
bool InsertPriorNode(LNode* p, int e) {
if (p == NULL)
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
s->data = p->data; //将p中的元素复制到s中
p->next = s; //新节点s连到p之后
p->data = e; //p中元素覆盖为e
return true;
}
//按位序删除
bool ListDelete(LinkList& L, int i, int& e) {
if (i < 1)
return false;
// 删除第一个节点的特殊处理
if (i == 1) {
if (L == NULL)
return false;
LNode* q = L;
e = L->data;
L = L->next;
free(q);
return true;
}
LNode* p = GetElem(L, i - 1);//找到第i-1个结点
if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode* q = p->next;
p->next = q->next;
e = q->data;
free(q);
return true;
}
//删除指定节点p
bool DeleteNode(LNode* p, int& e) {
//此方法不能删除最后一个节点!注意,只能传入头指针从头遍历来删除最后的结点
LNode* q = p->next;
if (p == NULL || q == NULL)
return false;
p->data = q->data; //和后继节点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放后继节点的存储空间
return true;
}
//打印单链表的元素
bool PrintList(LinkList L) {
LNode* p = L;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
printf("NULL\n");
return true;
}
//按位查找,查找到第i个元素
LNode* GetElem(LinkList L,int i) {
if (i < 1)
return NULL;
LNode* p = L;
int j = 1;//j是从1开始的,因为没有头结点,直接从第一个节点开始了
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
//按值查找,根据e的值查找到e对应的指针
LNode* LocateElem(LinkList L, int e) {
LNode* p = L->next;
while (p != NULL && p->data != e)
p = p->next;
return p;//找到就返回该节点指针,否则返回NULL
}
//求表的长度
int Length(LinkList L) {
int len = 0;//表长
LNode* p = L;
while (p != NULL) {
p = p->next;
len++;
}
return len;
}
// 尾插法建立不带头节点的单链表
LinkList List_TailInsert(LinkList& L) {
int x; // 定义单链表中的数据类型
LNode* s; // 临时节点
LNode* r = NULL; // 尾指针初始化为空
printf("请您输入要插入的元素:");
scanf("%d", &x);
L = NULL; // 初始化为空表
while (x != 9999) { // 输入9999表示结束
s = (LNode*)malloc(sizeof(LNode));
if (s == NULL) {
printf("内存分配失败!\n");
return L;
}
s->data = x;
s->next = NULL;
if (L == NULL) {
L = s; // 如果链表为空,第一个节点为头节点
}
else {
r->next = s; // 否则,将新节点插入到尾部
}
r = s; // 更新尾指针
printf("请您输入要插入的元素:");
scanf("%d", &x);
}
return L;
}
//头插法创建单链表,每回都在头结点后插
LinkList List_HeadInsert(LinkList& L) {
int x; //定义一个变量来存储要插入的值
LNode* s; //定义在循环外面,能加快程序的运行速度
L = (LNode*)malloc(sizeof(LNode));
L = NULL;
printf("请您输入要插入的元素:");
scanf("%d", &x);
while (x != 9999) { //输入9999表示结束
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = L;
L = s;
printf("请您输入要插入的元素:");
scanf("%d", &x);
}
return L;
}
//清空表
void CleanList(LinkList& L) {
LNode* p;
while (L != NULL) {
p = L;
L = L->next;
printf("删除的元素值为:%d\n", p->data);
free(p);
}
PrintList(L);
}
//逆置双链表
void ReverseList(LinkList& L) {
if (L == NULL || L->next == NULL) {
return; // 链表为空或只有一个元素时,无需逆置
}
LNode* prev = NULL;
LNode* curr = L;
LNode* next = NULL;
while (curr != NULL) {
next = curr->next; // 保存下一个节点
curr->next = prev; // 当前节点指向前一个节点
prev = curr; // 前一个节点移动到当前节点
curr = next; // 当前节点移动到下一个节点
}
L = prev; // 头节点指向新的头节点
}
int main() {
// 定义头指针
LinkList L;
InitList(L);
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
// 插入一些元素
InsertList(L, 1, 10);
InsertList(L, 2, 20);
InsertList(L, 3, 30);
InsertList(L, 2, 15); // 插入在第二个位置
printf("链表内容:");
PrintList(L);
// 删除一些元素
int e;
ListDelete(L, 2, e); // 删除第二个位置的元素
printf("删除第二个位置的元素:%d\n", e);
printf("链表内容:\n");
PrintList(L);
// 在第一个节点前插入元素
InsertPriorNode(L->next, 5);
printf("在第一个节点前插入5:");
PrintList(L);
// 删除指定节点
DeleteNode(L->next, e);
printf("删除第一个节点后的节点,其值为:%d\n", e);
printf("链表内容:\n");
PrintList(L);
//按值查找元素的地址
printf("20这个元素的地址为:%d\n", LocateElem(L, 20));
printf("20元素标准地址:%d\n",GetElem(L,2));
//打印单链表的长度
printf("表长为:%d", Length(L));
//清空表
printf("下面是清空表操作:\n");
CleanList(L);
// 检查链表是否为空
printf("查看单链表是否为空:%s\n", Empty(L) ? "是" : "否");
//检验后插法
List_TailInsert(L);
PrintList(L);
//检验头插法
CleanList(L);
List_HeadInsert(L);
PrintList(L);
//检验逆置
printf("下面是逆置操作:\n");
ReverseList(L);
PrintList(L);
return 0;
}
结果:
结束~
有收获的宝宝留个赞赞再走吧~
不胜感激~