链表

malloc函数和free函数通常配对使用,malloc如果没有free释放内存可能会造成“内存泄漏”


创建链表并添加节点

一、创建链表流程

(1)创建一个链表需要三个指针:指针(pHead),尾指针(pEnd),新指针(pNew)

(2)刚开始链表中一个结点都没有,可用malloc申请内存,动态创建1个结点,令pNew指向它

(3)输入数据后,目前这个新结点又是头结点,也是最后一个结点,所以要令pHead和pEnd也指向它。第一个结点通常需要特殊处理,所以将它放在循环外面建立

(4)剩下3个结点有相同规律,可用(5)到(7)步的循环进行处理:

(5)新建结点给pNew,输入数据

(6)使最后一个结点pEnd的下一结点next指向这个新结点,形成兄弟关系

(7)将新结点pNew设为最后一个结点pEnd

(8)循环结束

(9)不再添加结点,要使最后一个结点pEnd的指针指向NULL

(10)返回头指针pHead

定义全局变量n,各模块函数都可以使用

1、create函数创建链表:struct student* create()

            创建链表并输入四个节点

            算法思路:让pNew指向新开辟的结点,pEnd指向链表中最后一个结点,把pNew所指的结点连接在pEnd所指结点的后面,即pEnd->next=pNew;    。

(1)头指针(pHead) 尾指针(pEnd) 新指针(pNew):struct student *pHead,*pEnd,*pNew;。全局变量赋初值0:n=0;.

(2)malloc函数开辟新单元给尾指针和新指针,    struct student*是使malloc返回的指针转化为struct student类型数据的指针(*不可省略,否则就转换成struct student类型,而不是指针类型),    sizeof求字节数:pEnd=pNew=(struct student*)malloc(sizeof(struct student));        由于编译系统能实现隐式的类型转换,故可以写成pEnd=pNew=malloc(sizeof(struct student));


          输入第一个个学生名字和成绩:scanf("%s%d",pNew->name,&pNew->age);

(3)头指针为NULL

(4)循环:

while(pNew!=0)

{

n=n+1;

if(n==1)

pHead=pNew;

else

pEnd->next=pNew;

pEnd=pNew;                            //使新节点成为最后一个节点

pNew=(struct student*)malloc(sizeof(struct student));//开辟动态存储区,把起始地址赋给pNew

scanf("%s%d",pNew->name,&pNew->age);  //输入后面学生名字成绩

}

(5)pEnd->next=pNew; //使最后一个节点的下一节点指针指向新节点

pEnd->next=NULL;                        //最后一个节点的下一节点指针为空

return pHead;                          //返回头指针

2、print函数输出链表

            相对其它操作,输出链表结点的操作比较简单,用一个临时指针通过循环不停地指向下一结点即可。

           print函数输出链表所有结点:

void print(struct student *pHead)

{

struct student *p;

p=pHead;    //使p指向第一个结点

if(pHead!=NULL)

do

{

printf("name:%s , age:%d \n",p->name,p->age);

p=p->next;

}while(p!=NULL);

}

3、del函数删除结点

            删除结点时通常会进行结点查找,找到符合条件的结点再进行删除操作。

            在本程序中找到第3个结点为要删除的结点,再令第2个结点的下一结点指针指向第4个结点,第3个结点就完成了自然脱链动作。

        del函数删除指定姓名的结点

4、insert函数插入结点

            插入的意思是把结点插入至链表中间,插入方法有“前插”和“后插”法,前插就是找到目标结点后,在它前面插入新结点,后插就是在其后面插入。本程序中演示的是前插法。有个例外的是:如果未找到指定结点,会将新结点添加到链表最后。

            insert函数插入一个新结点在指定姓名之前


下面是代码:
#include<stdio.h>
#include<stdlib.h>

struct student
{
    char name[9];
    int age;
    struct student*next;  //指向下一个节点,指向自身的指针
};

int n;                      //定义全局变量,各模块函数都可以使用

//创建链表、节点:返回链表头指针
struct student* create()
{
    struct student *pHead,*pEnd,*pNew;      //头指针 尾指针 新指针
    //建立链表及第一个节点。。因为第一个节点是头结点,所以要放在循环外面特殊处理
    pEnd=pNew=(struct student*)malloc(sizeof(struct student));   //malloc函数分配内存,需要加头文件#include<stdlib.h>
    scanf("%s%d",pNew->name,&pNew->age);    //取结构成员的地址,首数组为该数组的地址,故scanf不需要加&
    //建立后面链表节点
    while(pNew->age!=0)
    {
        n=n+1;
        if(n==1)
            pHead=pNew;
        else
            pEnd->next=pNew;
        pEnd=pNew;                             //使新节点成为最后一个节点
        pNew=(struct student*)malloc(sizeof(struct student));//开辟动态存储区,把起始地址赋给pNew
        scanf("%s%d",&pNew->name,&pNew->age);  //输入后面学生名字成绩
    }
    pEnd->next=pNew;                    //使最后一个节点的下一节点指针指向新节点
    pEnd->next=NULL;                        //最后一个节点的下一节点指针为空
    return pHead;                           //返回头指针
}

//输出链表
void print(struct student *pHead)
{
   struct student *p;
   p=pHead;     //使p指向第一个结点
   if(pHead!=NULL)
    do
   {
       printf("name:%s , age:%d \n",p->name,p->age);
        p=p->next;
   }while(p!=NULL);
}

void del(struct student *pHead,int ilndex)  //删除节点
{
    struct student *pFront,*pBack;//前节点,后节点
    int i=0;
    pBack=pHead;                            //后节点指向头结点
    pFront=pHead;                     //前节点指向头结点的下一节点
   for(i=0;i<ilndex-1;i++)
   {
       pFront=pBack;
       pBack=pBack->next;
   }
        pFront->next=pBack->next;                       //后节点设为前节点
        free(pBack);
        n--;                //前节点设为前节点的下一节点
}

void insert(struct student *pHead,int ipoint)
{
    struct student *pFront,*pBack,*pNew;
    int i;
    pNew=(struct student*)malloc(sizeof(struct student));
    printf("Please input the new node's name and age:\n");
    scanf("%s%d",pNew->name,&pNew->age);
    pBack=pFront;
    pFront=pHead->next;
    for(i=0;i<ipoint-1;i++)
    {
            if(i==ipoint-2)     //插入后位于第ipoint位
            {
                pBack->next=pNew;
                pNew->next=pFront;
                return;
            }
        pBack=pFront;
        pFront=pFront->next;
    }
    pBack->next=pNew;
    pNew->next=NULL;
    n++;
}

int main()
{
    printf("please input student's name and age:\n");

    struct student *pHead;                  //链表头指针
    pHead=create();                         //创建节点
    print(pHead);                           //输出所有节点
    printf("n=%d\n",n);

    int ilndex;
    printf("please input the node that you want to delete:\n");
    scanf("%d",&ilndex);
    del(pHead,ilndex);                        //删除名为cc的节点
    printf("After delete:\n");
    print(pHead);
    printf("n=%d\n",n);

    int ipoint;
    printf("please input the point that you want to insert:\n");
    scanf("%d",&ipoint);
    insert(pHead,ipoint);                      //在名为dd的节点前插入一个节点
    printf("After insert:\n");
    print(pHead);
    printf("n=%d\n",n);

    return 0;
}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值