一、单项选择题
1.顺序表是线性表的( B )
A.链式存储结构B.顺序存储结构C.索引存储结构D.散列存储结构
2.对于顺序表,以下说法错误的是(A )
A.顺序表是用一维数组实现的线性表,数组的下标可以看成是元素的绝对地址
B.顺序表的所有存储结点按相应数据元素间的逻辑关系决定的次序依次排列
C.顺序表的特点是:逻辑结构中相邻的结点在存储结构中仍相邻
D.顺序表的特点是:逻辑上相邻的元素,存储在物理位置也相邻的单元中
3.线性表是具有n个(C)的有限序列(n>0)。
A.表元素B.字符C.数据元素D.数据项E.信息项
4.以下说法错误的是(A )
A.对于线性表来说,定位运算LocateElem在顺序表和单链表上的时间复杂度均为O(n)
B.读表元运算在顺序表上只需常数时间O(1)便可实现,因此顺序表是一种随机存取结构C.在链表上实现读表元运算的平均时间复杂度为O(1)
D.插入、删除操作在链表上的实现可在O(1)时间内完成
E.插入、删除操作在顺序表上的实现,平均时间复杂度为O(n)
5.若某线性表中最常用的操作是取第i个元素和找第i个元素的前趋元素,则采用( A )存储方式最节省时间。
A.顺序表B.单链表C.双链表D.单循环链表
6. 静态链表中指针表示的是( C ).
A.内存地址B.数组下标C.下一元素地址D.左、右孩子地址
7.链表不具有的特点是( B )
A.插入、删除不需要移动元素B.可随机访问任一元素
C.不必事先估计存储空间D.所需空间与线性长度成正比
8.在循环链表中,将头指针改设为尾指针(rear)后,其头结点和尾结点的存储位置分别是(D )A.rear和rear->next->next
B.rear->next 和rear
C.rear->next->next和rear
D.rear和rear->next
9.在单链表指针为p的结点之后插入指针为s的结点,正确的操作是:(B)。
A.p->next=s;s->next=p->next; B.s->next=p->next;p->next=s;
C.p->next=s;p->next=s->next; D.p->next=s->next;p->next=s;
10.对于一个头指针为head的带头结点的单链表,判定该表为空表的条件是(B)A.head==NULL B.head→next==NULL
C.head→next==head D.head!=NULL
二、填空题
1.以下为顺序表的定位运算,分析算法,请在________处填上正确的语句。
int locate_sqlist(sqlist L,datatype X)
/*在顺序表L中查找第一值等于X的结点。若找到回传该结点序号;否则回传0*/
{__int I;______;
while((i≤https://www.doczj.com/doc/0915698828.html,st)&&(L.data[i-1]!=X))i++;
if(___L.data[i-1]==X_____)return(i);
else return(0);
}
三、算法设计题
1.以顺序表和单链表作存储结构,各写一个实现线性表的就地(即使用尽可能少的附加空间)逆置的算法,在原表的存储空间内将线性表(a1,a2,.. .,a n)逆置为(a n,.. .,a2,a1)。
#include
#define N 10
void convert(char b[N])
{
char m;
int i;
for(i=0;i<=4;i++)
{
m=b[i];
b[i]=b[N-1-i];
b[N-1-i]=m;
}
}
//void conver2 (struct linklist &la)
//{
// struct linklist *p,*q;
// p=la->next;
// for(p;p->next->next!=0;p++)
// {
// p->next->next=q
// }
//}
void main()
{
char a[N];
int i;
printf("请输入%d个数\n",N);
for(i=0;i<=N-1;i++)
scanf("%d",&a[i]);
convert(a);
printf("改变后的顺序为\n");
for(i=0;i<=N-1;i++)
printf("%d ",a[i]);
}
#include
#include
#define N 10
typedef struct LNode
{
int data;
struct LNode *next;
}Link;
Link *creat(int n)
{
Link *head,*p,*s;
int i;
if(n<1) return NULL;
p=head=(Link *)malloc(sizeof(Link));
for(i=1;i<=n;i++)
{
s=(Link *)malloc(sizeof(Link));
scanf("%d",&s->data);
p->next=s;
p=s;
}
p->next=NULL;
return head;
}
struct LNode *convert (struct LNode *r) {
int i;
struct LNode *q,*p;
q=p=r->next;
while(p->next->next!=NULL)
p=p->next;
r->next=p->next;
for(i=1;i<=N-1;i++)
{
while(q->next->next!=NULL)
q=q->next;
q->next->next=q;
q->next=NULL;
}
p=r->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
}
void main()
{
int i;
Link *head,*p;
printf("请输入%d个数\n",N);
head=creat(N);
printf("改变后的值为\n");
convert(head);
}
检查出错程序:
#include
#include
#define MAX_VERTEX_NUM 6
struct ArcNode
{
int adjvex;
struct ArcNode *nextarc;
}ArcNode;
struct VNode
{
int in;
int data;
ArcNode *firstarc;
}VNode,AdjiList[MAX_VERTEX_NUM];
struct S
{
struct S *next;
int data;
}S;
ArcNode *Put(int i)
{
int m,n;
ArcNode *firstarc,*P,*s;
firstarc=p=(ArcNode *)malloc(sizeof(ArcNode));
for(m=0;;m++)
{
printf("请输入%d下一个元素所对应的下标,输入-1结束\n",i);
scanf("%d",&n);
if(n==-1)break;
s=(S *)malloc(sizeof(S));
p->adjvex=n;
p->nextarc=s;
p=s;
}
return(firstarc);
}
void Input()
{
int n,i,j;
for(n=0;n scanf("%d %d",&i,&j); AdjList[n]->data=i; AdjList[n]->in=j; AdjList[n]->firstarc=Put(i) } printf("输入完成!"); } void main() { int i,j; printf("请输入图的元素和度值!\n"); } 第二章线性表作业 一、选择题 1.下述哪一条是顺序存储结构的优点?() A.存储密度大B.插入运算方便 C.删除运算方便D.可方便地用于各种逻辑结构的存储表示 2.下面关于线性表的叙述中,错误的是哪一个?() A.线性表采用顺序存储,必须占用一片连续的存储单元。 B.线性表采用顺序存储,便于进行插入和删除操作。 C.线性表采用链接存储,不必占用一片连续的存储单元。 D.线性表采用链接存储,便于插入和删除操作。 3.线性表是具有n个()的有限序列(n>0)。 A.表元素B.字符C.数据元素D.数据项 4.若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用()存储方式最节省时间。 A.顺序表B.双链表C.带头结点的双循环链表D.单循环链表 5.某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用()存储方式最节省运算时间。 A.单链表B.仅有头指针的单循环链表C.双链表D.仅有尾指针的单循环链表 6.设一个链表最常用的操作是在末尾插入结点和删除尾结点,则选用( )最节省时间。 A. 单链表 B.单循环链表 C. 带尾指针的单循环链表 D.带头结点的双循环链表 7.若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点。则采用()存储方式最节省运算时间。 A.单链表B.双链表C.单循环链表D.带头结点的双循环链表 8. 静态链表中指针表示的是(). A.内存地址B.数组下标C.下一元素地址D.左、右孩子地址 9. 链表不具有的特点是() A.插入、删除不需要移动元素B.可随机访问任一元素 C.不必事先估计存储空间D.所需空间与线性长度成正比 10. 下面的叙述不正确的是() 第2章线性表 一选择题 1.下述哪一条是顺序存储结构的优点?( A ) A.存储密度大 B.插入运算方便 C.删除运算方 便 D.可方便地用于各种逻辑结构的存储表示 2.下面关于线性表的叙述中,错误的是哪一个?( B )A.线性表采用顺序存储,必须占用一片连续的存储单元。B.线性表采用顺序存储,便于进行插入和删除操作。 C.线性表采用链接存储,不必占用一片连续的存储单元。D.线性表采用链接存储,便于插入和删除操作。 3.线性表是具有n个( C )的有限序列(n>0)。 A.表元素 B.字符 C.数据元 素 D.数据项 E.信息项 4.若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用( A )存储方式最节省时间。 AHA12GAGGAGAGGAFFFFAFAF A.顺序表 B.双链表 C.带头结点的双循环链表 D.单循环链表 5.某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用( D )存储方式最节省运算时间。 A.单链表 B.仅有头指针的单循环链 表 C.双链表D.仅有尾指针的单循环链表 6.设一个链表最常用的操作是在末尾插入结点和删除尾结点,则选用( D )最节省时间。 A. 单链表 B.单循环链表 C. 带尾指针的单循环链表 D.带头结点的双循环链表 7.若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点。则采用( D )存储方式最节省运算时间。 AHA12GAGGAGAGGAFFFFAFAF A.单链表 B.双链表 C.单循环链 表 D.带头结点的双循环链表 8. 静态链表中指针表示的是( BC ). A.内存地址 B.数组下标 C.下一元素地址D.左、右孩子地址 9. 链表不具有的特点是( C ) A.插入、删除不需要移动元素 B.可随机访问任一元素C.不必事先估计存储空间 D.所需空间与线性长度成正比 10. 下面的叙述不正确的是( BC ) A.线性表在链式存储时,查找第i个元素的时间同i的值成正比 AHA12GAGGAGAGGAFFFFAFAF 昆明理工大学信息工程与自动化学院学生实验报告 (201 —201 学年第一学期) 课程名称:数据结构开课实验室:年月日年级、专业、班学号姓名成绩 实验项目名称线性表链式存储运算的算法实现指导教师 教 师 评语教师签名: 年月日 一.实验内容: 线性表链式存储运算的算法实现,实现链表的建立、链表的数据插入、链表的数据删除、链表的数据输出。 二.实验目的: 1.掌握线性表链式存储结构的C语言描述及运算算法的实现; 2.分析算法的空间复杂度和插入和删除的时间复杂度; 3.总结比较线性表顺序存储存储与链式存储的各自特点。 三.主要程序代码分析: LinkList creatListR1() //用尾插入法建立带头结点的单链表 { char *ch=new char(); LinkList head=(LinkList)malloc(sizeof(ListNode)); //生成头结点*head ListNode *s,*r,*pp; r=head; //尾指针初值指向头结点 r->next=NULL; scanf("%s",ch); //读入第一个结点的值 while(strcmp(ch,"#")!=0) { //输入#结束 pp=LocateNode(head,ch); if(pp==NULL) { s=(ListNode *)malloc(sizeof(ListNode)); //生成新的结点*s strcpy(s->data,ch); r->next=s; //新结点插入表尾 r=s; //尾指针r指向新的表尾 r->next=NULL; } scanf("%s",ch); //读入下一个结点的值 } return head; //返回表头指针 } int Insert(ListNode *head) //链表的插入 { ListNode *in,*p,*q; int wh; in=(ListNode *)malloc(sizeof(ListNode));in->next=NULL; //生成新结点p=(ListNode *)malloc(sizeof(ListNode));p->next=NULL; q=(ListNode *)malloc(sizeof(ListNode));q->next=NULL; scanf("%s",in->data); //输入插入的数据 scanf("%d",&wh); //输入插入数据的位置 for(p=head;wh>0;p=p->next,wh--); q=p->next; p->next=in; in->next=q; } void DeleteList(LinkList head,char *key) //链表的删除 { ListNode *p,*r,*q=head; p=LocateNode(head,key); //按key值查找结点的 if(p==NULL) exit(0); //若没有找到结点,退出 while(q->next!=p) //p为要删除的结点,q为p的前结点q=q->next; r=q->next; q->next=r->next; free(r); //释放结点*r } 四.程序运行结果: 实验1 线性表的基本操作 一、需求分析 目的: 掌握线性表运算与存储概念,并对线性表进行基本操作。 1.初始化线性表; 2.向链表中特定位置插入数据; 3.删除链表中特定的数据; 4.查找链表中的容; 5.销毁单链表释放空间; 二、概要设计 ●基础题 主要函数: 初始化线性表InitList(List* L,int ms) 向顺序表指定位置插入元素InsertList(List* L,int item,int rc)删除指定元素值的顺序表记录DeleteList1(List* L,int item) 删除指定位置的顺序表记录 DeleteList2(List* L,int rc) 查找顺序表中的元素 FindList(List L,int item) 输出顺序表元素OutputList(List L) 实验步骤: 1,初始化顺序表 2,调用插入函数 3,在顺序表中查找指定的元素 4,在顺序表中删除指定的元素 5,在顺序表中删除指定位置的元素 6,遍历并输出顺序表 ●提高题 要求以较高的效率实现删除线性表中元素值在x到y(x和y自定义)之间的所有元素 方法: 按顺序取出元素并与x、y比较,若小于x且大于y,则存进新表中。 编程实现将两个有序的线性表进行合并,要求同样的数据元素只出现一次。 方法: 分别按顺序取出L1,L2的元素并进行比较,若相等则将L1元素放进L中,否则将L 1,L2元素按顺序放进L。 本程序主要包含7个函数 主函数main() 初始化线性表InitList(List* L,int ms) 向顺序表指定位置插入元素InsertList(List* L,int item,int rc)删除指定元素值的顺序表记录DeleteList1(List* L,int item) 删除指定位置的顺序表记录 DeleteList2(List* L,int rc) 查找顺序表中的元素 FindList(List L,int item) 输出顺序表元素OutputList(List L) 提高题的程序 void Combine(List* L1,List* L2,List* L) void DeleteList3(List* L,int x,int y) 二、详细设计 初始化线性表InitList(List* L,int ms) void InitList(List* L,int ms) { L->list=(int*)malloc(LIST_INIT_SIZE*sizeof(int)); L->size=0; L->MAXSIZE=LIST_INIT_SIZE; 第2章线性表 班级学号__________-姓名 一、判断正误 (×)1. 链表的每个结点中都恰好包含一个指针。 链表中的结点可含多个指针域,分别存放多个指针。例如,双向链表中的结点可以含有两个指针域,分别存放指向其直接前趋和直接后继结点的指针。 (×)2. 链表的物理存储结构具有同链表一样的顺序。 链表的存储结构特点是无序,而链表的示意图有序。 (×)3. 链表的删除算法很简单,因为当删除链中某个结点后,计算机会自动地将后续的各个单元向前移动。 链表的结点不会移动,只是指针内容改变。 (×)4. 线性表的每个结点只能是一个简单类型,而链表的每个结点可以是一个复杂类型。 混淆了逻辑结构与物理结构,链表也是线性表!且即使是顺序表,也能存放记录型数据。 (×)5. 顺序表结构适宜于进行顺序存取,而链表适宜于进行随机存取。 正好说反了。顺序表才适合随机存取,链表恰恰适于“顺藤摸瓜” (×)6. 顺序存储方式的优点是存储密度大,且插入、删除运算效率高。 前一半正确,但后一半说法错误,那是链式存储的优点。顺序存储方式插入、删除运算效率较低,在表长为n的顺序表中,插入和删除一个数据元素,平均需移动表长一半个数的数据元素。 (×)7. 线性表在物理存储空间中也一定是连续的。 线性表有两种存储方式,顺序存储和链式存储。后者不要求连续存放。 (×)8. 线性表在顺序存储时,逻辑上相邻的元素未必在存储的物理位置次序上相邻。 线性表有两种存储方式,在顺序存储时,逻辑上相邻的元素在存储的物理位置次序上也相邻。 (×)9. 顺序存储方式只能用于存储线性结构。 顺序存储方式不仅能用于存储线性结构,还可以用来存放非线性结构,例如 完全二叉树是属于非线性结构,但其最佳存储方式是顺序存储方式。(后一节介绍) (×)10. 线性表的逻辑顺序与存储顺序总是一致的。 理由同7。链式存储就无需一致。 二、单项选择题 (C )1.数据在计算机存储器内表示时,物理地址与逻辑地址相同并且是连续的,称之为:(A)存储结构(B)逻辑结构(C)顺序存储结构(D)链式存储结构( B )2. 一个向量第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是(A)110 (B)108 (C)100 (D)120 ( A )3. 在n个结点的顺序表中,算法的时间复杂度是O(1)的操作是: (A)访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n) (B)在第i个结点后插入一个新结点(1≤i≤n) (C)删除第i个结点(1≤i≤n) (D)将n个结点从小到大排序 ( B )4. 向一个有127个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动个元素(A)8 (B)63.5 (C)63 (D)7 ( A )5. 链式存储的存储结构所占存储空间: 第2章线性表习题解答 第2章习题 (2) 第2章习题 2.1若将顺序表中记录其长度的分量listlen改为指向最后一个元素的位置last,在实现各基本运算时需要做那些修改? 【解】 //用线性表最后一个元素的下标last代替listLen实现顺序表 #define MAXLEN 100 typedef int elementType; typedef struct sllLast { elementType data[MAXLEN]; int last; }seqList; //初始化 void initialList(seqList &S) { https://www.doczj.com/doc/0915698828.html,st=-1; } //求表长度 int listLength(seqList S) { return https://www.doczj.com/doc/0915698828.html,st+1; } //按序号取元素 bool getElement(seqList S,int i,elementType &x) { if(i<1 || i>https://www.doczj.com/doc/0915698828.html,st+1) //i为元素编号,有效范围在https://www.doczj.com/doc/0915698828.html,st+1之间 return false; else { x=S.data[i-1]; return true; } } //查找元素x,成功:返回元素编号;失败:返回0 int listLocate(seqList S,elementType x) { int i; for(i=0;i<=https://www.doczj.com/doc/0915698828.html,st;i++) { if(S.data[i]==x) return i+1; //找到,转换为元素编号输出 } return 0; } //插入元素 int listInsert(seqList &S,elementType x, int i) 实验1 线性表及其应用 题目1 顺序表的建立与基本操作 一、实验目的 1. 通过实验,掌握include命令及头文件的使用 2. 通过实验,掌握顺序表的建立与输出 3. 通过实验,掌握顺序表的基本操作 二、实验内容 1. 练习顺序表的建立与输出 2. 练习顺序表的基本操作 三、实验前的准备 1. 理解并掌握顺序表的存储结构、基本操作 2. 复习include命令的使用 3. 预习实习指导书,并准备相关的程序清单 四、实验步骤与方法 (1)建立自己的工作目录 (2)在当前文件夹下建立函数结果状态代码的定义文件Status.h(课本p10(1)预定义常量和类型)和数据结构数据文件SqList.h(内容包括顺序表的描述、顺序表建立、顺序表的查询、插入、删除与输出等功能。) (3)理解并运行下列程序: #include 数据结构 实验1:线性表的基本操作及其应用 班级:RB软工移151 学号:201560140140 姓名:袁若飞 实验一线性表 一、实验目的 1、帮助读者复习C++语言程序设计中的知识。 2、熟悉线性表的逻辑结构。 3、熟悉线性表的基本运算在两种存储结构上的实现,其中以熟悉链表的操作为侧重点。 二、实验内容 本次实验提供4个题目,每个题目都标有难度系数,*越多难度越大,题目一、二是必做题。题目三、题目四选作。 三、实验准备知识 1、请简述线性表的基本特性和线性表的几种基本操作的机制 ①答:线性表的基本特性是:对线性表中某个元素ai来说,称其前面的元素ai-1为ai的直接前驱,称其后前面的元素ai+1为ai的直接后继。显然,线性表中每个元素最多有一个直接前驱和一个直接后继。 ②答:线性表的几种基本操作的机制有六个: (1)初始化线性表initial_List(L)——建立线性表的初始结构,即建空表。这也是各种结构都可能要用的运算。 (2)求表长度List_length(L)——即求表中的元素个数。 (3)按序号取元素get_element(L,i)——取出表中序号为i的元素。(4)按值查询List_locate(L,x)——取出指定值为x的元素,若存在该元素,则返回其地址;否则,返回一个能指示其不存在的地址值或标记。 (5)插入元素List_insert(L,i,x)——在表L的第i个位置上插入值为x的元素。显然,若表中的元素个数为n,则插入序号i应满足1<=i<=n+1。(6)删除元素List_delete(L,i)——删除表L中序号为i的元素,显然,待删除元素的序号应满足1<=i<=n。 2、掌握线性表的逻辑结构。 3、掌握线性表的链式存储结构。 4、熟练掌握线性表的插入、删除等操作。 (A )需经常修改L 中的结点值 (E )需不断对L 进行删除插入 第二部分线性表 、选择题 1 ?关于顺序存储的叙述中,哪一条是不正确的 (B ) A. 存储密度大 B. 逻辑上相邻的结点物理上不必邻接 C. 可以通过计算直接确定第 i 个结点的位置 D. 插入、删除操作不方便 2.长度为n 的单链表连接在长度为 m 的单链表后的算法的时间复杂度为 (C ) A 0( n ) B 0(1) C 0(m ) D 0(m+n ) 3 .在n 个结点的顺序表中,算法的时间复杂度是 0(1)的操作是:(A ) A 访问第i 个结点(1<=i<=n )和求第i 个结点的直接前趋(2<=i<=n ) B 在第i 个结点(1<=i<=n )后插入一个新结点 C 删除第i 个结点(1<=i<=n ) D 将n 个结点从小到大排序 4.一个向量第一个兀素的存储地址是 100 ,每个兀素的长度为 2 ,则第5 个兀素的地址是 (B ) ( A ) 110 ( B ) 108 (C ) 100 ( D ) 120 5 .已知一个顺序存储的线性表, 设每个结点需要占 m 个存储单元,若第一个结点的地址为 da , 则第i 个结点的地址为:(A ) 7 .链表是一种采用( B )存储结构存储的线性表。 (A )顺序 (B )链式 (C )星式 (D )网状 8 .线性表若采用链式存储结构时,要求内存中可用存储单兀的地址: (D ) (A )必须是连续的 (B )部分地址必须是连续的 (C )一定是不连续的 (D )连续或不连续都可以 9 .线性表L 在_ ( B )情况下适用于使用链式结构实现。 A ) da+(i-1)*m B ) da+i*m 6.在具有n 个结点的单链表中,实现( A )遍历链表和求链表的第 i 个结点 C )删除开始结点 C ) da-i*m D ) da+(i+1)*m A )的操作,其算法的时间复杂度为 0(n )。 B )在地址为p 的结点之后插入一个结点 D ) 删除地址为p 的结点的后继结点 实验一线性表的应用 一、实验教学目的 1、熟悉将算法转换成程序代码的过程。 2、了解顺序表的逻辑结构特性,熟练掌握顺序表存储结构的C语言描述方法。 3、熟悉链表数据结构的定义和插入、删除等基本操作,会使用链表的基本操作解决一些实际问题 二、实验教学内容 1、实验题目 (1)用C语言数组实现顺序表,并在顺序表上实现:①在第3个位置插入666; ②将第8个元素删除;③在顺序表中查找值为65的元素。 (2)已知有两个多项式Pn(x)和Qm(x),基于链表设计算法实现Pn(x)+Qm(x)运算,而且不重新开辟存储空间。 ⑶基于链表编程实现多项式乘法运算 2、实验要求: (1)要求用静态分配的一维数组和动态分配的一维数组来完成实验题目。分析静态分配的一维数组和动态分配的一维数组在顺序表基本操作实现上的共同点和区别。 (2)熟悉链表及其运算的实现。 ①自己编写实现函数; ②对所编写的算法进行时间复杂度分析。 ⑶实验⑴、⑵必做,实验⑶选做。 3、实验预备知识 (1)复习C语言相关知识(如:结构体、用typedef自定义类型、函数)。 (2)阅读顺序表与链表的类型定义和相应的插入、删除、查找等基本操作。 4、实验环境 (1)一台运行 Windows 2000/XP 操作系统的计算机。 (2)选用turbo c、visual c++、delphi、c++ builder 或visual basic等任何一种语言。 5、实验说明 (1)顺序存储定义 #define MAXSIZE 100/*表中元素的最大个数*/ typedef int datatype; /*元素类型*/ typedef struct {datatype data[MAXSIZE]; /*静态线性表*/ int last; /*表的实际长度*/ }seqlist; /*顺序表的类型名*/ (2)建立顺序表时可利用随机函数自动产生数据。 (3)注意问题 ①插入、删除时元素的移动原因、方向及先后顺序。 ②不同的函数形参与实参的传递关系。 (4)链表类型定义 typedef int datatype;/*元素类型*/ typedef struct node {datatype data; struct node *next; }lnode,*linklist;/*单链表的类型定义*/ (5)为了算法实现简单,最好采用带头结点的单向链表。 (6)注意问题 ①重点理解链式存储的特点及指针的含义。 ②注意比较顺序存储与链式存储的各自特点。 ③注意比较带头结点、无头结点链表实现插入、删除算法时的区别。 ④单向链表的操作是数据结构的基础,一定要注意对这部分的常见算法的理解。 三、实验内容和实验步骤:(由学生填写) 四、实验用测试数据和相关结果分析:(由学生填写) 五、实验总结:(由学生填写) 六、程序参考模板 第2章线性表 1.下面关于线性表的叙述中,错误的是哪一个?()A.线性表采用顺序存储,必须占用一片连续的存储单元。 B.线性表采用顺序存储,便于进行插入和删除操作。 C.线性表采用链接存储,不必占用一片连续的存储单元。 D.线性表采用链接存储,便于插入和删除操作。 2.线性表是具有n个()的有限序列(n>0)。 A.表元素 B.字符 C.数据元素 D.数据项 E.信息项 3.线性表( a1,a2,…,an)以链接方式存储时,访问第i位置 元素的时间复杂性为() A.O(i) B.O(1) C.O(n) D.O(i-1) 4.若长度为n的线性表采用顺序存储结构,在其第i个位置插 入一个新元素的算法的时间复杂度为()(1<=i<=n+1)。 A. O(0) B. O(1) C. O(n) D. O(n2) 5. 对于顺序存储的线性表,访问结点和增加、删除结点的时间 复杂度为()。 A.O(n) O(n) B. O(n) O(1) C. O(1) O(n) D. O(1) O(1) 6.对于一个头指针为head的带头结点的单链表,判定该表为空 表的条件是() A.head==NULL B.head→next==NULL C.head→next==head D.head!=NULL 7.链表不具有的特点是() A.可随机访问任一元素 B.插入、删除不需要移动元素 C.不必事先估计存储空间 D.所需空间与线性长度成正比 8.在双向链表指针p的结点前插入一个指针q的结点操作是()。 >Llink=q;q->Rlink=p;p->Llink->Rlink=q;q->Llink=q; >Llink=q;p->Llink->Rlink=q;q->Rlink=p;q->Llink=p->Llink ; C. q->Llink=p->Llink;q->Rlink=q;p->Llink=q;p->Llink=q; >Rlink=p;q->Llink=p->Llink;p->Llink->Rlink=q;p->Llink=q ; 9.在单链表指针为p的结点之后插入指针为s的结点,正确的 操作是:()。 A. s->next=p->next;p->next=s; B. p->next=s;s->next=p->next; C.p->next=s;p->next=s->next; D. p->next=s->next;p->next=s; 10.对于一个头指针为head的带头结点的单链表,判定该表为 第二章线性表习题及答案 一、基础知识题 2.1 试描述头指针、头结点、开始结点的区别、并说明头指针和头结点的作用。 答:始结点是指链表中的第一个结点,也就是没有直接前趋的那个结点。 链表的头指针是一指向链表开始结点的指针(没有头结点时),单链表由头指针唯一确定,因此单链表可以用头指针的名字来命名。 头结点是我们人为地在链表的开始结点之前附加的一个结点。有了头结点之后,头指针指向头结点,不论链表否为空,头指针总是非空。而且头指针的设置使得对链表的第一个位置上的操作与在表其他位置上的操作一致(都是在某一结点之后)。 2.2 何时选用顺序表、何时选用链表作为线性表的存储结构为宜? 答:在实际应用中,应根据具体问题的要求和性质来选择顺序表或链表作为线性表的存储结构,通常有以下几方面的考虑: 1.基于空间的考虑。当要求存储的线性表长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表;反之,当线性表长度变化大,难以估计其存储规模时,采用动态链表作为存储结构为好。 2.基于时间的考虑。若线性表的操作主要是进行查找,很少做插入和删除操作时,采用顺序表做存储结构为宜;反之,若需要对线性表进行频繁地插入或删除等的操作时,宜采用链表做存储结构。并且,若链表的插入和删除主要发生在表的首尾两端,则采用尾指针表示的单循环链表为宜。 2.3 在顺序表中插入和删除一个结点需平均移动多少个结点?具体的移动次数取决于哪两个因素? 答:在等概率情况下,顺序表中插入一个结点需平均移动n/2个结点。删除一个结点需平均移动(n-1)/2个结点。具体的移动次数取决于顺序表的长度n以及需插入或删除的位置i。i 越接近n则所需移动的结点数越少。 2.4 为什么在单循环链表中设置尾指针比设置头指针更好? 答:尾指针是指向终端结点的指针,用它来表示单循环链表可以使得查找链表的开始结点和终端结点都很方便,设一带头结点的单循环链表,其尾指针为rear,则开始结点和终端结点的位置分别是rear->next->next 和rear, 查找时间都是O(1)。 若用头指针来表示该链表,则查找终端结点的时间为O(n)。 2.5 在单链表、双链表和单循环链表中,若仅知道指针p指向某结点,不知道头指针,能否将结点*p从相应的链表中删去?若可以,其时间复杂度各为多少? 答:我们分别讨论三种链表的情况。 1. 单链表。当我们知道指针p指向某结点时,能够根据该指针找到其直接后继,但是由于不知道其头指针,所以无法访问到p指针指向的结点的直接前趋。因此无法删去该结点。 2. 双链表。由于这样的链表提供双向链接,因此根据已知结点可以查找到其直接前趋和直接后继,从而可以删除该结点。其时间复杂度为O(1)。 3. 单循环链表。根据已知结点位置,我们可以直接得到其后相邻的结点位置(直接后继),又因为是循环链表,所以我们可以通过查找,得到p结点的直接前趋。因此可以删去p所指结点。其时间复杂度应为O(n)。 2.6 下述算法的功能是什么? LinkList Demo(LinkList L){ // L 是无头结点单链表 ListNode *Q,*P; if(L&&L->next){ Q=L;L=L->next;P=L; 数据结构实验报告 实验名称:实验1——线性表 学生姓名: 班级: 班内序号: 学号: 日期: 1.实验要求 1、实验目的:熟悉C++语言的基本编程方法,掌握集成编译环境的调试方法 学习指针、模板类、异常处理的使用 掌握线性表的操作的实现方法 学习使用线性表解决实际问题的能力 2、实验内容: 题目1: 线性表的基本功能: 1、构造:使用头插法、尾插法两种方法 2、插入:要求建立的链表按照关键字从小到大有序 3、删除 4、查找 5、获取链表长度 6、销毁 7、其他:可自行定义 编写测试main()函数测试线性表的正确性。 2. 程序分析 2.1 存储结构 带头结点的单链表 2.2 关键算法分析 1.头插法 a、伪代码实现:在堆中建立新结点 将x写入到新结点的数据域 修改新结点的指针域 修改头结点的指针域,将新结点加入链表中b、代码实现: Linklist::Linklist(int a[],int n)//头插法 {front=new Node; front->next=NULL; for(int i=n-1;i>=0;i--) {Node*s=new Node; s->data=a[i]; s->next=front->next; front->next=s; } } 2、尾插法 a、伪代码实现:a.在堆中建立新结点 b.将a[i]写入到新结点的数据域 c.将新结点加入到链表中 d.修改修改尾指针 b、代码实现: Linklist::Linklist(int a[],int n,int m)//尾插法 {front=new Node; Node*r=front; for(int i=0;i 实验一线性表的基本操作 一、实验目的 1. 熟悉C/C++语言上机环境; 2. 掌握线性表的基本操作:查找、插入、删除等运算在顺序存储、链式存储结构上的运算。 二、实验环境 1. 装有Visual C++6.0的计算机。 2. 本次实验共计2学时。 三、实验内容 1. 建立顺序表,基本操作包括:初始化、建立顺序表、输出顺序表、判断是否为空、取表中第i个元素、查找、插入和删除。并在主函数中完成对各种函数的测试。 2. 设有两个非递增有序的线性表A和B,均已顺序表作为存储结构。编写算法实现将A表和B表合并成一个非递增有序排列的线性表(可将线性表B插入线性表A中,或重新创建线性表C)。 3. 建立单链表,基本操作包括:初始化、判断是否为空、取表中第i个元素、查找、插入和删除。并在主函数中完成对各种函数的测试。 四、源程序 #include 第二章线性表 一、填空题 1、数据逻辑结构包括线性结构、树型结构、图型结构这三种类型,树形结构和图形结构合称为非线性结构。 2、在线性结构中,第一个结点没有前驱结点,其余每个结点有且只有个前驱结点,最后一个结点没有后续结点,其余每个结点有且只有一个后续结点。 3、在顺序表中插入或删除一个元素,需要平均移动一半元素,具体移动的元素个数与插入或删除的位置有关。 4、在顺序表中,逻辑上相邻的元素,其物理位置一定相邻。在单链表中,逻辑上相邻的元素,其物理位置不一定相邻。 5、在带头结点的非空单链表中,头结点的存储位置由头指针指示,首元素结点的存储位置由头结点的next域指示,除首元素结点外,其它任一元素结点的存储位置由其直接前趋结点的next域指示。 6、阅读下列算法,并补充所缺内容。 void purge_linkst( ListNode *& la ) { // 从头指针为 la 的有序链表中删除所有值相同的多余元素,并释放被删结点空间ListNode *p,*q; if(la==NULL) return; q=la; p = la->link; while (p) { if (p && ___(1)p->data!=q->data___) {q=p; p = p->link;} else { q->link= ___(2)p->link___; delete(p); p=___(3)q->link___; } }//while }// purge_linkst 二、选择题 1、在数据结构中,从逻辑上可以把数据结构分成 C。 A、动态结构和静态结构 B、紧凑结构和非紧凑结构 C、线性结构和非线性结构 D、内部结构和外部结构 2、线性表的逻辑顺序与存储顺序总是一致的,这种说法 B。 A、正确 B、不正确 3、线性表若采用链式存储结构时,要求内存中可用存储单元的地址D。 A、必须是连续的 B、部分地址必须是连续的 C、一定是不连续的 D、连续或不连续都可以 4、在以下的述叙中,正确的是B。 A、线性表的线性存储结构优于链表存储结构 B、二维数组是其数据元素为线性表的线性表 C、栈的操作是先进先出 D、队列的操作方式是先进后出 三、综合题 1、已知L是无表头结点的单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的答案中选择合适的语句序列。 A、在P结点后插入S结点的语句序列是((4)、(1)); B、在P结点前插入S结点的语句序列是((7)、(11)、(8)、(4)、(1)); C、在表首插入S结点的语句序列是((5)、(12)); 一、选择题 1. D 2. B 3. B 4. B 5. B 6. B 7. D 8. B 9. C 10. B 11. C 12. C 13. B 14. D 15. A 16. B 17. B 18. C 19. A 20. C 21. D 22. A 23. A 24. A 二、填空题 1. 首元素其直接前驱结点的链域的值 2. HL→next =NULL; HL=HL→next 3. 有限、一对一 4. O(1) 随机存取 5. 表中一半表长和该元素在表中的位置 6. 必定不一定 7. O(1) O(n) 8. 前驱结点的地址 O(n) 9. n-i+1 n-i 10. s->left=p p->right 三、判断题 1. × 2. × 3. × 4. × 5. × 6. × 7. √ 8. × 9. × 10. × 11. × 四、简答题 1. 线性表为:(78,50,40,60,34,90) 2. (36, 12, 8, 50, 25, 5, 15) 3. 解答: 尾指针是指向终端结点的指针,用它来表示单循环链表可以使得查找链表的开始结点和终端结点都很方便,设一带头结点的单循环链表,其尾指针为rear,则开始结点和终端结点的位置分别是rear->next->next和rear, 查找时间都是O(1)。 若用头指针来表示该链表,则查找终端结点的时间为O(n)。 五、编程题 1. 解答:由于在单链表中只给出一个头指针,所以只能用遍历的方法来数单链表中的结点个数了。算法如下: int ListLength ( LinkList L ) { int len=0 ; ListNode *p; p=L; //设该表有头结点 while ( p->next ) { p=p->next; len++; } return len; } 2. int searchmin(linklist l) { int min; int *p; p=l; min=p->data; p=p->next; while (p->next< >nil) { if (min>p->data) min=p->data; p=p->next; } return min; } 3. int searchmax(linklist l) { int max; int *p; p=l; max=p->data; p=p->next; while (p->next< >nil) { if (max 姓名学号 ElemType data; //待插入元素 SqList L; //定义SqList类型变量 InitList_Sq(L); //初始化顺序表 printf("※1. 请输入所需建立的线性表的长度:"); scanf_s("%d", &LIST_MAX); printf("※2. 请录入数据:"); for (i = 0; i 第二章线性表习题(答案) 1.描述以下三个概念的区别:头指针,头结点,首元素结点。 首元结点是指链表中存储线性表中第一个数据元素a1的结点。为了操作方便,通常在链表的首元结点之前附设一个结点,称为头结点,该结点的数据域中不存储线性表的数据元素,其作用是为了对链表进行操作时,可以对空表、非空表的情况以及对首元结点进行统一处理。头指针是指向链表中第一个结点(或为头结点或为首元结点)的指针。 若链表中附设头结点,则不管线性表是否为空表,头指针均不为空。否则表示空表的链表的头指针为空。 2.填空: (1)在顺序表中插入或删除一个元素,需要平均移动一半元素,具体移动的元素个数与插入或删除的位置有关。 (2)在顺序表中,逻辑上相邻的元素,其物理位置也相邻。在单链表中,逻辑上相邻的元素,其物理位置不一定相邻。 (3)在带头结点的非空单链表中,头结点的存储位置由头指针指示,首元素结点的存储位置由头结点的next域指示,除首元素结点外,其它任一元素结点的存储位置由其直接前趋的next域指示。 3.已知L是无表头结点的单链表,且P结点既不是首元素结点,也不是尾元素结点。按要求从下列语句中选择合适的语句序列。 a. 在P结点后插入S结点的语句序列是:(4)、(1)。 b. 在P结点前插入S结点的语句序列是:(7)、(11)、(8)、(4)、(1)。 c. 在表首插入S结点的语句序列是:(5)、(12)。 d. 在表尾插入S结点的语句序列是:(11)、(9)、(1)、(6)。 供选择的语句有: (1)P->next=S; (2)P->next= P->next->next; (3)P->next= S->next;(4)S->next= P->next; (5)S->next= L; (6)S->next= NULL;(7)Q= P; (8)while(P->next!=Q) P=P->next; (9)while(P->next!=NULL) P=P->next; (10)P= Q; (11)P= L; (12)L= S; (13)L= P; 4.设线性表存于a[n]中且递增有序。试写一算法,将X插入到线性表的适当位置上,以保 持线性表的有序性。 void insertData(int a[],int data) { int i,location=0; for(i=0;i第二章 考研试题精选
第二章线性表答案
数据结构实验报告 实验一 线性表链式存储运算的算法实现
数据结构_实验1_线性表的基本操作
数据结构第2章作业 线性表(答案)
第2章线性表习题解答
实验1 线性表及其应用
201560140140--袁若飞--实验1:线性表的基本操作及其应用
(完整版)数据结构第二章线性表1答案
实验1__线性表的应用
第2章线性表(课堂作业)
第二章线性表习题及答案
数据结构实验一题目一线性表实验报告
实验一 线性表的基本操作
第二章_线性表(参考答案)
第2章线性表习题参考答案
实验一线性表与应用(I)
第二章课后作业答案