嵌入式-单向链表

链表增删改查

linklistfunc.c文件

#include <stdio.h>
#include <stdlib.h>
#include "./linklistfunc.h"

                                                                  
//创建单链表
Linklist* create_linklist(void)
{
    //申请堆空间
    Linklist *head = (Linklist*)malloc(sizeof(Linklist));
//判断链表是否为空
    if(NULL == head)
    {
        printf("链表为空,创建数据链表失败\n");
        return NULL;
    }

    //初始化头结点中的len
    head->text.len = 0;
    head->next= NULL;

    return head;


}

//从头部插入
void insert_linklist(Linklist *head,datatype num)
{
    //先创建结点
    Linklist* temp =(Linklist*)malloc(sizeof(Linklist));
    
    if(NULL == temp)
    {
    printf("创建结点失败,头插失败\n");
    return ;

    }
    temp->text.data = num;//数据域赋值
    temp->next = NULL;//指针域赋值

//先让temp的next指针存储head->这个结点的首地址
    temp->next = head->next;

    head->next =temp;//头结点的指针域存储temp结点的地址

//更新头结点中链表的长度
    head->text.len++;
    
    return ;
}


//头删法
void delete_linklist(Linklist *head)
{                                                              
    //判断链表是否为空
    if(head->next==NULL)
    {
        printf("链表为空,删除失败\n");

        return;
    }

    //先将要释放的结点地址另存
    Linklist*temp=head->next;
    head->next=head->next->next;//head->next=temp->next;

    //释放结点
    free(temp);
    temp = NULL;

    //更新头结点中链表长度
    head->text.len--;

    return ;
}
//尾删法                                           
void delete_linklist2(Linklist* head)
{
    //判断链表是否为空
    if(head->next==NULL)
    {
        printf("链表为空,删除失败\n");
        return;
    }

    //循环方式找到倒数2个结点p
    Linklist* p=head;
    while(p->next->next != NULL)
    {
        p=p->next;
    }

//释放结点
    Linklist* temp=p->next;
    p->next = NULL;

    free(temp);

    //free(p->next);
    p->next= NULL;

    //更新头结点中链表的长度
    head->text.len--;

    return;
}
//尾插法插入数据
void insert_linklist2(Linklist *head,datatype num)
{
    //先创建结点                                                     
    Linklist* temp =(Linklist*)malloc(sizeof(Linklist));

    if(NULL == temp)
    {
    printf("创建结点失败,尾插失败\n");
    return ;

    }
    temp->text.data = num;//数据域赋值
    temp->next = NULL;//指针域赋值


    Linklist* p = head;
    while(p->next != NULL)//判断p->next是否为NULL,空则跳出循环
    {
        p = p->next;
    }
    temp->next =p->next;//temp->next=NULL;
    p->next=temp;

    //更新头结点中链表的长度
    head->text.len++;

    return ;

}
 //遍历链表
 void show_linklist(Linklist* head)
 {
     Linklist *p = head;
     while(p->next != NULL)                                              
     {
         p=p->next;
         printf("%d ",p->text.data);
     }
     putchar(10);
     return ;
 }


 //按位置插入Bitwise按位
 void insert_linklistBitwise(Linklist* head,datatype num,int n)
 {
 
 //判断插入的位置是否合法
 if(n<1 || n>head->text.len+1)
     {
         printf("插入位置非法\n");
     }
 //向第n个位置插入,则需要找到第n-1个位置插入
 //若在找的途中,p指向NULL,则代表插入位置非法
 
     Linklist *p = head;
     for(int i=0;i<n-1;i++)
     {
         p=p->next;
         if(NULL == p)
         {
             printf("插入位置非法\n");
 
             return ;
         }
     }
     //先创建结点
     Linklist* temp =(Linklist*)malloc(sizeof(Linklist));
 
     if(NULL == temp)
     {
     printf("创建结点失败,按位置插入失败\n");
     return ;
 
     }
     temp->text.data = num;//数据域赋值
     temp->next = NULL;//指针域赋值


    temp->next=p->next;
    p->next = temp;

    //更新头结点中链表的长度
    head->text.len++;                                          

    return ;
}



//按位置删除
void delete_linklistBitwise(Linklist* head,int n)
{
    //判断链表是否为空
    if(NULL ==head->next)
    {
        printf("链表为空,删除失败\n");

        return ;
    }
    //判断删除位置是否合法
    if(n<1)
    {
        printf("删除位置非法\n");

        return;
    }
    //找到要删除的位置的前一个结点位置
    //删除第n个位置,则需要找到第n-1个位置
    Linklist *p = head;
    for(int i=0;i<n-1;i++)
    {
        p=p->next;

        if(p->next == NULL)
        {
            printf("当前插入的位置非法\n");
            return ;
        }

    }

                                                     
    //p指向的是要删除的结点的前一个位置
    Linklist* temp=p->next;
    p->next=temp->next;
    free(temp);
    temp=NULL;

    //更新头结点中链表的长度
    head->text.len--;

    return ;
}

 //直接插入排序(升序)
 void insert_linklistsort(Linklist *head,datatype num)
 {
     Linklist* p=head;
     while(p->next !=NULL)
     {
         if(num<p->next->text.data)
         {
             break;
         }
         p=p->next;
     }
     //创建结点
     Linklist* temp=(Linklist*)malloc(sizeof(Linklist));
     if(temp ==NULL)
     {
         printf("插入节点失败");
         return ;
     }
     temp->text.data=num;//数据域
     temp->next=NULL;//指针域
 
 
     //插入数据
     temp->next=p->next;
     p->next = temp;
 
     //更新结点
     head->text.len++;
 
 
     return ;
 }


//链表翻转(头删头插)(不使用辅助链表)
void recycle_linklist(Linklist* head)
{
    //从源头链表做头删,“新链表”做头插
    //新链表实际上是将原链表的头结点单独独立出来       

    Linklist *p,*q;
    p = head->next;
    head->next = NULL;
    //循环头插法,将结点P插入到新的链表中
    while(p!=NULL)
    {
        q=p->next;//将p结点的最后一个结点备份

        p->next = head->next;
        head->next=p;

        p=q;

    }

    printf("链表翻转完成\n");

    return ;
}


//找中结点:快慢指针
datatype middlenode_linklist(Linklist *head)
{
    if(head->next ==  NULL)
    {
        printf("链表为空,没有空间结点\n");
        return (datatype)-1;
    }
    Linklist *low,*fast;
    low=fast=head->next;

    while(fast!=NULL&&fast->next!=NULL)
    {
        low=low->next;
        fast=fast->next->next;

    }
//返回的值就是中间结点
    return low->text.data;
}

//释放链表
void free_linklist(Linklist **phead)
{
//循环头删,直到链表为空
//最后释放头结点,将头指针置为NULL
    //phead指向head
    //*phead代表访问head空间
    Linklist* temp =NULL;
    while((*phead)->next!=NULL)
    {
        temp=(*phead)->next;
        (*phead)->next = temp->next;
        free(temp);
        (*phead)->text.len--;
    }
    free(*phead);
    *phead = NULL;
    return;

}


linklistfunc.h

 #ifndef __LINKLIST__
 #define __LINKLIST__
 
 
 typedef int datatype;
 
 
 
 //结构体
 typedef struct lklist
 {
     union
     {
         int len;//若是头结点,则是用len存储链表长度
         datatype data;//若是有效数据结点,则用data存放有效数据
 
     }text;//数据域
 
     struct lklist* next;//指针域
 }Linklist;                                                               
//创建单链表
Linklist* create_linklist(void);

//从头部插入
void insert_linklist(Linklist *head,datatype num);
                                                                    

//遍历链表
void show_linklist(Linklist* head);

//尾插法插入数据
void insert_linklist2(Linklist *head,datatype num);

//头删法
void delete_linklist(Linklist *head);

//尾删法
void delete_linklist2(Linklist* head);

//按位置插入Bitwise按位
void insert_linklistBitwise(Linklist* head,datatype num,int n);

//按位置删除
 void delete_linklistBitwise(Linklist* head,int n);


//直接插入排序(升序)
void insert_linklistsort(Linklist *head,datatype num);

//链表翻转(头删头插)(不使用辅助链表)
void recycle_linklist(Linklist* head);

//找中结点:快慢指针
datatype middlenode_linklist(Linklist *head);

//释放链表
void free_linklist(Linklist **phead);

//直接插入排序(升序)
void insert_linklistsort(Linklist *head,datatype num);

//链表翻转(头删头插)(不使用辅助链表)
void recycle_linklist(Linklist* head);

//找中结点:快慢指针
datatype middlenode_linklist(Linklist *head);

//释放链表
void free_linklist(Linklist **phead);



#endif
           

linklist_main.c

#include <stdio.h>
#include <stdlib.h>

#include "./linklistfunc.h"

int main(int argc, const char *argv[])
{
    Linklist* head;

    head = create_linklist();

    //头部插入数据
    insert_linklist(head,10);
    insert_linklist(head,20);
    insert_linklist(head,30);
    insert_linklist(head,40);
    insert_linklist(head,50);
    insert_linklist(head,60);
    insert_linklist(head,70);
    insert_linklist(head,80);
    show_linklist(head);
 
 //尾插
     insert_linklist2(head,500);
     insert_linklist2(head,600);
     show_linklist(head);
                                                          
     //头删
     delete_linklist(head);
     show_linklist(head);
 
 //尾删
     delete_linklist2(head);
     show_linklist(head);
 
 //按位置插入
     insert_linklistBitwise(head,100,3);
     show_linklist(head);
 
 
 
 //按位置删除
     delete_linklistBitwise(head,4);
     show_linklist(head);
 


    //直接插入排序(升序)
    insert_linklistsort(head,90);   
    show_linklist(head);

    insert_linklistsort(head,12);                       
    show_linklist(head);

    insert_linklistsort(head,100);
    show_linklist(head);

    insert_linklistsort(head,9);    
    show_linklist(head);

    insert_linklistsort(head,99);
    show_linklist(head);





    //链表翻转
    recycle_linklist(head);
    show_linklist(head);
    
    

//快慢指针
    middlenode_linklist(head);
    show_linklist(head);

    //释放链表
    free_linklist(&head);
    printf("%p \n",head);



     return 0;
 }
                  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值