(语法)理解链表:建立,插入
2016-03-25 08:37
295 查看
链表是将一个个独立的数据利用指针将他们链接起来,达到方便访问,调用的一个功能,下面通过一个小程序对链表进行分析:
上面程序首先在第3行定义了一个结构体student,此结构体下面的有3个类型,最后一个是一个指针变量,而且是一个词结构体类型的指针变量,它的作用就是存储它后面一个对象的内存地址,以此类推,即将所有的独立对象通过指针链接起来形成链表了。
再下面student m_head = { 0,"head",NULL };
这个是定义了一个student类型的变量m_head,这个变量的内容为0,即此结构变量下面的三个参数都是空值,这就表示用它做一个链表头,链表头的作用是方便在链表头后面插入新的数据或者删除数据等等,因为如果没有链表头,仅从第一个数据开始是非常麻烦的,这就代表了需要一个链表头的存在。
下面的add(student* obj)函数先不解释,先看下面主函数中的内容,主函数中首先定义了一个sudent类型的chu数组(这里定义数组的主要作用只是为了试验,将这些数组链接起来),这个数组有5个元素,并对应的为他们赋了值,再下面的 m_head.next = &chu[0];
chu[0].next = &chu[1];
chu[1].next = &chu[2];
chu[2].next = &chu[3];
chu[3].next = &chu[4];
chu[4].next = 0;
这组赋值操作就是开始定义链表,即从链表头的指针变量开始依次将下一个对象的内存地址赋值给上一个对象的指针变量,以此便形成了链表结构。
下面的student* obj = (student*)malloc(sizeof(student));是动态分配一个内存空间出来,以供存储用户输入的信息,然后调用add(obj)函数将用户输入到内存中的信息插入到链表中去。
下面来看函数add(obj)是如何将此对象插入到链表中的,add函数中只有两条语句obj->next = m_head.next;和m_head.next = obj;不难理解,首先将之前m_head.next指针中的地址赋值给新对象obj的指针next(之前m_head中存储的地址是它下一个对象即chu[0]的内存地址),现在obj的next指针一句指向了之前链表中的第一个对象chu[0],obj变成了第一个对象,然后m_head.next
= obj;这句更好理解了,就是将现在的第一个对象obj的内存地址赋值给链表头m_head的next指针(因为obj就是一个指针变量,所以它的值可以直接赋值),那么现在就完成了将新对象插入到链表头下面的操作,成为了第一个对象并和后面的对象链接了起来。
最后面是一个whil循环,它的判断条件只有一个指针变量p,也就是说当p为真(不等于0)就一直循环执行下面的语句,若为假(等于0)就停止循环,我们在上面的链表中为最后一个链表的指针式赋值为0的,所以说这里这个循环执行到最后一个的时候就可以结束了。
循环里面的语句很简单,第一行是将结构体中的数据域部分输出出来,第二句就是关键了,它是将当前对象的指针中存储的内存地址赋值给指针变量p,我们知道此链表中每个对象中指针存储的内存地址都是下一个对象的内存地址,所以这里没执行一次循环p就会变成下一个对象的地址就会跳到下一个对象继续执行循环,直到遇到那个对象中的p等于0就停止循环,这里就是链表的遍历。
总结:指针的作用很大,可以实现各种各样的用途,还是需要深入理解指针,链表主要是靠声明结构类型是设定一个指针变量类型实现的,我们叫此种结构体中那个存储下一个对象地址的指针叫指针域,其余的都叫做数据域,即存储数据用的。
#include<iostream> using namespace std; struct student //定义类型为student的一个结构体 { int id; char name[16]; student* next; }; student m_head = { 0 }; <span style="white-space:pre"> </span> //定义链表头 void add(student* obj) //定义增加链表函数 { obj->next = m_head.next; m_head.next = obj; } int main() //主函数 { student chu[5] = //定义一个结构数组并为他们赋值 { { 11,"a1",0 }, { 12,"a2",0 }, { 13,"a3",0 }, { 14,"a4",0 }, { 15,"a5",0 } }; m_head.next = &chu[0]; //将这些结构链接起来形成链表 chu[0].next = &chu[1]; chu[1].next = &chu[2]; chu[2].next = &chu[3]; chu[3].next = &chu[4]; chu[4].next = 0; student* obj = (student*)malloc(sizeof(student)); //动态获取一块内存,指针obj指向它 cout << "输入ID:"; cin >> obj->id; //用户输入id cout << "输入姓名:"; cin >> obj->name; //用户输入name add(obj); //调用链表增加函数将对象obj增加到链表头 student* p = m_head.next; while (p) //whill循环遍历链表 { cout << p->id << " " << p->name << endl; p = p->next; } system("pause"); return 0; }
上面程序首先在第3行定义了一个结构体student,此结构体下面的有3个类型,最后一个是一个指针变量,而且是一个词结构体类型的指针变量,它的作用就是存储它后面一个对象的内存地址,以此类推,即将所有的独立对象通过指针链接起来形成链表了。
再下面student m_head = { 0,"head",NULL };
这个是定义了一个student类型的变量m_head,这个变量的内容为0,即此结构变量下面的三个参数都是空值,这就表示用它做一个链表头,链表头的作用是方便在链表头后面插入新的数据或者删除数据等等,因为如果没有链表头,仅从第一个数据开始是非常麻烦的,这就代表了需要一个链表头的存在。
下面的add(student* obj)函数先不解释,先看下面主函数中的内容,主函数中首先定义了一个sudent类型的chu数组(这里定义数组的主要作用只是为了试验,将这些数组链接起来),这个数组有5个元素,并对应的为他们赋了值,再下面的 m_head.next = &chu[0];
chu[0].next = &chu[1];
chu[1].next = &chu[2];
chu[2].next = &chu[3];
chu[3].next = &chu[4];
chu[4].next = 0;
这组赋值操作就是开始定义链表,即从链表头的指针变量开始依次将下一个对象的内存地址赋值给上一个对象的指针变量,以此便形成了链表结构。
下面的student* obj = (student*)malloc(sizeof(student));是动态分配一个内存空间出来,以供存储用户输入的信息,然后调用add(obj)函数将用户输入到内存中的信息插入到链表中去。
下面来看函数add(obj)是如何将此对象插入到链表中的,add函数中只有两条语句obj->next = m_head.next;和m_head.next = obj;不难理解,首先将之前m_head.next指针中的地址赋值给新对象obj的指针next(之前m_head中存储的地址是它下一个对象即chu[0]的内存地址),现在obj的next指针一句指向了之前链表中的第一个对象chu[0],obj变成了第一个对象,然后m_head.next
= obj;这句更好理解了,就是将现在的第一个对象obj的内存地址赋值给链表头m_head的next指针(因为obj就是一个指针变量,所以它的值可以直接赋值),那么现在就完成了将新对象插入到链表头下面的操作,成为了第一个对象并和后面的对象链接了起来。
最后面是一个whil循环,它的判断条件只有一个指针变量p,也就是说当p为真(不等于0)就一直循环执行下面的语句,若为假(等于0)就停止循环,我们在上面的链表中为最后一个链表的指针式赋值为0的,所以说这里这个循环执行到最后一个的时候就可以结束了。
循环里面的语句很简单,第一行是将结构体中的数据域部分输出出来,第二句就是关键了,它是将当前对象的指针中存储的内存地址赋值给指针变量p,我们知道此链表中每个对象中指针存储的内存地址都是下一个对象的内存地址,所以这里没执行一次循环p就会变成下一个对象的地址就会跳到下一个对象继续执行循环,直到遇到那个对象中的p等于0就停止循环,这里就是链表的遍历。
总结:指针的作用很大,可以实现各种各样的用途,还是需要深入理解指针,链表主要是靠声明结构类型是设定一个指针变量类型实现的,我们叫此种结构体中那个存储下一个对象地址的指针叫指针域,其余的都叫做数据域,即存储数据用的。
相关文章推荐
- dos 实用命令搜集
- (笔记)Linux内核学习(十一)之I/O层和I/O调度机制
- (笔记)Linux内核学习(十)之虚拟文件系统概念
- (笔记)Linux内核学习(九)之内核内存管理方式
- (笔记)Linux内核学习(八)之定时器和时间管理
- 详解Javascript的继承实现
- 二分查找
- (笔记)Linux内核学习(七)之内核同步机制和实现方式
- (笔记)Linux内核学习(六)之并发和同步概念
- Java实现单例模式
- 利用httpclient进行模拟登陆;
- 被召者 RC: REGDB_E_CLASSNOTREG (0x80040154)
- 数据库三范式粗暴简单理解法
- Deep Boltzmann Machines
- TOMCAT连接调优和JVM内存调优
- python中元组(tuple)用法总结
- 出差(三十)
- freeradius 2.2.5版本限制用户并发登录
- Three.js框架,菜鸟上路
- BZOJ 1415: [Noi2005]聪聪和可可