定义 : 链表 是一种物理存储单元上 非连续、非顺序 的存储结构,由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
在链表的储存上,每个结点不仅包含所存的元素信息,还包含元素间的 逻辑信息 。
在每个结点除了包含的数据域外,还包含一个 指针域 ,用以指向其后继结点。
带头结点的单链表中, 头指针head 指向头结点,头结点的值域不含任何信息,从头结点的后继结点开始储存信息。头指针head 始终 不等于NULL , head->next 等于NULL的时候,链表为空。
不带头结点的单链表中的 头指针head 直接指向开始结点,当head等于NULL时,链表为空。
双链表就是在单链表结点上增添了一个指针域,指向当前节点的 前驱 。
相比于单链表,双链表能够从 终端结点 反向走到 开始结点 。
只需要将单链表 最后一个 指针域( 空指针 )指向链表中的 第一个结点 即可。(如果循环单链表带头结点,则指向头结点;不带头结点,则指向开始结点)。
循环单链表可以实现从 任何一个结点 出发,访问链表中任何结点。(注意:此处应该区分与顺序表随机访问的特点。循环单链表指的是从一个结点出发,而不是知道一个结点从而迅速找到任何一个结点,因此循环单链表 不具有 随机访问特性。)
带头结点 的循环单链表,当 head 等于 head->next 时,链表为空; 不带头结点 的循环单链表,当 head 等于 NULL 时,链表为空。
双链表 终端节点的next指针 指向链表中第一个结点,将链表中的第一个结点的 prior指针 指向终端结点。
不带头结点 的循环双链表, head 等于 NULL ,链表为空
带头结点 的循环双链表是没有空指针的,其为空状态下, head->next 与 head->prior 必然都等于 head ,故一下四种语句都可判断为空
静态链表借助 一维数组 表示。
静态链表结点空间来自于一个 结构体数组 (一般链表结点空间来自整个内存),数组中每个结点含两个分量:
注意:静态链表的指针不是通常所说储存内存地址的指针型变量,而是储存数组下标的整型变量,其功能类似于指针,故在此称为指针
顺序表储存空间时一次性分配的,链表的是多次分配的
(注: 存储密度 = 结点值域所占存储量/结点结构所占存储总量 )
顺序表存储密度 = 1
链表存储密度 < 1
顺序表可以 随机存取 ,也可以 顺序存取
链表只能 顺序存取
顺序表平均需要移动一半元素
链表不需要移动元素,仅需 修改指针
gcc:pass#include "stdioh"
#include "stdlibh"
typedef struct text{
int id;
char name[9];
int age;
struct text p_node;
}T;
void main()
{
int t=1;
T p_temp,p_head,p_last;
p_temp=(T )malloc(sizeof(T));
printf("请输入 学号 姓名 年龄 \n");
//scanf("%d",p_temp->id);
scanf("%d",&p_temp->id);
getchar();
//gets(p_temp->name);
scanf("%s",p_temp->name);
//scanf("%d",p_temp->age);
scanf("%d",&p_temp->age);
p_head=p_last=p_temp;
//while((p_temp->id))//为什么这行有错误
while(1)//因为已经是int不能再 加*
{//add begin
char con;
printf("继续输入否(Y/N)\n");
getchar();
scanf("%c",&con);
if(con == 'Y' || con == 'y')
;
else
break;
//add end
p_temp=(T )malloc(sizeof(T));
//scanf("%d",p_temp->id);
scanf("%d",&p_temp->id);
//gets(p_temp->name);
scanf("%s",p_temp->name);
//scanf("%d",p_temp->age);
scanf("%d",&p_temp->age);
p_last->p_node=p_temp;
p_last=p_temp;
t++;//add
}
p_temp=p_head;
//while((p_temp->id))
while(t--)
{
//printf("t==%d\n ",t);
printf("%5d",p_temp->id);
//puts(p_temp->name);
printf("%7s ",p_temp->name);
printf("%4d\n",p_temp->age);
p_temp=p_temp->p_node;
}
}
Java语言中的对象引用实际上是一个指针(这里的指针均为概念上的意义,而非语言提供的数据类型),所以我们可以编写这样的类来实现链表中的结点。
private static class Entry<E> {
E element; // 当前存储元素
Entry<E> next; // 下一个元素节点
Entry<E> previous; // 上一个元素节点
Entry(E element, Entry<E> next, Entry<E> previous) {
thiselement = element;
thisnext = next;
thisprevious = previous;
}
}
将数据域定义成Object类是因为Object类是广义超类,任何类对象都可以给其赋值,增加了代码的通用性。为了使链表可以被访问还需要定义一个表头,表头必须包含指向第一个结点的指针和指向当前结点的指针。为了便于在链表尾部增加结点,还可以增加一指向链表尾部的指针,另外还可以用一个域来表示链表的大小,当调用者想得到链表的大小时,不必遍历整个链表。
链表的数据结构我们可以用类List来实现链表结构,用变量Head、Tail、Length、Pointer来实现表头。
存储当前结点的指针时有一定的技巧,Pointer并非存储指向当前结点的指针,而是存储指向它的前趋结点的指针,当其值为null时表示当前结点是第一个结点,因为当删除当前结点后仍需保证剩下的结点构成链表,如果Pointer指向当前结点,则会给 *** 作带来很大困难。如何得到当前结点呢?我们定义了一个方法cursor(),返回值是指向当前结点的指针。类List还定义了一些方法来实现对链表的基本 *** 作,通过运用这些基本 *** 作我们可以对链表进行各种 *** 作。
例如reset()方法使第一个结点成为当前结点。insert(Object d)方法在当前结点前插入一个结点,并使其成为当前结点。remove()方法删除当前结点同时返回其内容,并使其后继结点成为当前结点,如果删除的是最后一个结点,则第一个结点变为当前结点。
链接文件和索引文件是其中两种文件的物理结构,是两种离散的存储结构。链接分配是一种离散分配方式,可将文件装到多个离散的盘块中,可通过在每个盘块上的链接指针,将同属于一个文件的多个离散盘块链接成一个链表。这样形成的物理文件就是链接文件。
索引分配是在打开某个文件时,只需把该文件占用的盘块的编号调入内存即可,完全没有必要调入整个FAT。为此为每个文件分配一个索引块(表),再把分配给该文件的所有盘块号,都记录在该索引块中。这样形成的物理文件就是索引文件。
空闲块链是将外存中的所有空闲盘快用链表的形式表示,这是文件存储空间管理的其中一种方法。或许这是让每一个IT初学者很头痛的问题,明明我们在之前已经接触了数组,感到数组已经是万能的数据存储位置了,但是,如果我们如果一直在使用比较复杂的数据(也就是比较多的数据时),我们肯定会感到很反感,因为对于数组这种数据结构,在你自己使用之前,一定要对其大小进行一番定义,这样一来,它的存储空间在数据处理过程中显得极为不方便,因为谁也不想对将要处理的数据做一个空间的预算,这是我们每一个程序员都很忌讳的,并且还要让其空间足够大,这样才能满足我们的要求(但是如果分配的太多,难免会浪费内存)。
上面的一切都证明使用数组需要注意的东西真的很多很多,这样一来,我们就开始说说链表,链表也是一种数据结构,它弥补了数组带来的诸多不便,让我们可以任意为一些数据进行空间的分配,根据需要进行内存单元的开辟。当然对于链表而言,分为静态链表和动态链表,根据处理数据的方向又分为单向链表和双向链表。
提到链表我们都知道还有一个比较重要的知识点就是指针,因为前后数数据要有关联,必须要进行一系列的连接和指向处理,那么扮演这个角色的就是指针,并且,在现在的编程语言中,指针是任何东西都没有办法去替代的。可见它的重要性。
当然在学习了结构体之后,我们对链表的了解应该就比较轻松,说白了,链表就是通过指针连接的多个结构体。知识每一个结构体中有一个存放指针的成员变量,并且,这个成员的类型是该结构体类型的。每一个链表,都有这个自己的结点,这些结点是结构体的变量,当然,他们也是结构体类型的变量。问题一:链表是什么东西 链表是一种有序的列表,链表的内容通常是存储与内存中分散的位置上。
链表的方式有两种1:一种是利用数组结构串连的有序列表。
例如;两个数组,一个存放数据,另一个存放连接的关系。这种缺乏d性。
2:以动态内存配置的链表,(通常指的链表是一动态内存分配的链表)动态内存配置的链表,
是由许许多多的(node)所链接而成的,每一个结点,包含了数据部分和指向下一个结点的指针(Pointer)。
以动态内存配置的链表,在插入和删除元素的时候,只需要将指针改变指向就可以。
链表和数组一样是一种数据结构,如何使用完全基于你的应用需求。
链表和C++语言本身没有任何联系。很多语言都可以实现链表数据结构。
我讲一下数据和链表的区别有可能帮助你对链表的使用有个感觉。
数组是将元素在内存中连续存放,由于每个元素占用内存相同,所以你可以通过下标迅速访问数组中任何元素。但是如果你要在数组中增加一个元素,你需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果你想删除一个元素,你同样需要移动大量元素去填掉被移动的元素。
链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。比如:上一个元素有个指针指到下一个元素,以此类推,直到最后一个元素。如果你要访问链表中一个元素,你需要从第一个元素开始,一直找到你需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了, 只要修改元素中的指针就可以了。
从上面的比较你可以看出,如果你的应用需要快速访问数据,很少或不插入和删除元素,你就应该用数组;相反, 如果你的应用需要经常插入和删除元素你就需要用链表数据结构了。然后你自己可以想一想什么样的应用用链表合适。
另外,建议你找一本好一点的关于数据结构的书,里面应该关于链表和其上算法的详细介绍。链表本身是一个复杂的数据结构,而且包括很多种类,比如单向链表,双向链表,树,图等,不是一篇文章可以介绍得清楚的。
问题二:列表与链表有什么区别 列表,不清楚。应该说的是表。
表在数据结构中,是表示一种线性关系的数据结构。
链表,应该是链接表 是 表的一种存储结构。
表从存储结构上分为 顺序表和链接表。
顺序表是指在内存中连续存储的数据存储空间,数组。可以用下标访问每一个单元。
链接表是指在内存中不是连续存储而是由指针链连接各个单元的线性存储空间。
问题三:C语言链表中q->next=p;表示什么意思 q-next=p;
把p的地址赋给q的下一个地址
while (q)
{r=q->next;
q->next=p;
p=q;
q=r; }
把q的下一个地址赋给r;
p的地址赋给q的下一个地址;
q的地址赋给p的地址
r的地址赋给q;
直到q->next的地址为0就结束循环处其实链表要自己多画画就直到怎么回事了
问题四:c链表中 L->是什么 意思????求解?? L是头指针,指向的是头结点或者第一个数据元素结点。由于结点是一个结构体,通过指针引用结构体成员的方法就是L->data或者L->next
问题五:单链表中data是什么意思 这个是c里面的指针用法。 p是一个指针。 p->next 一般表示指向下一个存储单元,就是下一个存储单元的地址信息。 p->data 表示 p这个指针的存储单元中的值
问题六:java里的链表指的是什么?为什么需要链表? java中的 类有很多种,每个都有自己的一些特点,推荐你专门在这方面研究一下,比方Vector,ArrayList,,LinkedList,Hashtable等,
其中你问到的链表,是不是指LinkedList呢
LinkedList是 类的一种,和其它 类一样都用于存放未知内容和未知长度的数据或者说对象
由于LinkedList的内部实现是采用链表结构,所以它就取名为LinkedList
当然ArrayList的内部实现是采用数组结构,所以它就取名为ArrayList,呵呵,很好理解吧
它们就相当于一个容器,跟数据一样,可以存放数据,但数组你必须在一开始就指定它里面的内容是什么类型的,比方你必须 int[] array;
而 类就没有必要,只需要: Vector vector=new Vector();就可以,
至于放里面存放数据就更简单了,它什么都可以放,只要是对象:
String str=hello;
vectoradd(str);
Integer i=10;
vectoradd(i);
取数据的时候需要做类型强制转换,因为你放的时候没有强制指定类型:
String str=(String)vectorget(0);
String i=(Integer)vecotrget(1);
其它几种 类也和vector埂用法接近,但有些会有些变化和特点, 类是java语言的一个重点学习项目,一定要深入了解,不要光从百度上搜,一定要自己多看书,多做实例 >中有专门的一章重点讲解 类
问题七:链表中p→data++啥意思? 这个是c里面的指针用法。
p是一个指针。
p->next 一般表示指向下一个存储单元,就是下一个存储单元的地址信息。
p->data 表示 p这个指针的存储单元中的值
问题八:C风格的链表是什么意思 单链表就是只有一个节点指针的,就是你只能顺序访问链表中的每一个节点,因为他只包含了指向下一个节点的指针,而双链表就是由两个节点指针变量的,一个指向下一个,一个指向上一个,这样子,你既可以访问上一个节点,也可以访问下一个节点。怎
问题九:谁能解释一下这个链表指针是什么意思 一个int占四个字节,一个字母是一个字节,所就是说一般情况,temp中只能存四个字母,你的temp中存的如果是abce,那么他的二进制内容是否是: 01100001 01100010 01100011 01100100的形式呢?我这么说对吗?
#include
int main()
{
union {
int temp;
char s[5];
} data;
datatemp=1633837924;
/
01100001 01100010 01100011 01100100B=1633837924
a b c d
X86机器,是little endian编码,所以,输出是dcba
/
datas[4]=0;
printf(s=%s\n,datas );
getchar();
return 0;
}
问题十:什么叫单链表 数据的连接存储表示又称为连接表。当连接表中的每个结点只含有一个指针域时,则被称为单链表。个人理解其实就相当于用一根线(两个点之间唯一一根),其实就是指针把各个结点连起来的数据存储方式。
参考:《数据结构 C语言描述》徐晓凯、贺桂英
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)