/*****************************************************************
*
* file name :struct_Sequential_storage.c
* authour :yq_dyx@163.com
* date :2024.04.19
* function :设计一个函数,实现对链表的增删改查的功能,以结构体的形式存储数组首元素地址,数组总容量,已经有效元素个数。
* note :None
* CopyRight (c) 2024 yq_dyx@163.com All Right Reseverd
*
******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int DataType_t;
typedef struct LinkedList
{
DataType_t data; // 数据域
struct LinkedList *next; // 指针域
}LList_t;
//创建头结点
LList_t * Linkedlist_creat()
{
LList_t *head = (LList_t *)malloc(sizeof(LList_t));
if(NULL == head)
{
perror("calloc head is error\n"); // 分配内存失败
exit(1);
}
head->next = NULL; //头结点初始化
}
//创建新节点
LList_t * LinkedList_NewNode(DataType_t data)
{
LList_t *New =(LList_t *)malloc(sizeof(LList_t));
if(NULL == New)
{
perror("calloc NewNode is error\n"); // 分配内存失败
return NULL;
}
New->data = data; //新结点数据域初始化
New->next = NULL; //新结点指针域初始化
}
//头插
bool LinkedList_HeadInsert(LList_t *head,DataType_t data)
{
LList_t *New = LinkedList_NewNode(data); // 创建新节点, 并初始化
if(NULL == New) //判断新节点是否创建成功
{
printf("calloc NewNode is failed\n");
return false;
}
if(NULL == head->next) //判断链表是否为空
{
head->next = New;
return true;
}
New->next = head->next;
head->next = New;
return true;
}
//尾插
bool LinkedList_TailInsert(LList_t *head,DataType_t data)
{
int i = 0;
LList_t *New = LinkedList_NewNode(data);
if(NULL == New)
{
printf("calloc NewNode is failed\n");
return false;
}
if(NULL == head->next) //判断链表是否为空,为空直接退出
{
printf("linkedlist is empty\n");
return false;
}
LList_t *phead = head; // 备份头结点
while(phead->next)
{
phead = phead->next; // 遍历链表
}
phead->next = New;
return true;
}
//中间插
bool LinkedList_DestInsert(LList_t *head,DataType_t data,DataType_t datax)
{
int i = 0;
LList_t *New = LinkedList_NewNode(datax);
if(NULL == New)
{
printf("calloc NewNode is failed\n");
return false;
}
if(NULL == head->next) //判断链表是否为空,为空直接退出
{
printf("linkedlist is empty\n");
return false;
}
LList_t *phead = head; // 备份头结点
LList_t *p = head; // 备份头结点
while(phead->next) // 遍历链表
{
phead = phead->next;
if(i > 0)
{
p = p->next; //等phead遍历一次以后再参与遍历,寻找循环结束时当前结点的前一个结点
}
i++; //当i = 1时进行遍历
if(phead->data == data) // 判断是否找到插入位置
break;
}
New->next = phead->next;
phead->next = New;
}
//删除指定节点
bool LinkedList_DestDelete(LList_t *head,DataType_t data)
{
int i = 0;
if(NULL == head->next) //判断链表是否为空,为空直接退出
{
printf("linkedlist is empty\n");
return false;
}
LList_t *phead = head->next; // 备份头结点
LList_t *p = head; // 备份头结点
while(phead->data != data)
{
phead = phead->next; // 遍历链表
if(i > 0)
{
p = p->next; //等phead遍历一次以后再参与遍历,寻找循环结束时当前结点的前一个结点
}
i++; //当i = 1时进行遍历
}
p->next = phead->next; //将指定的结点的next域指向结点赋值给上一个结点
phead->next = NULL; //对删除的结点释放,防止内存泄漏,以及段错误
free(phead);
return true;
}
//删除首节点
bool LinkedList_HeadDelete(LList_t *head)
{
if(NULL == head->next) //判断链表是否为空,为空直接退出
{
printf("linkedlist is empty\n");
return false;
}
LList_t *phead = head->next; // 备份头结点
LList_t *p = head; // 备份头结点
head->next = phead->next;
phead->next = NULL; //对删除的结点释放,防止内存泄漏,以及段错误
free(phead);
return true;
}
//删除尾节点
bool LinkedList_TailDelete(LList_t *head)
{
int i = 0;
if(NULL == head->next) //判断链表是否为空,为空直接退出
{
printf("linkedlist is empty\n");
return false;
}
LList_t *phead = head; // 备份头结点
LList_t *p = head; // 备份头结点
while(phead->next)
{
phead = phead->next; // 遍历链表
if(i++ > 0) //当i = 1时进行遍历
{
p = p->next; //等phead遍历一次以后再参与遍历,寻找循环结束时当前结点的前一个结点
}
}
p->next = NULL; //断开最后一个节点
free(phead); //对删除的结点释放,防止内存泄漏,以及段错误
return true;
}
//打印链表
void LinkedList_Print(LList_t *head)
{
LList_t *phead = head; // 备份头结点
while(phead->next)
{
phead = phead->next; // 遍历链表
printf(" %d",phead->data); // 打印链表
}
printf("\n");
}
//删除data最小的结点
bool LinkedList_MintDelete(LList_t *head)
{
int i = 0;
int min = head->next->data;
printf("min = %d\n",min);
if(NULL == head->next) //判断链表是否为空,为空直接退出
{
printf("linkedlist is empty\n");
return false;
}
LList_t *phead = head; // 备份头结点
LList_t *p = head; // 备份头结点
while(phead->next)
{
phead = phead->next; // 遍历链表
min = (phead->data) <= min ? (phead->data) : min; //寻找最小的data
}
LList_t *ph = head->next; // 备份头结点
while(ph->data != min)
{
ph = ph->next; // 遍历链表
if(i > 0)
{
p = p->next; //等phead遍历一次以后再参与遍历,寻找循环结束时当前结点的前一个结点
}
i++;
if(ph->next == NULL) // 判断是否找到插入位置
{
if(ph->data != min)
printf("min is not found\n");
return false;
}
//当i = 1时进行遍历
}
p->next = ph->next; //将指定的结点的next域指向结点赋值给上一个结点
ph->next = NULL; //对删除的结点释放,防止内存泄漏,以及段错误
free(ph);
return true;
}
int main()
{
LList_t * Head = Linkedlist_creat();
LinkedList_HeadInsert(Head,8);
LinkedList_HeadInsert(Head,5);
LinkedList_HeadInsert(Head,3);
LinkedList_HeadInsert(Head,7);
LinkedList_Print(Head); //7 3 5 8
LinkedList_TailInsert(Head,42);
LinkedList_TailInsert(Head,99);
LinkedList_TailInsert(Head,87);
LinkedList_TailInsert(Head,63);
LinkedList_Print(Head); //7 3 5 8 42 99 87 63
LinkedList_DestInsert(Head,42,11);
LinkedList_DestInsert(Head,3,33);
LinkedList_DestInsert(Head,87,61);
LinkedList_Print(Head); //7 3 33 5 8 42 11 99 87 61 63
LinkedList_DestDelete(Head,42);
LinkedList_Print(Head);
LinkedList_HeadDelete(Head);
LinkedList_Print(Head);
LinkedList_TailDelete(Head);
LinkedList_Print(Head);// 3 33 5 8 11 99 87 61
LinkedList_MintDelete(Head);
LinkedList_Print(Head); // 33 5 8 11 99 87 61
return 0;
}