双链表的机制(建立,查询,修改,删除,人机交互的处理)以及内存分配与释放机制

一.定义:
链表(listed list)就是一些包含数据的独立数据结构(通常成为节点)的集合。链表中的每个节点通过链或者指针连接起来。程序通过指针访问链表中的节点。通常节点是动态分配的,但是有的时候也能看到由节点数组构建的链表。(此定义来自《c与指针》的第12章)。
我自己理解就是链表的特点就是方便通过指针遍历所有节点,特别是双链,可以通过一个指针向前或者向后遍历所有节点,链表使得数据的结构更加清晰,另外链表一般使用动态内存,根据需求分配空间。单链表和双链表并没有固定的格式,可以根据自己的理解去设计。
二.下面分享单链表和双链表的示意图
在这里插入图片描述
在这里插入图片描述
三.接下来分别介绍如下的功能:
1.结构体定义

/*每个节点的结构体*/
typedef struct  stDoubleLink {
  struct  stDoubleLink   *pPre ;  /*指向前一个节点*/
  struct  stDoubleLink   *pNext ; /*指下一个一个节点*/
  Uint    u32Worknum  ;           /*员工工号*/
  Uint    u32Wage     ;           /*员工工资*/
}stDoubleLink;
/*为了输入参数准备的结构体*/
typedef struct  Double_link_Value {
  Uint    u32Worknum_Value ;           /*员工工号*/
  Uint    u32Wage_Value    ;           /*员工工资*/
}Double_link_Value;

2.新建链表
主要就是把链表的前后对应关系搭建好。

/*
*  函数名称:mag_link_creat
*  函数功能描述:新建链表,并把头节点返回。
*  函数传递变量:Uint  u32Link_Length
*  函数返回值:pHead  
*  函数作者:Mr.shang
*  时间:2019.9.8
*  修改记录:
*  修改原因    修改内容   修改时间   修改人
*
*/

stDoubleLink  *mag_link_creat(Uint  u32Link_Length)
{
   stDoubleLink *pHead,*pN_Temp,*pM_Temp;
   Double_link_Value  stValue_Temp;
   Uint    u32i=0;


   pHead=(stDoubleLink *)malloc(sizeof(stDoubleLink));
   memset(pHead,0,sizeof(stDoubleLink));
   pHead->pNext=pHead;
   pHead->pPre=pHead;

   pM_Temp=pHead;
   for(u32i=0;u32i<u32Link_Length;u32i++)
   {
      pN_Temp=(stDoubleLink *)malloc(sizeof(stDoubleLink));
      memset(pN_Temp,0,sizeof(stDoubleLink));
	  memset(&stValue_Temp,0,sizeof(Double_link_Value));

	  stValue_Temp=mag_scanf_fun(stValue_Temp);
	  
	  pN_Temp->u32Worknum=stValue_Temp.u32Worknum_Value;
	  pN_Temp->u32Wage=stValue_Temp.u32Wage_Value;

	  pM_Temp->pNext=pN_Temp;/*前一个节点指向下一个节点*/
	  pHead->pPre=pN_Temp; /*头节点的前一个节点为最新的节点*/

	  pN_Temp->pNext=pHead;/*新节点指向头节点*/
	  pN_Temp->pPre=pM_Temp;/*新节点指向前一个节点*/ 

	  pM_Temp=pN_Temp;  /*前一个节点跳到本节点,为下次准备*/
   }

   return pHead;
}

2.查询链表

/*
*  函数名称:mag_link_inquire
*  函数功能描述:按照员工工号查询员工信息。
*  函数传递变量:stDoubleLink *pHead_Temp, Uint u32Worknum_Temp
*  函数返回值:无  
*  函数作者:Mr.shang
*  时间:2019.9.8
*  修改记录:
*  修改原因    修改内容   修改时间   修改人
*
*/
void  mag_link_inquire(stDoubleLink *pHead_Temp, Uint u32Worknum_Temp)
{
      stDoubleLink *pN_Temp,*pM_Temp;
     /*判断指针是否为空指针,在程序里面使用空指针会带来严重的后果*/
     if(NULL==pHead_Temp)
     {
        return;
     }
	  pN_Temp=pHead_Temp;
	  pN_Temp=pN_Temp->pNext;
	  while(pN_Temp!=pHead_Temp)
	  {
	      if(u32Worknum_Temp==pN_Temp->u32Worknum)
		  {
		    printf("查询到的员工信息:工号:%d,工资:%d\n",pN_Temp->u32Worknum,pN_Temp->u32Wage);		  
		  }	  
	      pN_Temp=pN_Temp->pNext;
	  }

}

3.按照员工工资排序

/*
*  函数名称:mag_link_rank
*  函数功能描述:根据员工工资从小到大进行排序。
*  函数传递变量:stDoubleLink *pHead_Temp
*  函数返回值:无  
*  函数作者:Mr.shang
*  时间:2019.9.8
*  修改记录:
*  修改原因    修改内容   修改时间   修改人
*
*/
void  mag_link_rank(stDoubleLink *pHead_Temp)
{
      stDoubleLink *pN_Temp,*pM_Temp;
	   Double_link_Value  stValue_Temp;
   /*判断指针是否为空指针,在程序里面使用空指针会带来严重的后果*/
     if(NULL==pHead_Temp)
     {
        return;
     }
	  pN_Temp=pHead_Temp;
	  pN_Temp=pN_Temp->pNext;
	  for(;pN_Temp!=pHead_Temp;pN_Temp=pN_Temp->pNext)
	  {
	    for(pM_Temp=pN_Temp->pNext;pM_Temp!=pHead_Temp;pM_Temp=pM_Temp->pNext)
		{
		   if(pN_Temp->u32Wage>pM_Temp->u32Wage)
		   {
		     stValue_Temp.u32Wage_Value=pN_Temp->u32Wage;
			 stValue_Temp.u32Worknum_Value=pN_Temp->u32Worknum;

			 pN_Temp->u32Wage=pM_Temp->u32Wage;
			 pN_Temp->u32Worknum=pM_Temp->u32Worknum;

		     pM_Temp->u32Wage=stValue_Temp.u32Wage_Value;
		     pM_Temp->u32Worknum=stValue_Temp.u32Worknum_Value;
		   }		
		}/* for(pM_Temp=pN_Temp->pNext;pM_Temp!=pHead_Temp;pM_Temp=pM_Temp->pNext)*/
	  	  
	  }/*for(;pN_Temp!=pHead_Temp;pN_Temp=pN_Temp->pNext)*/


}

4.删除某个节点:

/*
*  函数名称:mag_link_delete_one
*  函数功能描述:根据员工工号删除该员工信息,并释放该节点的空间。
*  函数传递变量:stDoubleLink *pHead_Temp, Uint u32Worknum_Temp
*  函数返回值:无  
*  函数作者:Mr.shang
*  时间:2019.9.8
*  修改记录:
*  修改原因    修改内容   修改时间   修改人
*
*/
void  mag_link_delete_one(stDoubleLink *pHead_Temp,Uint u32Worknum_Temp)
{
	  stDoubleLink *pN_Temp=NULL;
	  stDoubleLink *pT_Temp=NULL;
         /*判断指针是否为空指针,在程序里面使用空指针会带来严重的后果*/
     if(NULL==pHead_Temp)
     {
        return;
     }
	  pN_Temp=pHead_Temp;
	  pN_Temp=pN_Temp->pNext;
	  while(pN_Temp!=pHead_Temp)
	  {
	      if(u32Worknum_Temp==pN_Temp->u32Worknum)
		  {
		     printf("删除的员工信息:工号:%d,工资:%d\n",pN_Temp->u32Worknum,pN_Temp->u32Wage);	
			
			 pT_Temp=pN_Temp;/*记住要删除链表*/
			 pN_Temp=pN_Temp->pNext;/*到下一个节点*/
            
			(pT_Temp->pPre)->pNext =pN_Temp;/*将本节点的上一个节点和下一个节点连接*/
			 pN_Temp->pPre=pT_Temp->pPre;/*将本节点下一个点与上一个节点连接*/

			free(pT_Temp);/*释放节点*/
		  }
		  else
		  { 
			pN_Temp=pN_Temp->pNext;/*到下一个节点*/
		  }
	     
	  }/*while(pN_Temp!=pHead_Temp)*/
}

5.scanf函数的使用(人机交互)

/*
*  函数名称:mag_scanf_fun
*  函数功能描述:用键盘输入员工信息,并判断输入是否正确。
*  函数传递变量:Double_link_Value  stLink_Value_Temp
*  函数返回值:Double_link_Value  stLink_Value_Temp
*  函数作者:Mr.shang
*  时间:2019.9.8
*  修改记录:
*  修改原因    修改内容   修改时间   修改人
*
*/
Double_link_Value mag_scanf_fun(Double_link_Value  stLink_Value_Temp)
{
     Uchar         u8Scanf_flag=0;
     Int           s32Scanf_Return=0;

	 while(0==u8Scanf_flag)
	 {
	   printf("请输入员工工号\n");
	   s32Scanf_Return=scanf("%d",&stLink_Value_Temp.u32Worknum_Value);
	   if(EOF==s32Scanf_Return)
	   {
	     while(getchar()!='\n');
		 printf("scanf输入异常\n");
	   }
	   else if(0==s32Scanf_Return)
	   {
	     while(getchar()!='\n');
		 printf("scanf输入异常\n");
	   }
	   else if(1==s32Scanf_Return)
	   {
	    u8Scanf_flag=1;
	   
	   }
	 
	 }/* while(0==u8Scanf_flag)*/
	 u8Scanf_flag=0;
      while(0==u8Scanf_flag)
	 {
	   printf("请输入员工工资\n");
	   s32Scanf_Return=scanf("%d",&stLink_Value_Temp.u32Wage_Value);
	   if(EOF==s32Scanf_Return)
	   {
	     while(getchar()!='\n');
		 printf("scanf输入异常\n");
	   }
	   else if(0==s32Scanf_Return)
	   {
	     while(getchar()!='\n');
		 printf("scanf输入异常\n");
	   }
	   else if(1==s32Scanf_Return)
	   {
	    u8Scanf_flag=1;
	   
	   }
	 
	 }/* while(0==u8Scanf_flag)*/


   return  stLink_Value_Temp;
}

四.总述
链表的难点:
1.就是需要理清楚每个节点的关系。
2.堆空间的申请和释放。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值