天天看點

單向連結清單(二級指針實作)

#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;
}
           

運作結果為:

單向連結清單(二級指針實作)