线性表的实现及操作(二)

线性表的实现及操作(二)
线性表的实现及操作(二)

实验一、线性表的实现及操作(一)

一、实验目的

了解和掌握线性表的顺序存储结构;掌握用C语言上机调试线性表的基本方法;掌握线性表的基本操作:插入、删除、查找以及线性表合并等运算在顺序存储结构和链接存储结构上的运算,以及对相应算法的性能分析。

二、实验要求

给定一段程序代码,程序代码所完成的功能为:(1)建立一个线性表;(2)依次输入数据元素1,2,3,4,5,6,7,8,9,10;(3)删除数据元素5;(4)依次显示当前线性表中的数据元素。假设该线性表的数据元素个数在最坏情况下不会超过100个,要求使用顺序表。

程序中有3处错误的地方,有标识,属于逻辑错误,对照书中的代码仔细分析后,要求同学们修改错误的代码,修改后上机调试得到正确的运行结果。

(1)需求分析:

这份实验报告为所有必做题的实验报告。包括实验一顺序表建立、插入、删除等基本操作,实验二单链表的建立、插入、删除等基本操作,实验四二叉树的基本操作:树的建立、前序、中序、后序遍历及实验六图的遍历:深度优先和广度优先。这四份基础性的实验为改错性质,将每个实验题目中的错误改正过来并通过调试,有助于对基础知识的理解与强化记忆。

(2)概要设计:

实验一为对顺序线性表实现插入,删除,查找等基本操作。

需要用到的语句包括void ListInitiate(SeqList *L)

int ListInsert(SeqList *L, int i, DataType x)

int ListDelete(SeqList *L, int i, DataType *x)

int ListGet(SeqList L, int i, DataType *x)等。

实验二是对单链表进行建立,插入,删除等基本操作。

需要的语句为void ListInitiate(SeqList *L)

int ListInsert(SeqList *L, int i, DataType x)

int ListDelete(SeqList *L, int i, DataType *x)

int ListGet(SeqList L, int i, DataType *x)等。

实验四为二叉树,要求建立一个二叉树,并实现前序,中序及后序的遍历。所需语句包括void ListInitiate(SeqList *L)

int ListInsert(SeqList *L, int i, DataType x)

int ListDelete(SeqList *L, int i, DataType *x)

int ListGet(SeqList L, int i, DataType *x)等。

实验六的内容是图的遍历包括邻接矩阵和邻接链表两种方法。

三、程序代码

(更正后的代码)

#include

#define MaxSize 100

typedef int DataType;

typedef struct

{

DataType list[MaxSize];

int size;

} SeqList;

void ListInitiate(SeqList *L) /*初始化顺序表L*/

{

L->size = 0; /*定义初始数据元素个数*/

}

int ListLength(SeqList L) /*返回顺序表L的当前数据元素个数*/ {

return L.size;

}

int ListInsert(SeqList *L, int i, DataType x)

/*在顺序表L的位置i(0 ≤i ≤size)前插入数据元素值x*/

/*插入成功返回1,插入失败返回0*/

{

int j;

if(L->size >= MaxSize)

{

printf("顺序表已满无法插入! \n");

return 0;

}

else if(i < 0 || i > L->size )

{

printf("参数i不合法! \n");

return 0;

}

else

{

for(j = L->size; j > i; j--) L->list[j] = L->list[j]; /*为插入做准备*/

L->list[i] = x; /*插入*/

L->size ++; /*元素个数加1*/

return 1;

}

}

int ListDelete(SeqList *L, int i, DataType *x)

/*删除顺序表L中位置i(0 ≤i ≤size - 1)的数据元素值并存放到参数x 中*/

/*删除成功返回1,删除失败返回0*/

{

int j;

if(L->size <= 0)

{

printf("顺序表已空无数据元素可删! \n");

return 0;

}

else if(i < 0 || i > L->size-1)

{

printf("参数i不合法");

return 0;

}

else

{//此段程序有一处错误

*x = L->list[i]; /*保存删除的元素到参数x中*/

for(j = i +1; j <= L->size-1; j++) L->list[j] = L->list[j-1]; /*依次前移*/

L->size--; /*数据元素个数减1*/

return 1;

}

}

int ListGet(SeqList L, int i, DataType *x)

/*取顺序表L中第i个数据元素的值存于x中,成功则返回1,失败返回0*/

{

if(i < 0 || i > L.size-1)

{

printf("参数i不合法! \n");

return 0;

}

else

{

*x = L.list[i];

return 1;

}

}

void main(void)

{ SeqList myList;

int i , x;

ListInitiate(&myList);

for(i = 0; i < 10; i++)

ListInsert(&myList, i, i+1);

ListDelete(&myList, 4, &x);

for(i = 0; i < ListLength(myList); i++)

{

ListGet( myList, i, &x); //此段程序有一处错误

printf("%d ", x);

}

}

测试结果:

线性表的实现及操作(二)

一、实验目的

了解和掌握线性表的链式存储结构;掌握用C语言上机调试线性表的基本方法;掌握线性表的基本操作:插入、删除、查找以及线性表合并等运算在顺序存储结构和链接存储结构上的运算,以及对相应算法的性能分析。

二、实验要求

给定一段程序代码,程序代码所完成的功能为:(1)建立一个线性表;(2)依次输入数据元素1,2,3,4,5,6,7,8,9,10;(3)删除数据元素5;(4)依次显示当前线性表中的数据元素。假设该线性表的数据元素个数在最坏情况下不会超过100个,要求使用单链表。

程序中有3处错误的地方,有标识,属于逻辑错误,对照书中的代码仔细分析后,要求同学们修改错误的代码,上机调试并得到正确的运行结果。

三、程序代码:

(更正后的结果)

#include /*该文件包含pringtf()等函数*/

#include /*该文件包含exit()等函数*/

#include /*该文件包含malloc()等函数*/

typedef int DataType; /*定义DataType为int*/

typedef struct Node

{

DataType data;

struct Node *next;

} SLNode;

void ListInitiate(SLNode **head) /*初始化*/

{

/*如果有内存空间,申请头结点空间并使头指针head指向头结点*/

if((*head = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);

(*head)->next = NULL; /*置链尾标记NULL */

}

int ListLength(SLNode *head)

{

SLNode *p = head; /*p指向首元结点*/

int size = 0; /*size初始为0*/

while(p->next != NULL) /*循环计数*/

{

p = p->next;

size ++;

}

return size;

}

int ListInsert(SLNode *head, int i, DataType x)

/*在带头结点的单链表head的数据元素ai(0 ≤i ≤size)结点前*/

/*插入一个存放数据元素x的结点*/

{

SLNode *p, *q;

int j;

p = head; /*p指向首元结点*/

j = -1; /*j初始为-1*/

while(p->next != NULL && j < i - 1)

/*最终让指针p指向数据元素ai-1结点*/

{

p = p->next;

j++;

}

if(j != i - 1)

{

printf("插入位置参数错!");

return 0;

}

/*生成新结点由指针q指示*/

if((q = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);

q->data = x;

//此段程序有一处错误

p->next = q->next; /*给指针q->next赋值*/ p->next = q; /*给指针p->next重新赋值*/ return 1;

}

int ListDelete(SLNode *head, int i, DataType *x)

/*删除带头结点的单链表head的数据元素ai(0 ≤i ≤size - 1)结点*/ /*删除结点的数据元素域值由x带回。删除成功时返回1;失败返回0*/

SLNode *p, *s;

int j;

p = head; /*p指向首元结点*/

j = -1; /*j初始为-1*/

while(p->next != NULL && p->next->next!= NULL && j < i - 1)

/*最终让指针p指向数据元素ai-1结点*/

{

p = p->next;

j++;

}

if(j != i - 1)

{

printf("插入位置参数错!");

return 0;

}

//此段程序有一处错误

s = p->next; /*指针s指向数据元素ai结点*/

*x = s->data; /*把指针s所指结点的数据元素域值赋予x*/ p->next = s->next; /*把数据元素ai结点从单链表中删除指*/

free(s); /*释放指针s所指结点的内存空间*/

return 1;

}

int ListGet(SLNode *head, int i, DataType *x)

/*取数据元素ai和删除函数类同,只是不删除数据元素ai结点*/

{

SLNode *p;

int j;

p = head;

j = -1;

while(p->next != NULL && j < i)

{

p = p->next; j++;

}

if(j != i)

{

printf("取元素位置参数错!");

return 0;

}

//此段程序有一处错误

*x = p->data;

return 1;

}

void Destroy(SLNode **head)

{

SLNode *p, *p1;

p = *head;

while(p != NULL)

{

p1 = p;

p = p->next;

free(p1);

}

*head = NULL;

}

void main(void)

{

SLNode *head;

int i , x;

ListInitiate(&head); /*初始化*/

for(i = 0; i < 10; i++)

{

if(ListInsert(head, i, i+1) == 0) /*插入10个数据元素*/

{

printf("错误! \n");

return;

}

}

if(ListDelete(head, 4, &x) == 0) /*删除数据元素5*/

{

printf("错误! \n");

return;

}

for(i = 0; i < ListLength(head); i++)

{

if(ListGet(head, i, &x) == 0) /*取元素*/

{

printf("错误! \n");

return;

}

else printf("%d ", x); /*显示数据元素*/ }

Destroy(&head);

}

测试结果为:

第二章线性表答案

第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

线性表的顺序存储结构定义和基本操作算法实现

#include "" /***********************线性表的顺序存储结构定义*******************/ #define MAX 11 /*线性表可能达到的最大长度值*/ typedef int datatype; typedef struct {datatype data[MAX]; int last;}list; /************************1.线性表的初始化***************************/ void init(list *lp) {lp->last=0;} /************************2.求线性表的长度***************************/ int length(list *lp) { return (lp->last);} /***************3.插入运算,在表第i个位置插入一个值为 x的新元素******/ void insert(list *lp,int i,datatype x) { int j; if(lp->last==MAX-1) printf("Overflow!\n"); /*表已满*/ else if(i<1||i>lp->last+1) printf("Error!\n"); /*插入位置错误*/ else {for(j=lp->last;j>=i;j--) lp->data[j+1]=lp->data[j]; /*数据元素后移*/ lp->data[i]=x; /*插入x */ lp->last++; /*表长度加1*/ } } /***************4.删除运算,在表中删除第i个数据元素***************/ void delete(list *lp,int i) { int j; if(i<1||i>lp->last) /*检查空表及删除位置的合法性*/ printf("The %dth element is not exist!",i); /*不存在第i个元素*/ else {for(j=i+1;j<=lp->last;j++) lp->data[j-1]=lp->data[j]; /*向前移动元素*/ lp->last--; /*表长度减1 */ } } /*****************5.查找运算,在表中查找x数据元素*****************/ int locate(list *lp,datatype x) { int i=lp->last; while(i>0 && lp->data[i]!=x)i--; return i; }

线性表的顺序存储结构定义和基本操作算法实现

/************线性表的顺序存储结构定义和基本操作算法实现************/ #include "stdio.h" /***********************线性表的顺序存储结构定义*******************/ #define MAX 11 /*线性表可能达到的最大长度值*/ typedef int datatype; typedef struct {datatype data[MAX]; int last;}list; /************************1.线性表的初始化***************************/ void init(list *lp) {lp->last=0;} /************************2.求线性表的长度***************************/ int length(list *lp) { return (lp->last);} /***************3.插入运算,在表第i个位置插入一个值为x的新元素******/ void insert(list *lp,int i,datatype x) { int j; if(lp->last==MAX-1) printf("Overflow!\n"); /*表已满*/ else if(i<1||i>lp->last+1) printf("Error!\n"); /*插入位置错误*/ else {for(j=lp->last;j>=i;j--) lp->data[j+1]=lp->data[j]; /*数据元素后移*/ lp->data[i]=x; /*插入x */ lp->last++; /*表长度加1*/ } } /***************4.删除运算,在表中删除第i个数据元素***************/ void delete(list *lp,int i) { int j; if(i<1||i>lp->last) /*检查空表及删除位置的合法性*/ printf("The %dth element is not exist!",i); /*不存在第i个元素*/ else {for(j=i+1;j<=lp->last;j++) lp->data[j-1]=lp->data[j]; /*向前移动元素*/ lp->last--; /*表长度减1 */ } } /*****************5.查找运算,在表中查找x数据元素*****************/ int locate(list *lp,datatype x) { int i=lp->last; while(i>0 && lp->data[i]!=x)i--; return i;

第2章线性表习题解答

第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.360docs.net/doc/ac13262028.html,st=-1; } //求表长度 int listLength(seqList S) { return https://www.360docs.net/doc/ac13262028.html,st+1; } //按序号取元素 bool getElement(seqList S,int i,elementType &x) { if(i<1 || i>https://www.360docs.net/doc/ac13262028.html,st+1) //i为元素编号,有效范围在https://www.360docs.net/doc/ac13262028.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.360docs.net/doc/ac13262028.html,st;i++) { if(S.data[i]==x) return i+1; //找到,转换为元素编号输出 } return 0; } //插入元素 int listInsert(seqList &S,elementType x, int i)

(完整版)数据结构第二章线性表1答案

(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 的结点的后继结点

第2章线性表习题解析(答)

第二章线性表练习题 一、选择题 1.线性表是具有n个的有限序列。 A、表元素 B、字符 C、数据元素 D、数据项 E、信息项 2.线性表的静态链表存储结构与顺序存储结构相比优点是。 A、所有的操作算法实现简单 B、便于随机存储 C、便于插入和删除 D、便于利用零散的存储器空间 3.若长度为n的线性表采用顺序存储结构,在其第i个位置插入一个新元素算法的时间复杂度为。 A、O(log2n) B、O(1) C、O(n) D、O(n2) 4.(1)静态链表既有顺序存储的特点,又有动态链表的优点。所以,它存取表中第i个元素的时间与i无关; (2)静态链表中能容纳元素个数的最大数在定义时就确定了,以后不能增加;(3)静态链表与动态链表在元素的插入、删除上类似,不需做元素的移动。 以上错误的是。 A、(1)、(2) B、(1) C、(1)、(2)、(3) D、(2) 6.在双向链表存储结构中,删除p所指的结点时须修改指针。 A、p->next->prior=p->prior; p->prior->next=p->next; B、p->next=p->next->next;p->next->prior=p; C、p->prior->next=p;p->prior=p->prior->prior; D、p->prior=p->next->next;p->next=p->prior->prior;

7.在双向循环链表中,在P指针所指的结点后插入q所指向的新结点,其修改指针的操作是。 A、p->next=q; q->prior=p;p->next->prior=q;q->next=q; B、p->next=q;p->next->prior=q;q->prior=p;q->next=p->next; C、q->prior=p; q->next=p->next; p->next->prior=q; p->next=q; D、q->next=p->next;q->prior=p;p->next=q;p->next=q; 8.将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是。 A、 n b、2n-1 c、2n d、n-1 9.在一个长度为n的顺序表中,在第i个元素(1≤i≤n+1)之前插入一个新元素时须向后移动个元素。 A、n-i B、n-i+1 C、n-i-1 D、i 10.线性表L=(a1,a2,……an),下列说法正确的是。 A、每个元素有有一个直接前驱和一个直接后继 B、线性表中至少有一个元素 C、表中诸元素的排列必须是由小到大或由大到小。 D、除第一个和最后一个元素外,其余每个元素都有一个且仅有一个直接前驱和直接后继。 11.对单链表表示法,以下说法错误的是。 A、数据域用于存储线性表的一个数据元素 B、指针域(或链域)用于存放一指向本结点所含数据元素的直接后继所在结点的指针 C、所有数据通过指针的链接而组织成单链表 D、NULL称为空指针,它不指向任何结点只起标志作用

线性表的基本操作讲解

实验二线性表的基本操作 一、实验目的 1.掌握用C++/C语言调试程序的基本方法。 2.掌握线性表的顺序存储和链式存储的基本运算,如插入、删除等。 二、实验要求 1.C++/C完成算法设计和程序设计并上机调试通过。 2.撰写实验报告,提供实验结果和数据。 3.分析算法,要求给出具体的算法分析结果,包括时间复杂度和空间复杂度,并简要给出算法设计小结和心得。 三、实验内容: 1. 分析并运行以下各子程序的主要功能。 程序1:顺序存储的线性表和运算 #include #define MAXSIZE 100 int list[MAXSIZE]; int n; /*insert in a seqlist*/ int sq_insert(int list[], int *p_n, int i, int x) {int j; if (i<0 || i>*p_n) return(1); if (*p_n==MAXSIZE) return(2); for (j=*p_n+1; j>i; j--) list[j]=list[j-1]; list[i]=x; (*p_n)++; return(0); } /*delete in a seq list*/ int sq_delete(int list[], int *p_n, int i) {int j; if (i<0 || i>=*p_n) return(1); for (j = i+1; j<=*p_n; j++) list[j-1] = list[j]; (*p_n)--; return(0); } void main() {int i,x,temp; printf("please input the number for n\n"); printf("n="); scanf("%d",&n); for (i=0; i<=n; i++) {printf("list[%d]=",i); scanf("%d",&list[i]);}

第二章线性表习题及答案

第二章线性表习题及答案 一、基础知识题 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;

第2章线性表习题解答

第2章习题 (1) 第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.360docs.net/doc/ac13262028.html,st=-1; } //求表长度 int listLength(seqList S) { return https://www.360docs.net/doc/ac13262028.html,st+1; } //按序号取元素 bool getElement(seqList S,int i,elementType &x) { if(i<1 || i>https://www.360docs.net/doc/ac13262028.html,st+1) //i为元素编号,有效范围在https://www.360docs.net/doc/ac13262028.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.360docs.net/doc/ac13262028.html,st;i++) { if(S.data[i]==x) return i+1; //找到,转换为元素编号输出} return 0; } //插入元素 int listInsert(seqList &S,elementType x, int i) { int k; if(https://www.360docs.net/doc/ac13262028.html,st>MAXLEN-1) return 0; //表满,返回0 else if(i<1 || i>https://www.360docs.net/doc/ac13262028.html,st+2) return 1; //插入位置查处范围,返回1 else { for(k=https://www.360docs.net/doc/ac13262028.html,st;k>=i-1;k--) S.data[k+1]=S.data[k]; S.data[i-1]=x; https://www.360docs.net/doc/ac13262028.html,st++; return 2; } } //删除元素 int listDelete(seqList &S,int i) { int k; if(https://www.360docs.net/doc/ac13262028.html,st==-1) return 0; //空表,返回0 else if(i<1 || i>https://www.360docs.net/doc/ac13262028.html,st+1) return 1; //删除元素编号超出范围,返回1 else

线性表习题2

线性表典型例题 一、单项选择题 [例7-1]在数据结构中,与所使用计算机无关的数据叫( ①)结构;链表是一种采用( ②)存储结构存储的线性表;链表适用于( ③)查找;在链表中进行( ④)操作的效率比在线性表中进行该操作的效率高。 ①A.存储B.物理C.逻辑D.物理和逻辑 ②A.顺序B.网状C.星式D.链式 ③A.顺序B.二分法C.顺序及二分法D.随机 ④A.二分法查找B.快速查找C.顺序查找D.插入 解析:本题考查的是基本概念。本题答案为:①C;②D;③A;④D。 [例7-2] 链表不具备的特点是( )。 A.插入和删除不需要移动元素B.可随机访问任一结点 C.不必预分配空间D.所需空间与其长度成正比 解析:线性表可随机访问任一结点,而链表必须从第一个数据结点出发逐一查找每个结点。本题答案为:B。 [例7-3] 不带头结点的单链表head为空的判定条件是( )。 A.head==NULL B.head_>next==NULL C.head_>next==head D.head!=NULL 解析:在不带头结点的单链表head中,head指向第一个数据结点。空表即该表没有结点,head==NULL表示该单链表为空。本题答案为:A。 [例7-4] 带头结点的单链表head为空的判定条件是( )。 A.head==NULL B.head—>next==NULL C.head—> next==head D.head!=NULL 解析:在带头结点的单链表head中,head指向头结点。空表即该表只有头结点,head —>next==NULL表示该单链表为空。本题答案为:B。 [例7-5] 带头结点的循环单链表head中,head为空的判定条件是( )。 A.head==NULL B.head—>next==NULL C.head—> next==head D.head!=NULL 解析:在带头结点的循环单链表head中,head指向头结点。空表即该表只有头结点,head—>next==head表示该单链表为空。本题答案为:C。 [例7-6] 线性表采用链式存储时其存储地址( )。 A.必须是连续的B.部分地址必须是连续的 C.一定是不连续的D.连续不连续都可以 解析:链式存储采用动态存储,地址一般不连续。本题答案为:D。 [例7-7] 在双向链表的* p结点前插入新结点*s的操作为( )。 A.p—>prior=s;s—>next=p;p—>prior—>next=s;s—>prior=p—>prior; B.p—>prior=s;p—>prior—>next=s;s—>next=p;s—>prior=p—>prior; C.s—>next=p;s—>prior=p—>prior;p—>prior=s;p—>prior—>next=s; D.s—>next=p;s—>prior=p—>prior;p—>prior—>next=s;p—>prior=s; 解析:在双向链表的* p结点前插入新结点* s的操作如图7.12所示,图中虚线为所作的操作,序号为操作顺序。本题答案为:D。

实验一 线性表的基本操作

实验一线性表的基本操作 一、实验目的 1. 熟悉C/C++语言上机环境; 2. 掌握线性表的基本操作:查找、插入、删除等运算在顺序存储、链式存储结构上的运算。 二、实验环境 1. 装有Visual C++6.0的计算机。 2. 本次实验共计2学时。 三、实验内容 1. 建立顺序表,基本操作包括:初始化、建立顺序表、输出顺序表、判断是否为空、取表中第i个元素、查找、插入和删除。并在主函数中完成对各种函数的测试。 2. 设有两个非递增有序的线性表A和B,均已顺序表作为存储结构。编写算法实现将A表和B表合并成一个非递增有序排列的线性表(可将线性表B插入线性表A中,或重新创建线性表C)。 3. 建立单链表,基本操作包括:初始化、判断是否为空、取表中第i个元素、查找、插入和删除。并在主函数中完成对各种函数的测试。 四、源程序 #include #include #include #define MaxSize 50 typedef char ElemType; //-------存储结构---------- typedef struct { ElemType elem[MaxSize]; //存放顺序表中的元素 int length; //存放顺序表的长度 } SqList; //-------初始化线性表---------- void InitList(SqList *&L) //初始化线性表,构造一个空的线性表,并将长度设置为0 { L=(SqList *)malloc(sizeof(SqList)); L->length=0;

第二章_线性表(参考答案)

第二章线性表 一、填空题 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、定义线性表节点的结构,并定义节点的型和位置的型。 2、定义线性表的基本操作 3、在1,2的基础上,完成本题。 4、在main 函数中进行测试:先构建两个有序的线性表,然后合并这两个线性表。 四、已知一个单向链表,试给出复制该链表的算法。 要求:1、定义线性表的节点的结构以及节点的型和位置的型。 2、定义线性表的基本操作 3、在1,2的基础上,完成本题。 4、在main 函数中进行测试:先构建一个线性表,并定义一个空线性表,然后进行复制。 五、写出从一个带表头的单链表中删除其值等于给定值x 的结点的算法函数: int delete(LIST &L, int x);如果x 在该链表中,则删除对应结点,并返回其在链表中的位置(逻辑位置,第一个结点的逻辑位置为1),否则返回-1。 要求:1、定义线性表的节点的结构以及节点的型和位置的型。 2、定义线性表的基本操作 3、在1,2的基础上,完成本题。 4、在main 函数中进行测试:先构建一个线性表,然后调用函数删除值等于给定值的节点。 六、写出一个将两个静态链表(属于同一个存储池)合并的算法函数: void Merge(cursor M, cursor N); 合并的方法是将N 链表中的所有结点添加到M 链表的后面,并将N 链表的表头结点添加到空闲结点链表中。 要求:1、定义静态链表的结点的结构以及结点的型SPACE 以及位置(position )和游标(cursor )的型。 2、定义静态链表的基本操作:void Initialize(); 初始化,将所有存储池中的结点设置为空闲;cursor GetNode(); 从空闲链中获取一个结点;void FreeNode(cursor q); 将结点q 加入到空闲链; void Insert ( elementtype x, position p, cursor M ); 在链表M 中的位置为p 的元素后面添加一个值为x 的结点;void Delete (cursor M, position p ); 在链表M 中删除位置为p 的元素的后一个元素。 3、在1、2的基础上完成本题。 4、在main 函数中进行测试:先构建一个存储池,然后在该存储池中创建两个静态 表,最后将这两个静态表合并。 七、利用指针表示的线性表(链表)表示一个多项式,并实现两个多项式的相加和相乘运算。假设多项式形式为:11 11...)(e e m e m x a x a t a x A m m +++= -- 其中,系数a i ≠0,指数e i 满足e m >e m-1>…>e 2>e 1>=0。 要求:1、定义多项式每一项的结构。 2、定义两个多项式的相加和相乘运算函数。 3、在main 函数中,构建两个多项式,并测试相加和相乘运算。

线性表算法题

已知线性表(a1 a2 a3 …an)按顺序存于内存,每个元素都是整数,试设计用最少时间把所有值为负数的元素移到全部正数值(假设0为正数)元素前边的算法:例:(x,-x,-x,x,x,-x …x)变为(-x,-x,-x…x,x,x)。 .两个整数序列A=a1,a2,a3,…,am和B=b1,b2,b3,…,bn已经存入两个单链表中,设计一个算法,判断序列B是否是序列A的子序列。 设用带头结点的双向循环链表表示的线性表为L=(a1,a2, …a n)。写出算法将L改造成:L=(a1,a3,…a n,…a4,a2)。 已知A、B、C是三个顺序表且其元素按递增顺序排列,每个表中元素均无重复。在表A删去既在表B中出现又在表C中出现的元素。试设计实现上述删除操作的算法Delete。 在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素。例如:(7,10,10,21,30,42,42,42,51,70)将变作(7,10,21,30,42,51,70)。 假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。 试编写在带头结点的单链表中删除(一个)最小值结点的(高效)算法。void delete(Linklist &L) 在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素。例如:(7,10,10,21,30,42,42,42,51,70)将变作(7,10,21,30,42,51,70)。 设有一个正整数序列组成的有序单链表(按递增次序有序,且允许有相等的整数存在),试编写能实现下列功能的算法:(要求用最少的时间和最小的空间) ⑴确定在序列中比正整数x大的数有几个(相同的数只计算一次,如序列 {20,20,17,16,15,15,11,10,8,7,7,5,4}中比10大的数有5个); ⑵在单链表将比正整数x小的数按递减次序排列; ⑶将正整数(比)x大的偶数从单链表中删除。

第2章线性表习题参考答案

一、选择题 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 (maxdata) max=p->data; p=p->next; } return max; } 4. 顺序表:要将该表逆置,可以将表中的开始结点与终端结点互换,第二个结点与倒数第二个结点互换,如此反复,就可将整个表逆置了。 算法如下: // 顺序表结构定义同上题 void ReverseList( Seqlist *L) { DataType temp ; //设置临时空间用于存放data int i; for (i=0;i<=L->length/2;i++)//L->length/2为整除运算 { temp = L->data[i]; //交换数据 L -> data[ i ] = L -> data[ L -> length-1-i]; L -> data[ L -> length - 1 - i ] = temp; }

线性表的基本操作实验报告

实验一:线性表的基本操作 【实验目的】 学习掌握线性表的顺序存储结构、链式存储结构的设计与操作。对顺序表建立、插入、删除的基本操作,对单链表建立、插入、删除的基本操作算法。 【实验内容】 1.顺序表的实践 1) 建立4个元素的顺序表s=sqlist[]={1,2,3,4,5},实现顺序表建立 的基本操作。 2) 在sqlist []={1,2,3,4,5}的元素4和5之间插入一个元素9,实现 顺序表插入的基本操作。 3) 在sqlist []={1,2,3,4,9,5}中删除指定位置(i=5)上的元素9, 实现顺序表的删除的基本操作。 2.单链表的实践 3.1) 建立一个包括头结点和4个结点的(5,4,2,1)的单链表,实现单链 表建立的基本操作。 2) 将该单链表的所有元素显示出来。 3) 在已建好的单链表中的指定位置(i=3)插入一个结点3,实现单链表插 入的基本操作。 4) 在一个包括头结点和5个结点的(5,4,3,2,1)的单链表的指定位置 (如i=2)删除一个结点,实现单链表删除的基本操作。 5) 实现单链表的求表长操作。 【实验步骤】 1.打开VC++。 2.建立工程:点File->New,选Project标签,在列表中选Win32 Console Application,再在右边的框里为工程起好名字,选好路径,点OK->finish。至此工程建立完毕。 3.创建源文件或头文件:点File->New,选File标签,在列表里选C++ Source File。给文件起好名字,选好路径,点OK。至此一个源文件就被添加到了刚创

建的工程之中。 4.写好代码 5.编译->链接->调试 1、#include "stdio.h" #include "malloc.h" #define OK 1 #define OVERFLOW -2 #define ERROR 0 #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 typedef int ElemType; typedef int Status; typedef struct { ElemType *elem; int length; int listsize; } SqList; Status InitList( SqList &L ) { int i,n; L.elem = (ElemType*) malloc (LIST_INIT_SIZE*sizeof (ElemType)); if (!L.elem) return(OVERFLOW); printf("输入元素的个数:"); scanf("%d",&n); printf("输入各元素的值:"); for(i=0;i

线性表 答案

数据结构与算法上机作业第二章线性表

一、选择题 1、若长度为n的线性表采用顺序存储结构,在其第i个位置插入一个新的元素算法的时间复杂度为 C 。 A. O(log2n) B. O(1) C. O(n) D. O(n2) 2、以下关于线性表的说法中,不正确的是 C 。 A. 线性表中的数据元素可以是数字、字符、结构等不同类型 B. 线性表中包含的数据元素个数不是任意的 C. 线性表中的每一个结点都有且只有一个直接前驱和直接后继 D. 存在这样的线性表:表中各结点都没有直接前驱和直接后继 3、在有n个结点的顺序表上做插入、删除结点运算的时间复杂度为 B 。 A. O(1) B. O(n) C. O(n2) D. O(log2n) 4、等概率情况下,在有n个结点的顺序表上做插入结点操作,需平均移动的结点数目为 C 。提示:插入的位置有n+1个,移动总数为:1+2+3+……+n A. n B. (n-1)/2 C. n/2 D. (n+1)/2 5、在一个长度为n的顺序存储的线性表中查找值为x的元素时,平均查找长度(及x同元素的平均比较次数,假定查找每个元素的概率都相等)为 C 。 A. n B. n/2 C. (n+1)/2 D. (n-1)/2 6、在顺序表中,只要知道 D ,就可以求出任一结点的存储地址。 A. 基地址 B. 结点大小 C. 向量大小 D. 基地址和结点大小 7、将两个各有n个元素的有序表归并为一个有序表,其最少的比较次数是 A 。 A. n B. 2n-1 C. 2n D. n-1 8、线性表采用链表存储时其存储地址要求 D 。 A. 必须是连续的 B. 部分地址必须是连续的 C. 必须是不连续的 D. 连续的和不连续的都可以 9、下面关于线性表的描述中,错误的是 B 。 A. 线性表采用顺序存储,必须占用一片连续的存储单元 B. 线性表采用顺序存储,便于进行插入和删除操作 C. 线性表采用链式存储,不必占用一片连续的存储单元 D. 线性表采用链式存储,便于插入和删除操作 10、向具有n个结点的有序单链表中插入一个新结点并仍然有序的时间复杂度是 B A. O(1) B. O(n) C. O(n2) D. O(log2n) 11、在一个带头结点的单链表HL中,若要向表头插入一个由指针p指向的结点,则执行的语句是 D 。 A. HL=p; p->next=HL; B. p->next=HL; HL=p; C. p->next=HL; p=HL; D. p->next=HL->next; HL->next=p; 12、在一个单链表HL中,若要删除由指针q所指向结点的后继结点,则执行的语句是C 。 A. p=q->next; p->next=q->next; B. p=q->next; q->next=p; C. p=q->next; q->next=p->next; D. q->next=q->next->next; q->next=q; 13、设有编号为1, 2, 3, 4的4辆列车,顺序进入一个栈结构的站台,下列不可能的出栈顺序为 D 。 A. 1234 B. 1243 C. 1324 D. 1423

相关文档
最新文档