#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <malloc.h>
/*自定义类型*/
typedef int Status;
typedef struct Link {
Status data;
struct Link *next;
} link;
typedef struct LNode {
Status data;
struct LNode *next;
} LNode, *LinkList;
/*自定义类型end*/
/* 预定义函数 */
link* initLink(); // 初始化 单链表
link* InsetElem(link *p, Status location, Status elem); // 插入元素 单链表
link* deleteElem(link *p, Status location); // 删除元素 单链表
Status LinkLength(link *p); // 查询表长度 单链表
Status SelectElem(link* p, Status elem); // 查询元素位置 单链表
link* AmendElem(link* p, Status location, Status nextElem); // 修改元素数据 单链表
Status DestroyLink(link *p); // 销毁 单链表
Status ClearList(link *p); // 清空 链表
Status judgeLinkEmpty(link* p); // 判断链表是否为空
LinkList HeadInsert(LinkList L, Status n); // 头插法 单链表
LinkList FooterInsert(LinkList L, Status n); // 尾插法 单链表
LNode* initLinkList1(LinkList J); // 初始化循环单链表表J
LNode* initLinkList(LinkList K); // 初始化循环单链表表K
LinkList Connect(LinkList J, LinkList K); // 合并JK循环单链表
void print(link* p); // 输出表信息
void print1(LNode *L); // 输出循环表
/* 预定义函数end */
// 链表增删改查
int main(int argc, char const *argv[])
{
printf("初始化链表:");
link * p = initLink();
print(p);
printf("链表插入元素:");
link * InsetElemData = InsetElem(p, 5, 5);
print(InsetElemData);
printf("链表删除元素:");
link * deleteElemData = deleteElem(InsetElemData, 0);
print(deleteElemData);
printf("查询链表长度:");
Status LinkLengthData = LinkLength(deleteElemData);
printf("链表长度:%d\n", LinkLengthData);
printf("链表查询元素:");
Status SelectElemData = SelectElem(deleteElemData, 5);
if (SelectElemData == -1)
{
printf("查询元素不存在");
}else printf("查询元素在第 <%d> 位\n", SelectElemData);
printf("链表修改元素:");
link *AmendElemData = AmendElem(deleteElemData, 5, 520);
print(AmendElemData);
/*
printf("销毁列表:");
Status DestroyLinkData = DestroyLink(deleteElemData);
if (DestroyLinkData == 1)
printf("deleteElemData单链表已经销毁!\n");
*/
printf("清空链表:");
Status ClearListData = ClearList(deleteElemData);
if (ClearListData == 1)
printf("deleteElemData单链表已经清空!\n");
printf("判断链表是否为空:");
Status JLEData = judgeLinkEmpty(deleteElemData);
if (JLEData == 1)
{
printf("deleteElemData单链表为空!\n");
}else printf("deleteElemData单链表不为空!\n");
LinkList L, J, K, ConnectData;
link *LData = (link*)HeadInsert(L, 5);
printf("头插法简历链表:");
print(LData);
link *FooterInsertData = (link*)FooterInsert(L, 5);
printf("尾插法简历链表:");
print(FooterInsertData);
printf("初始化链表:\n");
J = initLinkList(J);
K = initLinkList1(K);
print1(J);
print1(K);
printf("合并循环表:\n");
ConnectData = Connect(J, K);
print1(ConnectData);
return 0;
}
/* 初始化单链表 */
link* initLink()
{
Status i;
link * p = (link*) malloc(sizeof(link)); // 创建头节点
p->data = 4; // 头结点数据域一般存储数据长度
link * temp = p; // 创建头指针,指向头节点
/* 生成链表 */
for (i = 0; i < 5; i++)
{
link * arr = (link*) malloc(sizeof(link)); // 创建节点
arr->data = i; // 给arr[i]的data赋值
arr->next = NULL; // 给arr[i]的指针置空,用于保存下一个结点地址
temp->next = arr; // 将arr[i]装入到头指针的地址temp->next中,同时也会存储到头结点p的next下,一直持续到结束
temp = temp->next; // 后,再将temp->next替换为头指针继续下一层循环,
}
return p;
}
/*
*插入元素 单链表:
* link *p: 链表数据
* Status: int类型
* Status location:插入位置
* Status elem: 插入元素
* */
link* InsetElem(link *p, Status location, Status elem)
{
Status i;
link * temp = p; // 创建临时节点,指向链表
for (i = 0; i < location; i++) // 遍历,获取添加点的前地址
{
if (temp == NULL) // 判断传入的链表是否为空
{
printf("插入位置无效\n");
return p;
}
temp = temp->next; // 获取插入前元素地址
}
link * addElem = (link*) malloc(sizeof(link)); // 创建结点存储添加元素
addElem->data = elem; // 添加插入元素value值
addElem->next = temp->next; // 替换元素地址
temp->next = addElem; // 保存元素入指针
return p;
}
/*
*删除元素 单链表
* link*p: 要修改的链表
* Status location:位置
* */
link* deleteElem(link*p, Status location)
{
Status i;
link * temp = p; // 创建临时节点指向链表
for (i = 0; i < location; i++) // 遍历删除位置,获取删除前一个元素的地址
{
temp = temp->next; // 获取插入前元素地址
}
link * delElem = temp->next; // 创建指针指向删除元素地址,防丢失
temp->next = temp->next->next; // 修改删除节点域,将下一个节点指针与替换是一个节点指针域
free(delElem); // 释放内存
return p;
}
/* 查询表长度 */
Status LinkLength(link *p)
{
link *temp = p; // 创建临时节点指向链表
Status i = 0; // 定义记录
while (temp->next != NULL){
i++; // 记录自增
temp = temp->next; // 头指针指向下一节点
}
return i;
}
/*
* 查询元素位置 单链表:
* link* p:查询链表
* Status elem:查询元素
* */
Status SelectElem(link* p, Status elem)
{
link *temp = p; // 创建临时节点指向链表
Status i = 1; // 标记元素查询位置
while (temp->next) // 循环查询链表
{
temp = temp->next; // 更新地址
if (temp->data == elem) // 判断当前地址data是否与查询的elem相同
{
return i; // 相同输出 i;
}
i++; // 不相同 i 自增继续循环
}
return -1; // 都没有输出 -1
}
/*
*修改元素数据 单链表:
* link* p: 要修改的单链表
* Status location:修改元素位置
* Status nextElem:修改后的元素
* */
link* AmendElem(link* p, Status location, Status nextElem)
{
Status i;
link *temp = p; // 创建临时节点
temp = temp->next; // 临时节点指向首元节点
for (i = 1; i < location; i++) // 遍历链表获取修改元素的前一个元素地址
{
temp = temp->next; // 获取修改元素的前一个元素地址
}
temp->data = nextElem; // 修改数据
return p;
}
// 判断链表是否为空
Status judgeLinkEmpty(link* p)
{
link * temp = p; // 创建临时节点
if (temp->next == NULL) // 判断节点指针域是否为空
return true; // 空返回true 非空false
else return false;
}
// 销毁单链表
Status DestroyLink(link *p)
{
link *temp = p; // 创建头指针,指向表p
while (temp->next) /* 循环指针下一地址是否为空 */
{
link * delElem = temp->next; // 创建指针指向删除元素地址,防丢失
temp->next = temp->next->next; // 修改删除节点域,将下一个节点指针与替换是一个节点指针域
free(delElem); // 释放内存
}
return true;
}
// 清空链表
Status ClearList(link *p)
{
link * CurrentNode, *NextNode; // 创建当前指针、指向下一节点指针
CurrentNode = p->next; // 记录首元节点地址
while (CurrentNode != NULL) // 判断是否为空,循环释放所有节点
{
NextNode = CurrentNode->next; // 记录下一节地址
free(CurrentNode); // 释放上一节点
CurrentNode = NextNode; // 重置上一节点记录信息
}
p->next = NULL; // 所有节点释放完成,头节点指针赋值为NULL结束循环;
return true;
}
/*
*头插法(倒序):
* LinkList L: 单链表
* Status n:插入数量
* */
LinkList HeadInsert(LinkList L, Status n)
{
Status i;
LNode *temp;
/* 初始化链表 空表 */
L = (LinkList) malloc(sizeof(LNode)); // 创建头节点
L->next = NULL; // 置空头节点地址
printf("请输入插入元素:");
for (i = n; i > 0; --i)
{
temp = (LinkList) malloc(sizeof(LNode)); // 创建节点
scanf("%d",&temp->data); // 输入插入信息
temp->next = L->next; // 记录上一节点所有地址
L->next = temp; // 将所有节点接入头节点
}
return L;
}
/*
*尾插法(升序):
* LinkList L: 单链表
* Status n:插入数量
* */
LinkList FooterInsert(LinkList L, Status n)
{
LNode * temp;
/* 新建空链表 */
L = (LinkList)malloc(sizeof(LNode)); // 创建
L->next = NULL;
LNode* footer = L; // 创建尾指针指向头结点
/* 循环遍历创建节点 */
printf("请输入插入%d个数字", n);
for (Status i = 0; i < n; i++)
{
temp = (LinkList)malloc(sizeof(LNode)); // 创建节点
temp->next = NULL; // 置空新节点地址
scanf("%d", &temp->data); // 输入节点数据
footer->next = temp; // 新节点插入表尾
footer = temp; // 尾指针指向新节点
}
return L;
}
// 创建表J
LNode* initLinkList(LinkList J)
{
LNode *arr, *footerNext; // 预定义输入数组,尾指针
/* 创建空链表 */
J = (LinkList)malloc(sizeof(LNode)); // 创建头结点
J->next = NULL; // 头节点地址置空
footerNext = J; // 创建尾指针指向头节点,保存循环数据
// 添加数据
for (int i = 0; i < 5; i++)
{
arr = (LinkList)malloc(sizeof(LNode)); // 创建新结点
arr->data = i; // 输入data域值
arr->next = NULL; // 新节点地址置空
footerNext->next = arr; // 尾指针地址指向新节点
footerNext = footerNext->next; // 新节点变成尾指针
}
footerNext->next = J; // 尾节点地址指向头节点,实现循环
return footerNext; // 返回尾指针
}
// 创建表K
LNode* initLinkList1(LinkList K)
{
LNode *arr, *footerNext;
/* 创建空链表 */
K = (LinkList)malloc(sizeof(LNode)); // 创建头结点
K->next = NULL; // 头节点地址置空
footerNext = K; // 创建尾指针指向头节点,保存循环数据
// 添加数据
for (int i = 5; i < 10; i++)
{
arr = (LinkList)malloc(sizeof(LNode)); // 创建新结点
arr->data = i; // 输入data域值
arr->next = NULL; // 新节点地址置空
footerNext->next = arr; // 尾指针下一地址指向新节点,
footerNext = footerNext->next; // 新节点变赋值变成尾节点
}
footerNext->next = K; // 尾节点地址指向头节点,实现循环
return footerNext; // 返回尾指针
}
/* 合并循环单链表:
* LinkList J:表J尾指针
* LinkList K:表K尾指针
* */
LinkList Connect(LinkList J, LinkList K)
{
LNode *LHeadNode; // 创建头指针
LHeadNode = J->next; // 头指针向头节点
J->next = K->next->next; // K表头链接J表尾
free(K->next); // 释放K表头节点
K->next = LHeadNode; // 修改尾指针,表尾地址指向头节点
return K;
}
/*
*输出表信息
* link* p:输出链表
* */
void print(link* p)
{
link *temp = p; //将temp指针重新指向头结点
//只要temp指针指向的结点的next不是Null,就执行输出语句。
while (temp->next)
{
temp = temp->next;
printf("%d\t", temp->data);
}
printf("\n");
}
/*
*输出表信息
* LinkList L:输出链表
* */
void print1(LNode *L)
{
LNode *nextNode = L->next; //将temp指针重新指向头结点
//先输出后判断,当循环到与L相同结束循环。
while (nextNode->next != L )
{
nextNode = nextNode->next;
printf("%d\t", nextNode->data);
}
printf("\n");
}
C语言单链表操作笔记2.0
最新推荐文章于 2022-08-10 17:15:38 发布