【C解析之十】链表进阶

C解析之十链表进阶


         前言:最直观的图解,解链表最迷惑之点。下面将介绍链表的核心操作:插入,删除,查询,掌握这些操作,链表便可在你的程序中大放光彩啦。
         1.链表的插入:将新的节点插入到链表指定的位置。
          如下图:
       
            等待插入的新节点(p),插入链表两个节点之间(左边为p1,右边为p2),完成这一操作需要两步:1.将p1的指针指向等待插入的节点;2将等待插入节点的指针指向p2。(如图)。
           
              上图数字1,2分别指示了这两个操作步骤。插入节点的关键代码:
                         p1->next = p;
                         p->next = p2;
            2.链表的删除 将一个节点从链表删除。
            如下图:
          
           删除节点操作是上一步插入节点逆操作。删除节点P,只需要把P1的指针指向P2,P便不在属于链表了。(如图)。
           
             
            上图的数字1指示了删除所需的一步操作。有同学可能觉得,P的指针还指向P2呢,这丝毫不能改变P已经被链表删除了的事实。链表删除操作的核心代码:
                P1->next=P->next;   //P-next指向的是P2
       或者 :P1->next=P2;      
             3.链表的查询:遍历链表查找满足特定要求的节点。 
               链表的查询,需要遍历每一个节点,那么在遍历的过程中同样可以输出链表,遍历的最后可以找到链表的末尾(此处同时解释【C解析之九】链表初探中最后读者可能存在疑问的链表输出与找到链表的末尾)。
             如下图:  
      
           链表习惯上表头Head不存储数据,Head之后的节点才真正是存有数据的节点,不管是查询时的比较,还是遍历时的输出都是操作链表节点内的数据。我们定义一个指针,通过指针的偏移(依次指向每个节点)来访问所有的节点。
          
             依次分析:
             数字1: 将指针指向第一个链表节点,代码:P=Head->next;
             数字2: 指针指向下一个链表节点,    代码:P=P->next;
             数字3: 指针继续指向下一个节点,    代码:P=P->next;
             ......
             最后的结果:P-next=NULL,此时P指向的加点便是末尾的节点,这可以成为控制while循环的条件之一。
            继续扩展上一篇的例子:这个例子是初学者进一步学习C的良好例子,有兴趣的同学可以试试。掌握这个例子,C语言可以说已经初步入门了。同时,这个例子对链表操作而言,可谓五脏俱全,借助上面的图解仔细阅读,理解其中的关系。笔者认为,链表的操作,能极好地锻炼逻辑思维,同时考验开发者的细致程度。为便初学者,笔者决定不再增加更多的干扰,此程序便不做模块化处理了。
    
#include
    
    
     
     
#include
     
     
      
      
//************
//定义链表节点
//************
struct Node{ 
	int id;                //id为学号,Score为成绩
	int Score;             //id,Score为数据区
	struct Node * next;    //指针next,指向下一个节点,故类型为Node *
};
//************
//定义链表头
//************
Node *Head;

int main(){
	Node *temp;
	Node *p1;
	Node *p2;
	Head=(Node *)malloc(sizeof(Node));
	if(Head!=NULL){          //检查是否申请空间成功
		Head->next=NULL;     //只有头节点,故此时指向空NULL      
		Head->id=0;          //赋值id
		Head->Score=0;       //赋值Score,一般而言,头节点不用于存储数据,此处均象征性赋值为0
	}
	printf("现在创建含4带个节点的链表:\n");
	for(int i=0;i<4;i++){

		//************
        //新建一个节点并赋值
        //************
		temp=(Node *)malloc(sizeof(Node));
		if(temp!=NULL){          //检查是否申请空间成功
		temp->next=NULL;               
		printf("请输入id与Score:\n");
		scanf("%d %d",&temp->id,&temp->Score);
		}

        //************
        //将节点添加到链表末尾
        //************
		p1=Head;
		while(p1->next!=NULL)
		{
			p1=p1->next;          //找到链表的末尾
		}
        p1->next=temp;            //将节添加到链表的末尾
		//printf("*****%d",Head->next->id);

	}
	printf("现在输出链表中的4个节点:\n");
	//************
    //输出链表
    //************
	p1=Head->next;
	while(p1!=NULL){
		printf("id为%d,成绩为%d\n",p1->id,p1->Score);
		p1=p1->next;
	}
    //*********
	//查找节点
	//*********
    printf("请输入你要查找的学生id:\n");
	int tempid;          
	scanf("%d",&tempid);
	p1=Head->next;
	while(p1!=NULL)  //到链表末尾或找到该id则停止循环
	{
		if(p1->id==tempid) break;
    	p1=p1->next;
	}
    if(p1!=NULL){                     //如果不是到链表末尾,当然就是找到该id
		printf("找到该id学生,其分数为%d:\n",p1->Score);
	}
	else{                            //到末尾了,说明该id没找到
		printf("没有找到该id的学生\n");
	}
	//**********
	//删除节点
	//**********
    printf("请输入你要删除的学生id:\n");
	scanf("%d",&tempid);
	p1=Head;
	while(p1!=NULL)
	{  
		if(p1->id==tempid) break;
		p2=p1;                        //记录要删除节点的上一个加点                          
    	p1=p1->next;
	}
    if(p1!=NULL){
		 p2->next=p1->next;           //删除的核心代码
		 free(p1);
	}
	else{
		printf("没有找到该id的学生\n");
	}
	//************
    //输出链表
    //************
	p1=Head->next;                     //用于验证是否删除成功
	while(p1!=NULL){
		printf("id为%d,成绩为%d\n",p1->id,p1->Score);
		p1=p1->next;
	}
    return 0;
}

     
     
    
    

        
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值