部分习题参考答案(数据结构 李春葆)
数据结构教程李春葆课后答案第5章递归

9. 设有一个不带表头结点的单链表 L,设计两个递归算法,maxnode(L)返回单链表 L
4
数据结构教程学习指导
中最大结点值,minnodel(L)返回单链表 L 中最小结点值。 解:对应的递归算法如下:
ElemType maxnode(LinkNode *L) { ElemType max; if (L->next==NULL) return L->data; max=maxnode(L->next); if (max>L->data) return max; else return L->data; } ElemType minnode(LinkNode *L) { ElemType min; if (L->next==NULL) return L->data; min=minnode(L->next); if (min>L->data) return L->data; else return min; }
b:5 b:4 b:3 b:2 a:1 c:2 c:3 c:4 c:5
2. 已知 A[0..n-1]为整数数组,设计一个递归算法求这 n 个元素的平均值。 解:设avg(A,i)返回A[0..i]共i+1个元素的平均值,则递归模型如下:
avg(A,i)=A[0] avg(A,i)=(avg(A,i-1)*i+A[i])/(i+1) 当i=0 其他情况
第 5 章 递归 return i-1; else return -1; }
5
#include "sqstring.cpp" //顺序串的基本运算算法 findpat(SqString s,SqString t) { int i=0,j=0,k; while (i<s.length && j<t.length) { if (t.data[j]=='*') { k=findpat(SubStr(s,i+2,s.length-i-1),SubStr(t,j+2,t.length-j-1)); j++; if (k>-1) return i-1; else return -1; } else if (s.data[i]==t.data[j]) { i++; j++; } else { i=i-j+1; j=0; } } if (j>=t.length)
部分习题参考答案(数据结构 李春葆)

int lena=1,j=0; while (p->next!=ha)//求出ha的长度lena { lena++;
p=p->next; }
if (i==0) //将hb的所有数据结点插入到ha的头结点和第1个数据结点之间
{ p=hb->prior;
//p指向hb的最后一个结点/
p->next=ha->next;
//将*p链到ha的第1个数据结点前面
ha->next->prior=p;
ha->next=hb->next;
hb->next->prior=ha;
//将ha头结点与hb的第1个数据结点链起
来
}
else if (i<lena)
q->next->prior=q;
p->next=q;q->prior=p;
q=p->prior;
//q重指向*p的前趋节点
}
return true;
}
}
2.5 设ha=(a1,a2,…,an)和hb=(b1,b2, …,bm) 是两个带头结点的循环单链表,编写将 这两个表合并为带头结点的循环单链表hc的算法。
else
//找到的情况
{ p->freq++;
//频度增1
q=p->prior;
//*q为p前驱节点
while (q!=h && q->freq<p->freq)
数据结构(李春葆)习题与解析

李春葆编著:数据结构(C 语言篇)――习题与解析(修订版)语言篇)――习题与解析(修订版)清华大学出版社清华大学出版社一、绪论一、绪论选择题选择题1.数据结构是一门研究非数值计算的程序设计问题数据结构是一门研究非数值计算的程序设计问题 计算机的计算机的 以及它们之间的以及它们之间的 和运算等的学科。
算等的学科。
1 A.数据元素数据元素 B.计算方法计算方法 C.逻辑存储逻辑存储 D.数据映像数据映像2 A.结构结构 B.关系关系 C.运算运算 D.算法算法2.数据结构被形式地定义为数据结构被形式地定义为 (K, R),其中,其中K 是 的有限集,R 是K 上的上的 有限集。
有限集。
1 A.算法算法 B.数据元素数据元素 C.数据操作数据操作 D.逻辑结构逻辑结构2 A.操作操作 B.映像映像 C.存储存储 D.关系关系3.在数据结构中,从逻辑上可以把数据结构分成在数据结构中,从逻辑上可以把数据结构分成 。
A.动态结构和静态结构动态结构和静态结构B.紧凑结构和非紧凑结构紧凑结构和非紧凑结构C.线性结构和非线性结构线性结构和非线性结构D.内部结构和外部结构内部结构和外部结构4.线性结构的顺序存储结构是一种线性结构的顺序存储结构是一种 的存储结构,线性表的链式存储结构是一种线性表的链式存储结构是一种 的存储结构。
储结构。
A.随机存取随机存取B.顺序存取顺序存取C.索引存取索引存取D.散列存取散列存取5.算法分析的目的是算法分析的目的是 ,算法分析的两个主要方面是,算法分析的两个主要方面是 。
1 A.找出数据结构的合理性找出数据结构的合理性 B.研究算法中的输入和输出的关系研究算法中的输入和输出的关系C.分析算法的效率以求改进分析算法的效率以求改进D.分析算法的易懂性和文档性分析算法的易懂性和文档性2 A.空间复杂度和时间复杂度空间复杂度和时间复杂度 B.正确性和简单性正确性和简单性C.可读性和文档性可读性和文档性D.数据复杂性和程序复杂性数据复杂性和程序复杂性6.计算机算法指的是计算机算法指的是 ,它必须具备输入、输出和,它必须具备输入、输出和 等 5个特性。
数据结构简明教程(李春葆版)课后习题答案

数据结构简明教程(第2版)配套练习题参考答案———————数据结构简明教程———————1.练习题1参考答案1.单项选择题(1)D (2)C (3)C (4)A (5)C (6)B (7)C (8)A (9)C (10)B 2.填空题(1)①逻辑结构 ②存储结构 ③运算(不限制顺序)(2)①线性结构 ②非线性结构(不限制顺序)(3)①数据元素 ②关系(4)①没有 ②没有(5)①前驱 ②一 ③后继 ④任意多个(6)任意多个(7)①顺序 ②链式 ③索引 ④哈希(不限制顺序)(8)①时间 ②空间(不限制顺序)(9)问题规模(通常用n 表示)。
(10)辅助或临时空间3.简答题(1)答:运算描述是指逻辑结构施加的操作,而运算实现是指一个完成该运算功能的算法。
它们的相同点是,运算描述和运算实现都能完成对数据的“处理”或某种特定的操作。
不同点是,运算描述只是描述处理功能,不包括处理步骤和方法,而运算实现的核心则是处理步骤。
(2)答:T 1(n )=O(n log 2n ),T 2(n )=O( ),T 3(n )=O(n 2),T 4(n )=O(n log 2n )。
(3)答:j =0,第1次循环:j =1,s =10。
第2次循环:j =2,s =30。
第3次循环:j =3,s =60。
第4次循环:j =4,s =100。
while 条件不再满足。
所以,其中循环语句的执行次数为4。
(4)答:语句s ++的执行次数2)2)(3(3)1()1(12121-+=++-+=+-=∑∑∑-=-==n n n n i n n i n i i nj。
(5)答:其中x ++语句为基本运算语句,∑∑∑=+==-=-==n i n i j ni n n i n n T 1112)1()(1)(=O(n 2)。
(6) 答:由于内循环j 的取值范围,所以i ≤n /2,则,该程序段的时间复杂度为O(n 2)。
∑∑∑-===--==2/122/124/))12((n i nij n i n i n m 3log 2n2.练习题2参考答案1.单项选择题(1)A (2)C (3)A (4)B (5)C(6)D (7)C (8)B (9)A (10)C(11)B (12)A (13)C (14)D (15)D(16)D (17)A (18)C (19)A (20)D2.填空题(1)L.length=0(2)O(1)(3)O(n)(4)n-i(5)①物理存储位置②指针域(6)①前驱 ②O(n)(7)q=p->next; p->next=q->next; free(q);(8)s->next= p->next; p->next=s;(9)O(1)(10)L->next==L3.简答题(1)答:顺序存储结构中,逻辑上相邻元素的存储空间也是相邻的,无需额外空间表示逻辑关系,所以存储密度大,同时具有随机存取特性。
数据结构教程李春葆课后答案第10章内排序

2 else d=d/3; } }
数据结构教程学习指导
(1)指出fun(a,n)算法的功能。 (2)当a[]={5,1,3,6,2,7,4,8}时,问fun(a,8)共执行几趟排序,各趟的排序 结果是什么? 答:(1)fun(a,n)算法的功能是采用增量递减为1/3的希尔排序方法对a数组中元素进 行递增排序。 (2)当a[]={5,1,3,6,2,7,4,8}时,执行fun(a,8)的过程如下: d=2:2 1 3 6 4 7 5 8 d=1:1 2 3 4 5 6 7 8 共有两趟排序。 4. 在实现快速排序的非递归算法时,可根据基准元素,将待排序序列划分为两个子 序列。若下一趟首先对较短的子序列进行排序,试证明在此做法下,快速排序所需要的栈 的深度为 O(log2n)。 答:由快速排序的算法可知,所需递归工作栈的深度取决于所需划分的最大次数。在 排序过程中每次划分都把整个待排序序列根据基准元素划分为左、右两个子序列,然后对 这两个子序列进行类似的处理。 设S(n)为对n个记录进行快速排序时平均所需栈的深度, 则: S(n)=
KeyType QuickSelect(RecType R[],int s,int t,int k) //在 R[s..t]序列中找第 k 小的元素 { int i=s,j=t; RecType tmp; if (s<t) //区间内至少存在 2 个元素的情况 { tmp=R[s]; //用区间的第 1 个记录作为基准 while (i!=j) //从区间两端交替向中间扫描,直至 i=j 为止 { while (j>i && R[j].key>=tmp.key) j--; //从右向左扫描,找第 1 个关键字小于 tmp 的 R[j] R[i]=R[j]; //将 R[j]前移到 R[i]的位置 while (i<j && R[i].key<=tmp.key) i++; //从左向右扫描,找第 1 个关键字大于 tmp 的 R[i] R[j]=R[i]; //将 R[i]后移到 R[j]的位置 } R[i]=tmp; if (k-1==i) return R[i].key; else if (k-1<i) return QuickSelect(R,s,i-1,k); //在左区间中递归查找 else return QuickSelect(R,i+1,t,k); //在右区间中递&& s==k-1) return R[k-1].key; else return -1; }
数据结构教程李春葆课后答案第6章数组和广义表

int length; }
//元素值 //重复元素的个数
如数组 A[]={1,1,1,5,5,5,5,3,3,3,3,4,4,4,4,4,4},共有 17 个元 素,对应的压缩存储 B 为:{1,3},{5,4},{3,4},{4,6}}。从中看出,如果重复元素 越多,采用这种压缩存储方式越节省存储空间。
6. 利用三元组存储任意稀疏数组 A 时,假设其中一个元素和一个整数占用的存储空间 相同,问在什么条件下才能节省存储空间。
答:设稀疏矩阵 A 有 t 个非零元素,加上行数 rows、列数 cols 和非零元素个数 nums (也算一个三元组),那么三元组顺序表的存储空间总数为 3(t+1),若用二维数组存储时占 用存储空间总数为 m×n,只有当 3(t+1)<m×n 即 t<m×n/3-1 时,采用三元组存储才能节省存 储空间。
解:对于稀疏矩阵三元组表 a,从 a.data[0]开始查看,若其行号等于列号,表示是一
个对角线上的元素,则进行累加,最后返回累加值。算法如下:
bool diagonal(TSMatrix a,ElemType &sum)
数据结构教程李春葆课后答案第7章树和二叉树

教材中练习题及参考答案
1. 有一棵树的括号表示为 A(B,C(E,F(G)),D),回答下面的问题: (1)指出树的根结点。 (2)指出棵树的所有叶子结点。 (3)结点 C 的度是多少? (4)这棵树的度为多少? (5)这棵树的高度是多少? (6)结点 C 的孩子结点是哪些? (7)结点 C 的双亲结点是谁? 答:该树对应的树形表示如图 7.2 所示。 (1)这棵树的根结点是 A。 (2)这棵树的叶子结点是 B、E、G、D。 (3)结点 C 的度是 2。 (4)这棵树的度为 3。 (5)这棵树的高度是 4。 (6)结点 C 的孩子结点是 E、F。 (7)结点 C 的双亲结点是 A。
12. 假设二叉树中每个结点值为单个字符,采用二叉链存储结构存储。设计一个算法 计算一棵给定二叉树 b 中的所有单分支结点个数。 解:计算一棵二叉树的所有单分支结点个数的递归模型 f(b)如下:
f(b)=0 若 b=NULL
6 f(b)=f(b->lchild)+f(b->rchild)+1 f(b)=f(b->lchild)+f(b->rchild)
表7.1 二叉树bt的一种存储结构 1 lchild data rchild 0 j 0 2 0 h 0 3 2 f 0 4 3 d 9 5 7 b 4 6 5 a 0 7 8 c 0 8 0 e 0 9 10 g 0 10 1 i 0
答:(1)二叉树bt的树形表示如图7.3所示。
a b c e h j f i d g e h j c f i b d g a
对应的算法如下:
void FindMinNode(BTNode *b,char &min) { if (b->data<min) min=b->data; FindMinNode(b->lchild,min); //在左子树中找最小结点值 FindMinNode(b->rchild,min); //在右子树中找最小结点值 } void MinNode(BTNode *b) //输出最小结点值 { if (b!=NULL) { char min=b->data; FindMinNode(b,min); printf("Min=%c\n",min); } }
数据结构教程李春葆课后答案 树和二叉树

FindMinNode(b,min);
printf("Min=%c\n",min);
}
}
14. 假设二叉树中每个结点值为单个字符,采用二叉链存储结构存储。设计一个算法 将二叉链 b1 复制到二叉链 b2 中。
解:当 b1 为空时,置 b2 为空树。当 b1 不为空时,建立 b2 结点(b2 为根结点),置 b2->data=b1->data;递归调用 Copy(b1->lchild,b2->lchild),由 b1 的左子树建立 b2 的左 子树;递归调用 Copy(b1->rchild,b2->rchild),由 b1 的右子树建立 b2 的右子树。对应的 算法如下:
结点最少的情况是第 6 层为最下层,即 1~5 层构成一棵满二叉树,其结点总数为 25-1=31,再加上第 6 层的结点,总计 31+8=39。这样最少的结点个数为 39。
7. 已知一棵满二叉树的结点个数为 20~40 之间,此二叉树的叶子结点有多少个? 答:一棵高度为 h 的满二叉树的结点个数为 2h-1,有:20≤2h-1≤40。 则 h=5,满二叉树中叶子结点均集中在最底层,所以叶子结点个数=25-1=16 个。
num2=LeftNode(t,2*i+1);
num+=num1+num2;
}
return num;
}
else return 0;
}
else return 0;
}
12. 假设二叉树中每个结点值为单个字符,采用二叉链存储结构存储。设计一个算法 计算一棵给定二叉树 b 中的所有单分支结点个数。
解:计算一棵二叉树的所有单分支结点个数的递归模型 f(b)如下:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int lena=1,j=0; while (p->next!=ha) //求出ha的长度lena { lena++;
p=p->next; }
if (i==0) //将hb的所有数据结点插入到ha的头结点和第1个数据结点之间
{
QNode *head,*tail;
//总链表的首节点指针和尾节点指针
int first=1,i;
for (i=0;i<MAXQNode;i++)
{
if (QH[i]!=NULL && first==1) //遇到第一个非空队列
{
head=QH[i]; //让head指向第一个数据节点
tail=QT[i];
}
free(hb); //释放hb头结点
}
练习题3 习题3.1、3.2、3.3、3.4和3.6。
3.1 有5个元素,其进栈次序为:A、B、C、D、E,在各种可能 的出栈次序中,以元素C、D最先出栈(即C第一个且D第二个 出栈)的次序有哪几个?
答:要使C第一个且D第二个出栈,应是A进栈,B进栈,C进栈, C出栈,D进栈,D出栈,之后可以有以下几种情况: (1)B出栈,A出栈,E进栈,E出栈,输出序列为CDBAE; (2)B出栈,E进栈,E出栈,A出栈,输出序列为CDBEA; (3)E进栈,E出栈,B出栈,A出栈,输出序列为CDEBA。 所以可能的次序有:CDBAE、CDBEA、CDEBA。
else
//找到的情况
{ p->freq++;
//频度增1
q=p->prior;
//*q为p前驱节点
while (q!=h && q->freq<p->freq)
{ p->prior=q->prior;p->prior->next=p;//交换*p和*q的位置
q->next=p->next;
if (q->next!=NULL) //*p不为最后一个节点时
qu->data[qu->rear]=a;
}
}
else if (a<0)
{ if (qu->rear==qu->front)
printf(" 队列空,不能出队\n");
else
{ qu->front=(qu->front+1)%QueueSize; //出队
x=qu->data[qu->front];
q->next->prior=q;
p->next=q;q->prior=p;
q=p->prior;
//q重指向*p的前趋节点
}
return true;
}
}
2.5 设ha=(a1,a2,…,an)和hb=(b1,b2, …,bm) 是两个带头结点的 循环单链表,编写将这两个表合并为带头结点的循环单链表 hc的算法。
L->data[j+1]=L->data[j]; L->data[i]=x; L->length++; }
2.3 设计一个算法,将一个带头结点的数据域依次为a1,a2,…, an(n≥3)的单链表的所有结点逆置,即第一个结点的数据域变 为an,…,最后一个结点的数据域为a1。
void Reverse(LinkList *&L) { LinkList *p=L->next,*q;
qu->rear=qu->front=0;
while (1)
{ printf("输入a值:"); scanf("%d",&a);
if (a>0)
{ if ((qu->rear+1)%QueueSize==qu->front)
printf(" 队列满,不能入队\n");
else
{ qu->rear=(qu->rear+1)%QueueSize; //入队
first=0;
}
if (QH[i]!=NULL && first==0) //遇到其他非空队列
{
tail->next=QH[i];
tail=QT[i];
}
}
printf("\n输出所有元素:");
while (head!=NULL)
{
printf("%d ",head->data);
head=head->next;
//将hb插入到ha中间
{ p=ha->next;
while (j<i)
//在ha中查找第i个结点*p
{ p=p->next;
j++;
}
q=p->next;
//q指向*p结点的后继结点/
p->next=hb->next;
//hb->prior指向hb的最后一个结点
hb->next->prior=p;
{ ElemType data[QueueSize];
int front,rear;
//队首和队尾指针
} SqQueue;
void main()
{ ElemType a,x; SqQueue *qu;
//定义队列
qu=(SqQueue *)malloc(sizeof(SqQueue));
//队列初始化
{ p=hb->prior;
//p指向hb的最后一个结点/
p->next=ha->next;
//将*p链到ha的第1个数据结点前面
ha->next->prior=p;
ha->next=hb->next;
hb->next->prior=ha;
//将ha头结点与hb的第1个数据结点链起来
}
else if (i<lena)
if (QH[x]==NULL)
//对应的队列为空队时
{
QH[x]=s;
QT[x]=s;
}
else
{
QT[x]->next=s; //将*s节点链到QT[x]所指节点之后
QT[x]=s;
//让QT[x]仍指向尾节点
}
}
void Create(QNode *QH[],QNode *QT[]) //根据用户输入创建队列
解:用栈来判断。
3.4 设从键盘输入一整数序列a1,a2,...an,试编程实现:当 ai>0时,ai进队,当ai<0时,将队首元素出队,当ai=0时,表示 输入结束。要求将队列处理成环形队列,入队和出队操作单独 编写算法,并在异常情况时(如队满)打印出错。
typedef struct ququeue
练习题2 习题2.2、2.3、2.4、2.5和2.6。
2.2 设计一个算法,将x插入到一个有序(从小到大排序)的 线性表(顺序存储结构)的适当位置上,并保持线性表的有 序性。
void Insert(SqList *&L,ElemType x) { int i=0,j;
while (i<L->length && L->data[i]<x) i++; for (j=L->length-1;j>=i;j--)
3.2 假设以I和O分别表示进栈和出栈操作,栈的初态和终栈均为 空,进栈和出栈的操作序列可表示为仅由I和O组成的序列。 (1)下面所示的序列中哪些是合法的? A.IOIIOIOO B.IOOIOIIO C.IIIOIOIO D.IIIOOIOO (2)通过对(1)的分析,写出一个算法判定所给的操作序列 是否合法。若合法返回1;否则返回0。(假设被判定的操作序 列已存入一维数组中)。
解:(1)A、D均合法,而B、C不合法。因为在B中,先 进栈一次,立即出栈三次,这会造成栈下溢。在C中共进 栈五次,出栈三次,栈的终态不为空。
(2)本题使用一个链栈来判断操作序列是否合法,其中A为存
放操作序列的字符数组,n为该数组的元素个数(这里的
ElemType类型设定为char)。对应的算法如下:
int judge(char A[],int n)
{ int i;
ElemType x;
LiStack *ls;
InitStack(ls);
for (i=0;i<n;i++)
{ if (A[i]=='I')
//进栈
Push(ls,A[i]);
else if (A[i]=='O')
//出栈
{ if (StackEmpty(s))
bool LocateNode(DLinkList *h,ElemType x)
{ DLinkList *p=h->next,*q;
while (p!=NULL && p->data!=x)
p=p->next;
//找data域值为x的节点*p
if (p==NULL)
//未找到的情况
return false;
L->next=NULL; while (p!=NULL) { q=p->next;
p->next=L->next; L->next=p; p=q; } }