哈佛cs50公開課,list1鏈表相關程序

很納悶,上次發的fifteen竟然說包含不適內容,就是程序而已啊,莫名其妙。

這個就是公開課上鍊表的程序,稍微改了下,沒用他的頭文件,同時添加了註釋。用codeblocks編譯通過。

鏈表這個確實挺麻煩,並不是不能理解,而是具體實施該怎麼做。

主要要理解頭指針,頭節點,第一個節點的含義和怎麼表示。

下面是程序:

/*
一個數字鏈表。可以實現插入(按大小),查詢,刪除等功能
輸入1,用於刪除;
輸入2,用於尋找;
輸入3,用於插入;
輸入4,用於遍歷;
輸入0,用於退出;
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//定義鏈表
typedef struct node
{
    int n;//注意這個n,和平時int n區別開來
    struct node *next;
}
node;
//頭指針
node *first=NULL;
//聲明函數
void delete(void);
void find(void);
void insert(void);
void traverse(void);
int getint(void);//代替頭文件裏的GetInt
//主函數
int
main()
{
    int c;
    do
    {
        printf("\n菜單\n\n"
                "輸入1,刪除鏈表內數字\n"
                "輸入2,尋找鏈表內數字\n"
                "輸入3,插入數字到鏈表中(自動排序)\n"
                "輸入4,遍歷鏈表\n"
                "輸入0,退出\n");
        //輸入
        printf("請輸入命令:");
        c=getint();
        //分類
        switch(c)
        {
            case 1:delete();break;
            case 2:find();break;
            case 3:insert();break;
            case 4:traverse();break;
            default:printf("請按照提示輸入命令\n");
        }
    }
    while(c!=0);
    //釋放鏈表空間
    node *ptr=first;
    while(ptr!=NULL)
    {
        node *predptr=ptr;
        ptr=ptr->next;
        free(predptr);
    }
    return 0;
}


//getint
int getint(void)
{
    int p,m,num;
    while(1)
    {
        p=scanf("%d",&num);//scanf的返回值
        while((m=getchar())!='\n'&&m!=EOF);//清除輸入緩存
        if(p==1)//返回值是數字則爲1,否則是其它的
            return num;
        else
            printf("請確保輸入的是整數,再試一次:");
    }
}


//delete
void
delete(void)
{
    printf("輸入要刪除的數字:");
    int n=getint();

    node *ptr=first;//爲什麼不直接用first
    node *predptr=NULL;//

    while(ptr!=NULL)//最後節點
    {
        if(ptr->n==n)//鏈表裏面有這個數,這2個n是不一樣的,一個是定義鏈表裏的數據,一個是輸入的數字
        {
            //if(ptr->n==first->n)
            if(ptr==first)//ptr是在變化的,因爲是個while循環,判斷ptr變化了沒?用這個if(ptr->n==first->n)可以不?實驗後可以
            {
                first=ptr->next;
                free(ptr);
            }
            else//在中間或是尾部
            {
                predptr->next=ptr->next;//predptr在這裏已經不是NULL了,第一個節點不相等就會執行下面的predptr=ptr;而相等就不會進行這一步
                free(ptr);
            }
            break;
        }
        else
        {
            predptr=ptr;
            ptr=ptr->next;//同上面聯繫起來看,predptr與ptr相隔1個節點
        }
    }
    if(ptr==NULL)
        printf("你所要刪除的數字不存在\n");
    traverse();
}

//insert
void
insert(void)
{
    node *newptr=malloc(sizeof(node));
    if(newptr==NULL)
        {
            printf("申請空間出錯\n");
            return;
        }
    printf("輸入插入的數字:");
   //插入的鏈表節點
    newptr->n=getint();
    newptr->next=NULL;
    //如果鏈表是空的,則直接是newptr
    if(first==NULL)
        first=newptr;//爲什麼不是first->next=newptr?因爲first單純是個指針,就是第一個節點,first->next是第二個節點了。
    //插入鏈表頭部
    else if(newptr->n<first->n)//first->n?第一個數據?
    {
        newptr->next=first;//爲什麼不是first->next?同上,相當於將newptr和first鏈接起來
        first=newptr;
    }
    //插入中間或底部
    else
    {
        node *predptr=first;//爲什麼不直接用first而是新建一個指針predptr呢?
        while(1)
        {
            //是否重複
            if(predptr->n==newptr->n)
            {
                free(newptr);
                break;
            }
            //判斷是否在尾部
            else if(predptr->next==NULL)
            {
                predptr->next=newptr;
                break;
            }
            //在中間的情況
            else if(predptr->next->n>newptr->n)//predptr->next->n?
            {
                newptr->next=predptr->next;
                predptr->next=newptr;
                break;
            }
           //循環
            predptr=predptr->next;
        }
    }
    //遍歷一下
    traverse();
}

//find
void
find(void)
{
    printf("輸入要查找的數字:");
    int n=getint();
    node *ptr=first;
    while(ptr!=NULL)
    {
        if(ptr->n==n)
        {
            printf("\n已找到%d\n",n);
            usleep(100000);
            break;
        }
        ptr=ptr->next;
    }
     if(ptr==NULL)
        printf("你所要尋找的數字不存在\n");
}

//traverse
void
traverse(void)
{
    printf("現在列表中存在的數據有:");
    node *ptr=first;
    while(ptr!=NULL)
    {
        printf("%d ",ptr->n);
        ptr=ptr->next;
    }
    fflush(stdout);
    usleep(100000);
    printf("\n\n");
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章