zoukankan      html  css  js  c++  java
  • 第十四次课:链表

    0、为何学习链表

    学习数据结构做准备。学了数据结构会发现数据可以组合成各种形状,线性表,堆栈,队列,串,树状,图等。

    1、链表和数组的区别

    数组建立之后不可修改(增删),链表可以。比如建立数组之后,增加一个元素,实现起来就是插入一个元素,然后该元素后面的所有元素都需要往后撤一个位置,数组实现起来很麻烦。再比如删掉一个元素,那么后面的元素都需要往前前进一个位置,实现起来也很麻烦。而链表实现增删操作则很容易,只是一句赋值语句而已。

    数组是静态的,链表是动态的。虽然C99允许数组个数是一个变量,后期输入,但是一旦输入了也不好再修改,但是链表不同,链表非常方便完成增删操作,所以链表可以随时根据我们的需要增加或者释放一个元素。

    2、链表的结构

    链表有头指针和结点组成,头指针是一个存储单元,这个存储单元存放一个地址,该地址指向一个元素(结点),每个结点包括两部分,一部分是实际数据,另一部分是下一个结点的地址。链表类似火车,头指针像一个火车头,结点类似火车厢,火车厢通过每节车厢后的挂绳链接再一起,但是火车厢总有结束的时候,最后一节火车厢不链接任何东西,称为火车尾,类似的,链表中最后一个结点称为表尾,它也是一个结点,结点地址部分放一个NULL(空地址)。

    3、静态链表的建立

    链表有一个头指针和多个结点组成,头指针使用指针实现即可,而结点又包括两部分内容,且两部分内容的数据类型不一样,在我们所学习的数据类型中,只有结构可以胜任了,例如可以如下定义结点的结构类型:

    struct Student 
    {
        int num;
        float score;
        struct Student *next;
    };
    

    其中num和score是实际数据,next是下一个结点的地址,每个结点都是一个结构变量,所以指向结构变量的指针自然是结构类型。上述程序只是结点的类型,并不是实际的结点,或者说实际分配存储空间,只有定义了结构变量才会分配存储空间,例如下面的程序则为建立真实的链表:

    #include <stdio.h>
    
    struct Student{                 //定义结构类型  //全局变量,main和子函数是处于同一个等级
    	int num;
    	float score;
    	struct Student *next;
    };
    
    int main(){
     /*(1)定义各结点*/
    	struct Student a,b,c,*head;           
    /*(2)初始化各结点的实际数据*/
    	a.num =10101;a.score=88.5;               
    	b.num =10103;b.score=90;
    	c.num =10107;c.score=85;
    /*(3)将各结点链接在一起*/	
    	head=&a;
    	a.next=&b;
    	b.next =&c;
    	c.next =NULL;
    /*打印各结点的实际数据*/	
    	struct Student *p=head;                 //1)定义指针指向头指针,头指针不可变,所以不可以使用头指针遍历整个链表
    	for(;p!=NULL;p=p->next){                        //2)p=p->next实现p指向每一个结点   //关于for循环的大括号
    		printf("%ld %5.1f
    ",p->num,p->score);    //3)使用->运算符打印输出每个结点数据
    	}
    	
    	return 0;                                     //关于返回值
    } 
    

    建立链表需要上述(1)-(3)3个步骤,打印/输出链表则需要1)-3)3个步骤。

    课上练习题:

    例1:
    (1)建立链表,实际数据包括学号,姓名。并使用同一排3名同学的信息进行初始化。
    (2)输出3名同学的信息。

    #include <stdio.h>
    #include <string.h> 
    
    struct Student{
    	int num;
    	char name[20];
    	struct Student *next;
    };
    
    int main(){
    	struct Student a,b,c,*head;
    	a.num =22;strcpy(a.name,"于金池");
    	b.num =23;strcpy(b.name,"于港岩");
    	c.num =24;strcpy(c.name,"王丫");
    	
    	head=&a;
    	a.next=&b;
    	b.next =&c;
    	c.next =NULL;
    	
    	struct Student *p=head;
    	for(;p!=NULL;p=p->next){
    		printf("%ld %s
    ",p->num,p->name);
    	}
    	
    	return 0;
    } 
    

    例2:
    (1)建立链表,实际数据包括学号,姓名。并使用同一排3名同学的信息进行初始化。
    (2)建立函数printinfo,参数是结构指针,在该函数中实现输出3名同学的信息。

    #include <stdio.h>
    #include <string.h> 
    
    struct Student{
    	int num;
    	char name[20];
    	struct Student *next;
    };
    
    void printinfo(struct Student *p){
    	for(;p!=NULL;p=p->next){
    		printf("%ld %s
    ",p->num,p->name);
    	}
    } 
    
    int main(){
    	struct Student a,b,c,*head;
    	a.num =22;strcpy(a.name,"于金池");
    	b.num =23;strcpy(b.name,"于港岩");
    	c.num =24;strcpy(c.name,"王丫");
    	
    	head=&a;
    	a.next=&b;
    	b.next =&c;
    	c.next =NULL;
    	
    	printinfo(head);
    	
    	return 0;
    } 
    

    例3:
    (1)建立链表,实际数据包括学号,姓名。并使用同一排3名同学的信息进行初始化。
    (2)建立函数searchinfo,参数是结构指针,在该函数中实现输出你自己的信息。

    #include <stdio.h>
    #include <string.h> 
    
    struct Student{
    	int num;
    	char name[20];
    	struct Student *next;
    };
    
    void searchinfo(struct Student *p){
    	for(;p!=NULL;p=p->next){
    		if(p->num ==22)
    		printf("%ld %s
    ",p->num,p->name);
    	}
    } 
    
    int main(){
    	struct Student a,b,c,*head;
    	a.num =22;strcpy(a.name,"于金池");
    	b.num =23;strcpy(b.name,"于港岩");
    	c.num =24;strcpy(c.name,"王丫");
    	
    	head=&a;
    	a.next=&b;
    	b.next =&c;
    	c.next =NULL;
    	
    	searchinfo(head);
    	
    	return 0;
    } 
    

    在上述函数调用中,函数参数是链表头指针,因为通过链表头指针可以访问到链表中的任意结点,因此在定义相关的操作函数时,可以使用头指针作为参数和返回值。

  • 相关阅读:
    Leetcode练习(Python):链表类:第206题:反转链表:反转一个单链表。
    Leetcode练习(Python):链表类:第203题:移除链表元素:删除链表中等于给定值 val 的所有节点。
    Leetcode练习(Python):链表类:第160题:相交链表:编写一个程序,找到两个单链表相交的起始节点。
    Leetcode练习(Python):链表类:第141题:环形链表:给定一个链表,判断链表中是否有环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
    Leetcode练习(Python):链表类:第83题:删除排序链表中的重复元素:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
    【Java基础总结】数据库编程
    【Java基础总结】多线程
    特迷茫的大三时期
    解决忘记了开机密码,无法进入系统的方法
    一开机未通过输入密码登录,就出现用户名或密码错误??
  • 原文地址:https://www.cnblogs.com/c-programing-language/p/6697610.html
Copyright © 2011-2022 走看看