C语言语法教程-链表

2021-06-16 00:04

阅读:671

标签:教程   ++   been   语言   else   结构体   工作   lse   switch   

链表是一群结构体(称为结点)通过指针连起来。这种结构体类型,比较特殊,叫自引用结构体类型。它有一个指针指向和和结构体一样的类型,其余是数据成员。
头指针指向第一结点,尾指针一定要用空表示,这叫有头有尾。一般在表头加头结点,之后才是正式含数据的结点。
这些结点通过头指针访问,所以若头指针值为空,那么链表就为空。所以头指针是最重要的,一般一定会给函数传递头指针。

//-------------------------------------
//--- linked list.1
//--- 使用链表管理学生信息
//-------------------------------------
#include 
#include 

struct student
{
    long no;
    char name[20];
    char addr[30];
    struct student *next;
};

typedef struct student LIST;
LIST *CreateList();
void DispList(LIST *h);
void input(LIST *p);
LIST *DeleteNode(LIST *h, long no);
LIST *InsertNode(LIST *h, LIST *s);

int main(int argc, char const *argv[])
{
    LIST *head,*p;
    long no;
    int choice,confirm;
    head=CreateList();    //创建链表,返回头指针
    DispList(head);          //输出链表内信息
    while(1)
    {
        printf("0--Insert\n1--Delete\n2--Quit\nPlease select:");
        scanf("%d",&choice);
        if(choice==2)
            break;
        printf("your just select %d,yes? ",choice);
        scanf("%d",&confirm);
        if(confirm){
            switch(choice)
            {
                case 0:
                    printf("OK,now we insert a record!\n");
                    printf("======Insert=====\n");
                    p=(LIST *)malloc(sizeof(LIST));
                    if(p == NULL)
                    {
                        printf("Wrong!\n");
                        exit(0);
                    }
                    input(p);
                    head=InsertNode(head,p);
                    DispList(head);
                    break;
                case 1:
                    printf("OK,now we delete a record!\n");
                    printf("======Delete=====\n");
                    printf("Delete Id:");
                    scanf("%d",&no);
                    head=DeleteNode(head,no);
                    if (head!=NULL)
                        DispList(head);
                    else printf("All records have been deleted!\n");
                    break;
            }
        }
    }
    return 0;
}
void input(LIST *p)
{
    LIST *cur=p;
    printf("Id:");
    scanf("%d", &cur->no);  
    printf("Name:");
    scanf("%s", &cur->name);
    printf("Address:");
    scanf("%s", &cur->addr);
}
LIST *CreateList()/*返回头指针,故定义为结构体指针函数。*/
/*创建链表的函数定义*/
{
    LIST *h, *prev, *cur;//这三不是结构体,是工作指针,用来操作的。 
    int i, n;
    h=NULL;
    /*第一个结点过来孤零零的,不知道干啥,所以得弄个头指针。初始化为空。*/
    printf("Input numbers of records:");
    scanf("%d",&n);

    for (int i = 0; i next=NULL;/*将cur的next置为NULL*/
        if (h==NULL)/*如果h=NULL,表示当前在处理第一个结点*/
        {
            h=cur;/*令h指向第一个结点*/
        }
        else
            prev->next=cur;
            /*令表中最后一个结点的next指向cur;prev负责将链段尾结点和新结点连起来*/
            /*关于指针指来指去,想想就好了,实际上指针都是地址,内存条里是不会有箭头的。要懂链表,先理解结构体。结构体变量可以通过变量名.成员名的方式访问成员,也可以用存储了结构体首地址的指针变量->成员名的形式访问成员。这里cur存储了新来的结构体的首地址,prev存储了链段尾结构体的首地址,你不妨将指针直接看成结构体,没什么不妥。那么让尾结构体的指针成员next存储新来的结构体的首地址,这样,通过链段尾结构体就可以访问新来的结构体的了,事实上只能这样访问,别无它法。正因为如此,一个结构体带一个结构体,才起名为链表。
            通过prev->next就可以操作指针成员next。prev->next=cur执行后,prev就存储了新来结构体的首地址。由于新来的结构体已经安顿好了,它其实已经作为老结构体了,那么prev就存储了这个老结构体的首地址,你可以把prev看成这个老结构体。
            */
        //input information
        printf("=====第%d人=====\n",i+1);
        input(cur);

        prev=cur;/*将prev指向最后一个结点;prev永远指向链段的最后一个结点*/
    }
    return h;
}

void DispList(LIST *h)
{
    LIST *p=h;
    int i=0;
    while(p!=NULL)
    {
        if(i==0)
        {
            printf("学号\t姓名\t地址\n");//只显示一次
            i=1;
        }
        printf("%d\t%s\t%s\n",p->no, p->name, p->addr);
        p=p->next;
    }
}

LIST *InsertNode(LIST *h, LIST *s)
{
    LIST *pre, *p;
    p=h;
    if (h==NULL)
    {
        h=s;
        s->next=NULL;
    }else{
        while((s->no > p->no) && (p->next!=NULL))
        {
            pre=p;
            p=p->next;
        }
        if(s->no no){
            if (h==p){
                s->next=h;
                h=s;
            }else{
                pre->next=s;
                s->next=p;
            }
        }else{
            p->next=s;
            s->next=NULL;
        }
    }
    return h;
}

LIST *DeleteNode(LIST *h, long no)
{
    LIST *pre, *p;
    if (h==NULL)
    {
        printf("链表为空,不能删除结点!\n");
        return NULL;
    }
    p=h;
    while((p->no != no) && p->next!=NULL)
    {
        pre=p;
        p=p->next;
    }
    if (p->no==no)
    {
        if (p==h)
            h=p->next;
        else pre->next=p->next;
        free(p);
        printf("结点成功删除\n");
    }else printf("There isn‘t Id:%d.\n",no);
    return h;
}

C语言语法教程-链表

标签:教程   ++   been   语言   else   结构体   工作   lse   switch   

原文地址:https://www.cnblogs.com/feicaixian/p/9728631.html


评论


亲,登录后才可以留言!