㈠ 数据结构中的链表是不是可以存放不同类型的数据 int型char型之类的 还是只能存放同一种类型的元素
要看你建的是什么类型的表了 要是你typedef的是整型的表那就只能放整形的数据 double float这些就不行 但是要是你用结构体定义里面包括不同的类型也是可以的 比如说你要建个学生姓名和成绩的链表就可以这样
typedef struct data{
int num;
char name[20];
float score[M];
} data; //定义学生资料结构体
typedef struct stu{
data student;
struct stu *next;
}stu,*LinkList; //定义链表头结点
然后再建立这个结构体的链表
L=(LinkList)malloc(sizeof(stu));
if(!L)
return 0; //异常处理
L->next=NULL; //建立带头结点的单链表
下面接着输入学生资料函数就可以了 这样也就是可以同时输入不同类型数据了
我没打全 不知道明白没.....我觉得说的挺乱.............
㈡ 已知单链表L中的数据元素类型为整型,设计算法删除所有偶数
遍历L中的所以元素,查询是否为偶数,是则删除,删除元素前先把前一个元素的next指针指向后一个元素,由于是L是单链表 ,所以查询元素时需要定义两个指针变量,一个用来存储当前元素的地址一个用来存储前一个元素的地址,如果不用两个指针来就不知道前一个元素的地址了.我这里只是说了方法而已,具体编程还需要看你具体题目,如果可以的话,附上题目,我帮你做了
㈢ iOS - 链表
链表最基本的结构是在每个节点保存数据到下一个节点的地址,在最后一个节点保存一个特殊的结束标记。另外在一个固定的位置保存指向第一个节点的指针,有的时候也会同时储存指向最后一个节点的指针。但是也可以提前把一个节点的位置另外保存起来,然后直接访问,当然如果只是访问数据就没必要了,不如在链表上出错指向实际数据的指针。这样一般是为了访问链表中下一个或者前一个节点
优势 :
可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理
链表最明显的好处是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数组的存取往往要在不同的排列顺序中转换。而列表是一种自我指示数据类型,因为它包含指向另一个相同类型的数据的指针(链接),同时,链表允许插入和移除表上任意位置上的节点.
劣势 :
链表由于增加了节点的指针域,空间开销比较大;另外,链表失去了数组随机读取的优点,一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置
链表中最简单的一种是单向链表
一个单向链表的节点被分成两个部分,它包含两个域,一个信息域和一个指针域,第一个部分保存或者显示关于节点的信息,第二个节点存储下一个节点的地址,而最后一个节点则指向一个空值。单向链表只可向一个方向遍历
单链表有一个头节点 head ,指向链表在内存的首地址,链表中的每一个节点的数据类型为结构体类型,节点有两个成员:整型成员(实际需要保存的数据)和指向下一个结构体类型节点的指针即下一个节点的地址(事实上,此单链表是用于存放整型数据的动态数组)。链表按此结构对各节点的访问需从链表的头找起,后续节点的地址由当前节点给出。无论在表中访问哪一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为NULL
上图还给出这样一层含义,链表中的各节点在内存的存储地址不是连续的,其各节点的地址是在需要时向系统申请分配的,系统根据内存当前的情况,即可以连续的分配地址,也可以跳跃式分配地址
单向列表程序的实现
在链表节点的定义中,除一个整形的成员外,成员 next 是指向与节点类型完全相同的指针
在链表节点的数据结构中,非常特殊的一点就是结构体内的指针域的数据类型使用了未定义成功的数据类型。 这是C中唯一规定可以先使用后定义的数据结构
创建一个存放正整数单链表,输入0或小于0的数,结束创建链表,并打印链表中的
在链表的创建过程中,链表的头指针是非常重要的参数,因为对链表的输出和查找都要从链表的头开始,所以链表创建成功后,要返回一个链表节点的地址,即头指针
程序执行流程:
双向链表其实是单向链表的改进,当我们对单链表进行操作时,有时你要对某个节点的直接前驱进行操作时,又必须从表头开始查找。这是由单链表节点的结构所限制的,因为单链表每个节点只有一个存储直接后继节点地址的链域,那么能不能定义一个既有存储直接后继节点地址的链域,又有存储直接前驱节点地址的链域的这样一个双链节点结构呢? 这就是双向链表
在双向链表中,节点除含有数据域外,还有两个链域,一个存储直接后继节点地址,一般称为右链域(当此"连接"为最后一个"连接"时,指向空值或空列表);一个存储直接前驱节点地址,称为左链域(当此"连接"为第一个"连接"时,指向空值或空列表)
双向链表节点定义
当然,也可以把一个双向链表构成一个双向循环链表。
双向列表与单向链表一样,也有三种基本运算:查找、插入和删除
循环链表是与单向链表一样,是一种链式的存储结构,所不同的是,循环链表的最后一个节点的指针是指向该循环链表的第一个节点或者头节点,从而构成一个环形的链
循环链表的运算与单链表的运算基本一致,所不同的有以下几点:
块状链表本身是一个链表,但是链表存储的不是一般的数据,而是由这些数据组成的顺序表。每一个块状链表的节点,也就是顺序表,可以被叫做一个块
块状链表另一个特点是相对于普通链表来说节省内存,因为不用保存指向每一个数据节点的指针
参考: ios -链表的简单认识
㈣ 1>构造一个链表,每个结点存储的是整型数据。 如:(2,4,6,8,10,12,14,16,18,20) <2
#include<iostream.h>
structnode{
intdata;
structnode*next;
};
node*createlist(){/*以上是构造一个链表*/
node*u,*p,*head;
intx;
head=newnode;
head->data=0;
p=head;
while(x!=0){
cout<<"请输入数据(0结束输入过程):";
cin>>x;
if(x==0)break;
u=newnode;
u->data=x;
u->next=NULL;
p->next=u;
p=u;
}
returnhead;
}
voiddisplist(node*L){
inti=0;
node*p=L->next;
while(p!=NULL){
if(i%10==0)cout<<endl;
cout<<p->data<<"";
p=p->next;
i++;
}
}
intlist_length(node*L){//求表的长度
intcount=0;
node*p=L->next;
while(p!=NULL){
count++;
p=p->next;
}
return(count);
}
voidtraversal(node*L){//输出连表中的值
if(!L)return;
node*p=L->next;
while(p){
cout<<p->data<<"";
p=p->next;
}
}
voidlist_insert(node*L,inti,intx){//在指定位置插入结点
node*s,*p=L->next;
intk=0;
while((k!=i-1)&&(p!=NULL)){
p=p->next;
k++;
}
if(p==NULL)cout<<"序号错。"<<endl;
else{
s=newnode;
s->data=x;
s->next=p->next;
p->next=s;
}
}
voidlist_delete(node*L,inti){//删除结点
node*u,*p=L;
intk=0;
while((k!=i-1)&&(p!=NULL)){
p=p->next;
k++;
}
if((p==NULL)||(p->next==NULL))cout<<"删除序号错。"<<endl;
else{
u=p->next;
p->next=u->next;
deleteu;
}
}
voidlist_insertincrease(node*L,intx){//在增序表中插入结点
node*u,*p=L;
while((p->next!=NULL)&&(p->next->data<x))p=p->next;
u=newnode;
u->data=x;
u->next=p->next;
p->next=u;
}
voidmain(){
// intx,i;
node*head;
head=createlist();
cout<<"显示链表:"<<endl;
displist(head);
cout<<"插入数据36后:"<<endl;
list_insert(head,2,36);
displist(head);
cout<<"删除结点2后:"<<endl;
list_delete(head,2);
displist(head);
}