天天看点

单向链表(二级指针实现)

#include <stdio.h>
#include <stdlib.h>
typedef struct newlist
{
    int data;
    struct newlist *next;//next指针存储在当前的结构体中,此链表为单链表,且数据按从小到大插入
} onelist;

int insertone(onelist **old_flist,int a)  //传过来的地址是赋值给old_flist的,
{                                        //不用管前边的俩个*,那个只代表类型,之所以用两个是因为首指针的地址不能修改
    onelist *p =(onelist *)malloc(sizeof(onelist));
    p->data = a;
    p->next=NULL;
    onelist * tmp,*q,*flist = * old_flist;//flist=*old_flist(原flist所存储的值,即main函数中flist的值 )
                                          //即让flist指针指向把链表首指针所存储的值当作地址所对应的内存块,即把原首指针所存储的数据存入flist指针中
    if(flist==NULL)                       //如果对flist进行修改,相当于修改flist指针的指向,但并没有修改首指针所存储的值
    {
        * old_flist=p;//修改的是main函数中首指针中所存储的值
    }
    else
    {
        for( q = flist; q!= NULL; q = q->next)
        {
            if(q->data>a)     //如果链表的第一个数大于现在要插入的数据
            {
                *old_flist=p;
                p->next=q;
                break;
            }
            else if(q->data<a&&q->next!= NULL)    //如果链表当前位置的数据值大于要插入的值,且链表的后继指针不为空
            {
                if(q->data<=a&&(q->next)->data>=a)    //找到插入的位置
                {
                    tmp = q->next;
                    q->next = p;
                    p->next=tmp;
                    break;
                }
            }
            else if(q->data<=a&&q->next==NULL)       //如果链表的最后一个数据值小于要插入的值
            {
                q->next=p;
                p->next=NULL;
                break;
            }
        }
    }
    return 0;
}

int deleteone(onelist **old_flist,int a)
{
    onelist *flist=*old_flist,*tmp=NULL,*tmp1=NULL,*tmpback=NULL;
    if(flist==NULL)         //判断是否是空链表
    {
        printf("空链表!");
        return 0;
    }
    for(tmp=flist; tmp!=NULL; tmp=tmp->next)
    {
        if(tmp->data==a)
        {
            if(tmp->next!=NULL)      //找到要删除的值,如何其后继指针不为空,就把后继指针所对应内存位置中的值赋值到当前位置,释放后继指针位置的内存空间
            {
               tmp->data=(tmp->next)->data;
               tmp1=(tmp->next)->next;
               free(tmp->next);
               tmp->next=tmp1;
            }
            else
            {
                if(tmp==flist)      //如果首指针所对应的物理内存即为要删除的值对应的物理地址,且此链表只有这一个数据,则释放此内存空间,并把首指针置空
                {
                    *old_flist=NULL;
                    free(tmp);
                }
                else                //如果是链表中的最后一个元素(此链表有多个元素),则把上一个指针的next置空,释放当前空间
                {
                    tmpback->next=NULL;
                    free(tmp);
                }
            }
        }
        tmpback=tmp;                //记录指向当前内存空间的上一个指针
    }
    return 0;
}
int main()
{
    onelist *flist =NULL,*tmp=NULL;
    int a,num,count=1;
    printf("请输入要插入数的个数:");
    scanf("%d",&num);
    while(num>=count)
    {
        printf("请输入第%d个数:",count);
        scanf("%d",&a);
        insertone(&flist,a);
        count++;
    }
    tmp=flist;
    while(tmp!=NULL)
    {
        printf("%d\n",tmp->data);
        tmp=tmp->next;
    }
    printf("请输入您要删除的数字:");
    scanf("%d",&num);
    tmp=flist;
    deleteone(&flist,num);
    while(tmp!=NULL)
    {
        printf("%d\n",tmp->data);
        tmp=tmp->next;
    }
    return 0;
}
           

运行结果为:

单向链表(二级指针实现)