单链表的创建、遍历、删除及插入

在链表中,有一个头指针变量,用这个指针变量保存一个地址,该地址为变量的地址,也就是说,头指针指向一个变量,这个变量称为元素,每一个元素包含俩个部分:数据部分和指针部分。数据部分用来存放数据,指针部分用来指向下一个元素。最后一个元素的指针指向NULL,表示指向的地址为空。链表中的每一个结点包括了数据和指向下一个结点的指针,如果在链表中,每个结点只有一个指针,且所有节点都是单线联系,除了末尾结点指针为空外,每个结点的指针都指向下一个节点,一环扣一环形成一条线性链,称此链表为线性链表或单链表。

单链表的建立

链表的每个结点都必须包括数据域和指针域,即每个结点 要包含不同类型的数据,因此结构体的数据类型选择结构体类型,可包含多个多种类型的成员,其中必须有一个成员的类型是指向本结构体的指针类型。

例如,建立一个链表表示一个班级,其中,链表的结点表示学生,它的结点结构体类型如下

struct student
{
  char cName[20]; /*姓名*/
  int iNumber;  /*学号*/
  struct student *next; /* next的类型是指向本结构体类型的指针类型*/
}              
         

在next成员定义中,引用了本结构体类型。也就是说类型定义中采用了递归。

然后,定义一个creat函数,用来创建链表,该函数将会返回链表的头指针。

int iCount;      /*全局变量表示链表长度*/
struct Student *Creat()
{
   struct Student *pHead=NULL;       /*初始化链表,头指针为空*/
   struct Student *pNew,*pEnd;
   iCount=0;        /*初始化链表长度*/
   pEnd=pNew=(struct Student *)malloc(sizeof(struct Student);
   printf("Please first enter name,then number\n");
   scanf("%s",pNew->cName);
   scanf("%d",pNew->iNumber);
   while(pNew->iNumber!=0){
   iCount++;         //代表结点个数的增加
   if(iCount==1){     //判断是否为第一次加入的结点
      pNew->next=pHead;   //指针指向为空
      pEnd=pNew;       //跟踪新加入的结点
      pHead=pNew;
     }
   else
   {
    pNew->next=NULL;
    pEnd->next=pNew;
    pEnd=pNew;
   }
   pNew=(struct Student *)malloc(sizeof(struct Student);  //为新结点再次分配内存空间
   scanf("%s",pNew->cName);
   scanf("%d",pNew->iNumber);
 }
free(pNew);   //释放结点空间
return pHead;  
}  

已有结点时,先将新结点pNew的指针指向NULL,然后将原来最后一个结点的指针指向新结点,最后将pEnd指针指向最后一个节点(新结点)。一个结点创建完后,要再次进行内存分配,并输入数据,通过while语句判断其是否符合要求,当结点不符合要求时,结束while语句通过free函数将不符合要求的节点空间去进行释放。

单链表的遍历

 遍历链表中的数据并进行输出

void print (struct *pHead)
{
     struct Student *pTemp;   //循环所用的临时指针
     int iIndex=1;      //表示链表中的结点序号
     printf("名单中共有%d个学生",iCount);
     pTemp=pHead;     //得到首节点的地址
     while(pTemp!=NULL){
     printf("第%d个学生是:\n",iIndex);
     printf("%s\n",pTemp->cName);          //输出信息
     printf("%c\n",pTemp->iNumber);
     pTemp=pTemp->next;    //移动临时指针到下一个结点
     iIndex++;           //自加
          }
}

 在while循环中,每输出一个结点的内容,临时指针就移动到下一个结点,当为最后一个结点时,指针指向NULL,循环结束。

单链表的插入

 在头结点位置进行插入

struct Student *Insert(struct Student *pHead)
{
   struct Student *pNew;         //定义pNew指向分配的空间
   printf("请输入学生的姓名和学号:\n");
   pNew=(struct Student *)malloc(sizeof(struct Student);   //分配内存空间
   scanf("%s",pNew->cName);
   scanf("%c",pNew->iNumber);
   pNew->next=pHead;   //新结点指针指向原来的首结点
   pHead=pNew;         //头指针指向新结点
   iCount++;          //结点个数增加
   return pHead;       //返回头指针
}
   

首先为插入的新节点分配内存,然后输入数据。先将新节点的指针指向原来的首结点,保存首结点的地址,然后将头结点指向新结点,最后增加结点数量。 

 若需在结点(学号为number)后的位置插入,需要先找到学号为number的节点位置,然后为新插入的结点分配内存,向新结点输入数据。插入时,首先将新结点的指针指向插入结点的下一个结点,然后将插入结点的指针指向新结点,最后再增加结点数量,返回头指针。

struct Student *Insert(struct Student *pHead,int number)
{
   struct Student *p=pHead,pNew;
   while(p&&p->iNumber!=number) p=p->next;
   printf("请输入学生的姓名和学号:\n");
   pNew=(struct Student *)malloc(sizeof(struct Student *));
   scanf("%s",pNew->cName);
   scanf("%d",&->iNumber);
   pNew->next=p->next;          //新结点的指针指向插入结点的下一个结点
   p->next=pNew;               //插入结点的指针指向新结点
   iCount++;                //结点数量增加
   return pHead;
}
   

删除 

void Delete(struct Student *pHead,int iIndex)   //iIndex为要删除的结点序号
{
    int i;
    struct Student *pTemp;    //临时指针
    struct Student *pPre;      //表示要删除结点前的结点
    pTemp=pHead;           //得到头结点
    pPre=pTemp;
    printf("删除第&d个学生\n",iIndex);
    for(i=0;i<iIndex;i++){         //使pTemp指向要删除的结点
    pPre=pTemp;
    pTemp=pTemp->next;
    }
    pPre->next=pTemp->next;          //连接要删除的结点两边的结点
    free(pTemp);             //释放要删除节点的内存
    iCount--;               //结点数量减少
}

定义两个指针,分别表示要删除的结点和这个结点之前的结点,利用for循环来找到要删除的结点,pTemp保存要删除结点的地址, pPre保存前一个结点的地址,连接要删除结点两边的结点,使用free函数将pTemp指向的内存空间进行释放。

//头插法创建链表
struct Student *head,*p;
head=(struct Student *)malloc(sizeof(struct Student));
head->next=NULL;
int i;       //要创建多少个结点
for(i=0;i<5;i++)
{
  p=(struct Student *)malloc(sizeof(struct Student));
  scanf("%d",&p->iNumber);
  scanf("%s",p->cName);
  p->next=head->next;
  head->next=p;
}
//尾插法创建链表
struct Student *head,*p,*q;
q=(struct Student *)malloc(sizeof(struct Student));
q->next=NULL;
int i;       //要创建多少个结点
for(i=0;i<5;i++)
{
   p=(struct Student *)malloc(sizeof(struct Student));
   scanf("%d",&p->iNumber);
   scanf("%s",p->cName);
   p->next=NULL;
   q->next=p;
   q=p;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值