链表的创建,删除,打印功能(新手)

//完整代码

#include<stdio.h>
#include<stdlib.h>
typedef struct lianbiao
{
    int score;
    struct lianbiao*next;
}Linklist;

//创造结点 

Linklist*creat(int n)
{
    Linklist *head,*node,*end;
    head=(Linklist*)malloc(sizeof(Linklist));
    end=head;//让尾结点等于头结点 
    printf("请输入要创造的值:\n");
    for(int i=0;i<n;i++)
    {
        node=(Linklist*)malloc(sizeof(Linklist));
        scanf("%d",&node->score);
        end->next=node;//将尾/头结点的指针域指向刚创建好的普通结点。 
        end=node;//令尾结点等于现在的普通结点,来实现连接下一个结点。 
    }
    end->next=NULL;//所有结点创好后,让最后一个结点的指针域为空。 
    return head;//返回头结点(的地址) 
}
 

//删除 (为了看起来更简便,易理解,这里我没有写判空,也没有free)
void delet(Linklist*list,int score,int n)
{
    Linklist *t=list->next,*m=list,*p;//定义两个指针,一个承载的头结点的指针域指向的下一个结点地址。 个承载的头结点的地址 
    
    for(int i=0;i<n;i++)
    {
        if(t->score==score)
        {
            m->next=t->next;
           
        }
        else
        m=t;//移动m指针 
        t=t->next;//移动t指针 
    }
}

//打印 (主要理解如何用另外的指针来前进(遍历)的) 
void print(Linklist*list)
{
    Linklist *t=list;
    while(t->next!=NULL)
    {
        printf("%d ",t->next->score);
        t=t->next;
    }
}
//主函数 
int main()
{
    printf("请选择创建的结点数(不包含头节点):\n");
    int n;
    scanf("%d",&n);
     Linklist*list=creat(n);//创建链表 (这里用list指针来接收头结点的地址)
     printf("请输入要删除的值:\n");
     int s;
     scanf("%d",&s);
     delet(list,s,n);
     printf("现在的结点的值:\n");
    print(list);
    return 0;
    }

  • 如何创建一个链表

#include<stdio.h>

#include<stdlib.h>

typedef struct lianbiao

{

int score;

struct lianbiao*next;

}Linklist;

说明 :
  一,typedef之后的"struct lianbiao"这是一个结构体。很多新手同志不知道怎么去理解结构体。其实很简单,你可以理解为这是一个类型
  比如我们使用int去定义一个变量a,那a便是整型。
  如果用char,那a就是字符型。
  而如果我们用结构体去定义a,那么a便是结构体类型,例如struct lianbiao a,这种类型的好处就是,可以使变量a具有多种类型的属性。
  二,这里的typedef不过多讲解,想了解更多可以去搜索。为了帮助你理解,你可以把它当成一个"取别名"的标识符。比如在没有用typedef时,我们定义变量a是这样:
    struct lianbiao a;可以发现这个定义实在太长了,所以为了简化,我们给struct lianbiao取个别名Linklist,然后定义a就可以是:Linklist a;


//创造结点

Linklist*creat(int n)

{

Linklist *head,*node,*end;

head=(Linklist*)malloc(sizeof(Linklist));

end=head;//让尾结点等于头结点

printf("请输入要创造的值:\n");

for(int i=0;i<n;i++)

{

node=(Linklist*)malloc(sizeof(Linklist));

scanf("%d",&node->score);

end->next=node;//将尾/头结点的指针域指向刚创建好的普通结点。

end=node;//令尾结点等于现在的普通结点,来实现连接下一个结点。

}

end->next=NULL;//所有结点创好后,让最后一个结点的指针域为空。

return head;//返回头结点(的地址)

}
创造结点的难点:
1,Linklist*creat(int n)
    可以这样理解,这是一个由Linklist*的类型定义的一个creat函数,参数为n。为什么是
    Linklist*的类型而不是Linklist类型呢?因为我们待会儿返回的是头结点的地址,所以用
    Linklist*这种结构体指针类型来接收。


2,head=(Linklist*)malloc(sizeof(Linklist));
这是动态内存分配,用head指针,去接收一个大小为结构体类型Linklist的空间大小的地址。

3,创建头指针(结点),普通指针(结点),尾指针(结点)的目的。
(注:这里说明一下为什么又叫指针又叫结点,因为我们创建的结点要以地址的方式返回,所以用指针来接收地址)
1,创建头结点,因为会将它作为返回值,我们知道头结点,就可以通过它访问整个链表,头结点的数据域(score)可以不用赋值。
2,普通结点,这个是我们需要给数据域(score)赋值的结点。
3,尾结点,或者说指针,我们用它来将链表串起来(具体步骤看代码注释)

//删除
void delet(Linklist*list,int score,int n)

{

Linklist *t=list->next,*m=list,*p;//定义两个指针,一个承载的头结点的指针域指向的下一个结点地址。 个承载的头结点的地址

for(int i=0;i<n;i++)

{

if(t->score==score)

{

m->next=t->next;

}

else

m=t;//移动m指针

t=t->next;//移动t指针

}

}

删除功能难点:
1,通过什么方式来删除
这里可以直接将 需要删除的结点 的 上一个结点的指针域  指向 需要删除的结点 的下一个结点。
Linklist *t=list->next,*m=list;
      m->next=t->next;
以此来实现一个逻辑上的删除。
(这个结点空间其实并没有删掉,所以我说逻辑上删除,如果要释放删除结点的空间可以用free。刚接触的同志只需要理解这个逻辑上面删除就行了)

2,如何让寻找目标结点的指针前进(或者说遍历)
m=t;
t=t->next;

//打印 (主要理解如何用另外的指针来前进(遍历)的)

void print(Linklist*list)

{

Linklist *t=list;

while(t->next!=NULL)

{

printf("%d ",t->next->score);

t=t->next;

}

}

本人也刚接触编程不久,如有错误,请大佬们指正

猜你喜欢

转载自blog.csdn.net/qq_58136559/article/details/125135051