且顺序存储
① 线性表(a1,a2,a3,…,an)中元素递增有序且按顺序存储与计算机内。要求完成:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct line
{
int data;
line *next;
}Line;
void print(Line *head);
void search(Line *head);
void insert(Line *head,int data);
void change(Line* q);
void search(Line *head)
{
Line *p,*q;
int data,flag=0;
q=head;
p=head->next;
printf("input data:");
scanf("%d",&data);
while (p!=NULL)
{
if(p->data==data)
{
flag=1;
break;
}
q=p;
p=p->next;
}
if(flag==0)
insert(head,data);
else if(flag==1)
change(q);
}
void change(Line* q)
{
Line *p;
p=q->next;
if(p->next==NULL)
return;
q->next=p->next;
p->next=NULL;
q=q->next;
p->next=q->next;
q->next=p;
}
void insert(Line *head,int data)
{
Line *p,*q,*r;
int flag=0;
r=(Line*)malloc(sizeof(Line));
r->next=NULL;
r->data=data;
q=head;
p=head->next;
while (p!=NULL)
{
if(p->data>=data)
{
break;
}
q=p;
p=p->next;
}
r->next=p;
q->next=r;
}
void print(Line *head)
{
Line *p;
p=head->next;
int n=0;
while (p!=NULL)
{
printf("%4d",p->data);
p=p->next;
n++;
if (n%10==0)
{
printf( "\n");
}
}
}
void main()
{
Line *head;
head=(Line*)malloc(sizeof(Line));
head->next=NULL;
while (true)
{
system("pause");
system("cls");
int c;
printf("1.insert\n");
printf("2.print\n");
printf("make a choise:");
scanf("%d",&c);
switch(c)
{
case 1:search(head);break;
case 2:print(head);break;
default:exit(1);break;
}
}
}
我有点疑问 第二句话
(2) 若找到将其与后继元素位置交换
他不就把顺序打乱了吗 呵呵 你这个题的逻辑有问题 不过我还是帮你实现了
② 顺序存储表示法为什么不是树的存储形式
顺序存储表示法是树的存储形式的原因:顺序存储方式不仅能用于存储线性结构,还可以用来存放非线性结构,例如完全二叉树是属于非线性结构,但其最佳存储方式是顺序存储方式。
对于一般的家谱树(一般的多叉树)来说,我们可以很清楚的看出层次关系,树的层数表示代数(一共多少代人),树的最后一层表示最后一代人,由于多叉链表法表示的不方便,因此被迫无奈采用孩子兄弟表示法(二叉链表法)。
结构
二叉树的顺序存储就是用一组连续的存储单元存放二又树中的结点元素,一般按照二叉树结点自上向下、自左向右的顺序存储。使用此存储方式,结点的前驱和后继不一定是它们在逻辑上的邻接关系,非常适用于满二又树和完全二又树。根据完全二叉树和满二叉树的特性,假设将图1中的完全二又树存放在一维数组bree中,将发现结点的编号正好与数组元素的下标对应。
③ 顺序存储是二叉树常用的存储结构吗
二叉树的存储结构
二叉树是非线性结构,即每个数据结点至多只有一个前驱,但可以有多个后继。它可采用顺序存储结构和链式存储结构。
1.顺序存储结构
二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结点。因此,必须把二叉树的所有结点安排成为一个恰当的序列,结点在这个序列中的相互位置能反映出结点之间的逻辑关系,用编号的方法从树根起,自上层至下层,每层自左至右地给所有结点编号,缺点是有可能对存储空间造成极大的浪费,在最坏的情况下,一个深度为k且只有k个结点的右单支树需要2k-1个结点存储空间。依据二叉树的性质,完全二叉树和满二叉树采用顺序存储比较合适,树中结点的序号可以唯一地反映出结点之间的逻辑关系,这样既能够最大可能地节省存储空间,又可以利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系。图5-5(a)是一棵完全二叉树,图5-5(b)给出的图5-5(a)所示的完全二叉树的顺序存储结构。
(a) 一棵完全二叉树 (b) 顺序存储结构
图5-5 完全二叉树的顺序存储示意图
对于一般的二叉树,如果仍按从上至下和从左到右的顺序将树中的结点顺序存储在一维数组中,则数组元素下标之间的关系不能够反映二叉树中结点之间的逻辑关系,只有增添一些并不存在的空结点,使之成为一棵完全二叉树的形式,然后再用一维数组顺序存储。如图5-6给出了一棵一般二叉树改造后的完全二叉树形态和其顺序存储状态示意图。显然,这种存储对于需增加许多空结点才能将一棵二叉树改造成为一棵完全二叉树的存储时,会造成空间的大量浪费,不宜用顺序存储结构。最坏的情况是右单支树,如图5-7 所示,一棵深度为k的右单支树,只有k个结点,却需分配2k-1个存储单元。
(a) 一棵二叉树 (b) 改造后的完全二叉树
(c) 改造后完全二叉树顺序存储状态
图5-6 一般二叉树及其顺序存储示意图
(a) 一棵右单支二叉树 (b) 改造后的右单支树对应的完全二叉树
(c) 单支树改造后完全二叉树的顺序存储状态
图5-7 右单支二叉树及其顺序存储示意图
结构5-1二叉树的顺序存储
#define Maxsize 100 //假设一维数组最多存放100个元素
typedef char Datatype; //假设二叉树元素的数据类型为字符
typedef struct
{ Datatype bt[Maxsize];
int btnum;
}Btseq;
2.链式存储结构
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。
通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。其结点结构为:
其中,data域存放某结点的数据信息;lchild与rchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示)。利用这样的结点结构表示的二叉树的链式存储结构被称为二叉链表,如图5-8所示。
(a) 一棵二叉树 (b) 二叉链表存储结构
图5-8 二叉树的二叉链表表示示意图
为了方便访问某结点的双亲,还可以给链表结点增加一个双亲字段parent,用来指向其双亲结点。每个结点由四个域组成,其结点结构为:
这种存储结构既便于查找孩子结点,又便于查找双亲结点;但是,相对于二叉链表存储结构而言,它增加了空间开销。利用这样的结点结构表示的二叉树的链式存储结构被称为三叉链表。
图5-9给出了图5-8 (a)所示的一棵二叉树的三叉链表表示。
图5-9二叉树的三叉链表表示示意图
尽管在二叉链表中无法由结点直接找到其双亲,但由于二叉链表结构灵活,操作方便,对于一般情况的二叉树,甚至比顺序存储结构还节省空间。因此,二叉链表是最常用的二叉树存储方式。
结构5-2二叉树的链式存储
#define datatype char //定义二叉树元素的数据类型为字符
typedef struct node //定义结点由数据域,左右指针组成
{ Datatype data;
struct node *lchild,*rchild;
}Bitree;
<p></p>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct
node
{
int
data;
node
*next;
};
node
*create(int
a[],int
len)
{
int
i;
node
*head=new
node;
head->data=a[0];
node
*p=head;
node
*q;
for(i=1;i<len;i++)
{
q=new
node;
q->data=a[i];
p->next=q;
p=q;
}
p->next=NULL;
return
head;
}
node
*
insert(node
*head,int
k)
{
node
*temp=new
node;
temp->data=k;
temp->next=head;
head=temp;
return
head;
}
node
*dele(node
*head,int
m)
{
int
i;
node
*p=head;
node
*x=new
node;
node
*y=new
node;
if(m==1)
{
node
*q=head;
head=head->next;
free(q);
}
else
{
for(i=1;i<m;i++)
{
x=p;
p=p->next;
y=p->next;
}
x->next=y;
free(p);
}
return
head;
}
void
main()
{
int
a[10]={1,2,3,4,5,6,7,8,9,10};
int
len=10;
node
*head=new
node;
head=create(a,len);
node
*p=head;
printf("原数组为:");
while(p!=NULL)
{
printf("%d
",p->data);
p=p->next;
}
printf("\n输入要插入的元素:");
int
k;
scanf("%d",&k);
head=insert(head,k);
p=head;
printf("增加元素后的数组为:");
while(p!=NULL)
{
printf("%d
",p->data);
p=p->next;
}
printf("\n要删除的元素位置为:");
int
m;
scanf("%d",&m);
head=dele(head,m);
p=head;
printf("删除元素后的数组为:");
while(p!=NULL)
{
printf("%d
",p->data);
p=p->next;
}
}<p>此处为链表实现的方式,链表的好处在于内存不必连续,并且顺序存储
</p>
<p>顺序存储结构的特点是:连续的内存,随机存储。</p>
⑤ 顺序存储方式的优点是存储密度大,且插入,删除运算效率高对吗
顺序存储方式的有点是密度大,而插入,删除运算效率高是链表的优点。
⑥ 栈的顺序存储和链表存储的差异
顺序存储: 线性表的顺序表:指的是用一组地址连续的存储单元,依次存储线性表的数据元素。
线性表的顺序存储结构具备如下两个基本特征: 1、线性表中的所有元素所占的存储空间是连续的(即要求内存中可用存储单元的地址必须是连续的)。 2、线性表中各数据元素在存储空间中是按逻辑顺序依次存放的。 即:线性表逻辑上相邻、物理也相邻(逻辑与物理统一:相邻数据元素的存放地址也相邻),则已知第一个元素首地址和每个元素所占字节数,则可求出任一个元素首地址。 优点: 1、
无须为表示结点间的逻辑关系而增加额外的存储空间。
2、
可以方便的随机存取表中的任一结点。
3、
存储密度大(=1),存储空间利用率高。 缺点: 1、
插入和删除运算不方便,需移动大量元素。 2、
由于要求占用连续的存储空间,存储分配只能按最大存储空间预先进行,致使存储空间不能得到充分利用。
3、
表的容量难以扩充。 链表存储: 线性表的链式存储:指用一组任意的存储单元存储线性表中的数据元素。
线性表的链式存储结构具备的基本特征: 链式存储时,相邻数据元素可随意存放,但所占存储空间分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针。 优点: 1、
插入、删除操作很方便,可通过修改结点的指针实现,无须移动元素。
2、
方便扩充存储空间。
缺点: 1、
不能随机存取元素。
2、
存储密度小(<1),存储空间利用率低。 总结: 1、
顺序表适宜于做查找这样的静态操作;
链表宜于做插入、删除这样的动态操作。 2、若线性表的长度变化不大,且其主要操作是查找,则采用顺序表; 若线性表的长度变化较大,且其主要操作是插入、删除操作,则采用链表。
⑦ 存储器可分为哪三类
存储器不仅可以分为三类。因为按照不同的划分方法,存储器可分为不同种类。常见的分类方法如下。
一、按存储介质划分
1. 半导体存储器:用半导体器件组成的存储器。
2. 磁表面存储器:用磁性材料做成的存储器。
二、按存储方式划分
1. 随机存储器:任何存储单元的内容都能被随机存取,且存取时间和存储单元的物理位置无关。
2. 顺序存储器:只能按某种顺序来存取,存取时间和存储单元的物理位置有关。
三、按读写功能划分
1. 只读存储器(ROM):存储的内容是固定不变的,只能读出而不能写入的半导体存储器。
2. 随机读写存储器(RAM):既能读出又能写入的存储器。
二、选用各种存储器,一般遵循的选择如下:
1、内部存储器与外部存储器
一般而言,内部存储器的性价比最高但灵活性最低,因此用户必须确定对存储的需求将来是否会增长,以及是否有某种途径可以升级到代码空间更大的微控制器。基于成本考虑,用户通常选择能满足应用要求的存储器容量最小的微控制器。
2、引导存储器
在较大的微控制器系统或基于处理器的系统中,用户可以利用引导代码进行初始化。应用本身通常决定了是否需要引导代码,以及是否需要专门的引导存储器。
3、配置存储器
对于现场可编程门阵列(FPGA)或片上系统(SoC),可以使用存储器来存储配置信息。这种存储器必须是非易失性EPROM、EEPROM或闪存。大多数情况下,FPGA采用SPI接口,但一些较老的器件仍采用FPGA串行接口。
4、程序存储器
所有带处理器的系统都采用程序存储器,但是用户必须决定这个存储器是位于处理器内部还是外部。在做出了这个决策之后,用户才能进一步确定存储器的容量和类型。
5、数据存储器
与程序存储器类似,数据存储器可以位于微控制器内部,或者是外部器件,但这两种情况存在一些差别。有时微控制器内部包含SRAM(易失性)和EEPROM(非易失)两种数据存储器,但有时不包含内部EEPROM,在这种情况下,当需要存储大量数据时,用户可以选择外部的串行EEPROM或串行闪存器件。
6、易失性和非易失性存储器
存储器可分成易失性存储器或者非易失性存储器,前者在断电后将丢失数据,而后者在断电后仍可保持数据。用户有时将易失性存储器与后备电池一起使用,使其表现犹如非易失性器件,但这可能比简单地使用非易失性存储器更加昂贵。
7、串行存储器和并行存储器
对于较大的应用系统,微控制器通常没有足够大的内部存储器。这时必须使用外部存储器,因为外部寻址总线通常是并行的,外部的程序存储器和数据存储器也将是并行的。
8、EEPROM与闪存
存储器技术的成熟使得RAM和ROM之间的界限变得很模糊,如今有一些类型的存储器(比如EEPROM和闪存)组合了两者的特性。这些器件像RAM一样进行读写,并像ROM一样在断电时保持数据,它们都可电擦除且可编程,但各自有它们优缺点。
参考资料来源:网络——存储器
⑧ 简述栈和队列的顺序存储结构和链式存储结构的优缺点
顺序栈--入栈操作受数组上界的约束有可能发生栈上溢,且需要地址连续的存储单元。
链栈--无须地址连续,便于多个栈共享存储单元,且不存在栈满上溢情况。
顺序队列--需地址连续且有假上溢现象(需改为循环队列才可解决假上溢)
链式队列--特别适合于数据元素变动比较大的情况,且不存在队列满而产生的溢出问题。
⑨ 顺序存储方式串的基本操作是什么
1.串联结concat串联结concat函数是用T返回由S1和S2联结而成的新串。由于串长固定,因此超过串长的串值必须舍去,称为“截断”。假设S1、S2和T都是SString型的串变量,且串T是由串S1联结得到的,即串T的值的前一段和串S1的值相等,串T的值的后一段和串S2的值相等,则只要进行相应的“串值复制”操作即可,只是需要约定,对超长部分实施“截断”操作。基于串S1和S2长度的不同情况,串T值的产生可能有2种情况:①S1[0]+S2[0]≤MAXSTRLEN时,得到串T的正确结果;②S1[0]<MAXSTRLEN,而S1[0]+S2[0]>MAXSTRLEN时,则将串S2的一部分截断,得到的串T只包含S2的一个子串;③S1[0]=MAXSTRLEN时,则得到的串T并非联结结果,而和串S1相等。在这里仅考虑能正确联结的情况,即S1[0]+S2[0]<MAXSTRLEN,
⑩ 什么是顺序存储器
按存储方式分
随机存储器:任何存储单元的内容都能被随机存取,且存取时间和存储单元的物理位置无关。
顺序存储器:只能按某种顺序来存取,存取时间和存储单元的物理位置有关。