寻找链表中最小data并删除

/*****************************************************************
*
*      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;
}

posted @ 2024-04-22 21:33  不懂小白在线记录  阅读(14)  评论(0)    收藏  举报