第二章线性表作业-答案
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2.8已知由单链表表示的线性表中,含有三类字符的数据元素( 2.8已知由单链表表示的线性表中,含有三类字符的数据元素(如:字母字符、数字字符 已知由单链表表示的线性表中,含有三类字符的数据元素 和其它字符) 和其它字符),试编写算法构造三个以循环链表表示的线性表,使每个表中只含同一类 的字符,且利用原表中的结点空间作为这三个表的结点空间,头结点可另辟空间。
2.8 已知由单链表表示的线性表中,含有三类 字符的数据元素( 字符的数据元素(如:字母字符、数字字符和 其它字符) 其它字符),试编写算法构造三个以循环链表 表示的线性表,使每个表中只含同一类的字 符,且利用原表中的结点空间作为这三个表 的结点空间,头结点可另辟空间。 2.9 假设在长度大于1的单循环链表中,既无 假设在长度大于1 头结点也无头指针。s 头结点也无头指针。s为指向链表中某个结 点的指针,试编写算法删除结点* 点的指针,试编写算法删除结点*s的直接前 趋结点。 2.10设顺序表L 2.10设顺序表L是一个递增有序表,试写一算 法,将x插入L中,并使L 法,将x插入L中,并使L仍是一个有序表。
Status locatenode(dullinklist &L,elemtype x) {dulnode *p,*q; p=q=Lp=q=L->next; while(p) (pp=p{if (p->data!=x) p=p->next; else {p->freq++; break;} } {pwhile(q) {if(q->freq>pq=q{if(q->freq>p->freq) q=q->next; {p->prior->next=pp->next->prior=pelse {p->prior->next=p->next; p->next->prior=p->prior; p->prior=qp->next=q; p->prior=q->prior; q->prior->next=p; q->prior=p} >priorq} return ok; }
要解决这样的问题,只要新建三个头结点,然后在原来的单链表中依次查询,找到 一类字符结点时,就摘下此结点链接到相应头结点指明的新链表中就是了。 算法如下: //设已建立三个带头结点的空循环链表A,B,C. //以下是 void DivideList( LinkList L, LinkList A, LinkList B, LinkList C) { ListNode *p=L->next, *q; ListNode *a=A, ListNode *b=B; ListNode *c=C; while ( p ) { if ( p->data>='a' &&p->data<='z'|| p->data>='A' &&p->data<='Z') { q=p; //保存字母结点位置 p=p->next;//指向下一结点 a->next=q;//将字母结点链到A表中 q->next=A;// 形成循环链表 a=a->next; // 指向下一结点 } else if( p->data>='0' && p->data<='9') { // 分出数字结点
第二章 线性表
作业评讲
பைடு நூலகம்
作业: 作业:
2.5、 2.7、2.9、2.11做在作业本上,交,其余堂下练习 、 做在作业本上, 、 、 做在作业本上 2.1 试描述头指针、头结点、开始结点的区别、并说明头指针 和头结点的作用。 2.2 何时选用顺序表、何时选用链表作为线性表的存储结构为 宜? 2.3 在顺序表中插入和删除一个结点需平均移动多少个结点? 在顺序表中插入和删除一个结点需平均移动多少个结点? 具体的移动次数取决于哪两个因素? 具体的移动次数取决于哪两个因素? 2.4 为什么在单循环链表中设置尾指针比设置头指针更好? 为什么在单循环链表中设置尾指针比设置头指针更好? 2.5 在单链表、双链表和单循环链表中,若仅知道指针p指向 在单链表、双链表和单循环链表中,若仅知道指针p 某结点,不知道头指针,能否将结点* 从相应的链表中删去? 某结点,不知道头指针,能否将结点*p从相应的链表中删去? 若可以,其时间复杂度各为多少? 若可以,其时间复杂度各为多少?
2.11 写出以下链表操作的算法
1)创建一个空的双向循环链表
• status CreateList_Dul(DuLinkList &L);
2)取得双向循环链表中第i个数据元素的位 取得双向循环链表中第i 置指针
• status GetElemP_Dul(DuLinkList L, int i);
3)将单链表置逆
status ReverseList_L(LinkList &L);
2.1 试描述头指针、头结点、开始结点的区别、并说明头指针和头 结点的作用。
开始结点是指链表中的第一个结点,没有直接前趋 开始结点是指链表中的第一个结点,没有直接前趋 的那个结点。 链表的头指针是一指向链表开始结点的指针( 链表的头指针是一指向链表开始结点的指针(没有头 结点时) 结点时),单链表由头指针唯一确定,因此单链 表可以用头指针的名字来命名。 头结点在链表的开始结点之前附加的一个结点。有 头结点在链表的开始结点之前附加的一个结点。有 了头结点之后,头指针指向头结点,不论链表 否为空,头指针总是非空。而且头指针的设置 使得对链表的第一个位置上的操作与在表其他 位置上的操作一致(都是在某一结点之后) 位置上的操作一致(都是在某一结点之后)。
2.3 在顺序表中插入和删除一个结点需平均移动多少 个结点?具体的移动次数取决于哪两个因素? 个结点?具体的移动次数取决于哪两个因素? 在等概率情况下, 在等概率情况下,顺序表中插入一个结点需平均 移动n/2个结点。 个结点。 移动 个结点 删除一个结点需平均移动(n-1)/2个结点。 个结点。 删除一个结点需平均移动 个结点 具体的移动次数取决于顺序表的长度n以及需插 具体的移动次数取决于顺序表的长度 以及需插 入或删除的位置i。 越接近 越接近n则所需移动的结点数越少 入或删除的位置 。i越接近 则所需移动的结点数越少 。
2.4 为什么在单循环链表中设置尾指针比设置头指针更 好? 尾指针是指向终端结点的指针,用它来表示单循环 链表可以使得查找链表的开始结点和终端结点都很方 链表可以使得查找链表的开始结点和终端结点都很方 ,设一带头结点的单循环链表,其尾指针为rear rear,则 便,设一带头结点的单循环链表,其尾指针为rear,则 开始结点和终端结点的位置分别是rear >nextrear开始结点和终端结点的位置分别是rear->next->next 和 查找时间都是O(1) O(1)。 rear, 查找时间都是O(1)。 若用头指针来表示该链表, 若用头指针来表示该链表,则查找终端结点的时 间为O(n)。 间为 。
写一算法在单链表上实现线性表的ListLength(L) ListLength(L)运算。 2.7 写一算法在单链表上实现线性表的ListLength(L)运算。 求单链表长只能用遍历的方法了,从头数到尾。算法如下: int ListLength ( LinkList L ) { int len=0 ; ListNode *p; p=L; //设该表有头结点 设该表有头结点 while ( p->next ) { p=p->next; len++; } return len; }
2.6 设有一个双链表,每个结点中除有prior、 设有一个双链表,每个结点中除有prior、 data和next三个域外,还有一个访问频度域 data和next三个域外,还有一个访问频度域 freq,在链表被起用之前,其值均初始化为 freq,在链表被起用之前,其值均初始化为 零。每当在链表进行一次LocateNode(L,s) 零。每当在链表进行一次LocateNode(L,s) 运算时,令元素值为x的结点中freq域的值 运算时,令元素值为x的结点中freq域的值 加1,并调整表中结点的次序,使其按访问 频度的递减序排列,以便使频繁访问的结点 总是靠近表头。试写一符合上述要求的 LocateNode运算的算法。 LocateNode运算的算法。 2.7 写一算法在单链表上实现线性表的 ListLength(L)运算。 ListLength(L)运算。
假设在长度大于1的单循环链表中,既无头结点也无头指针。s 2.9 假设在长度大于1的单循环链表中,既无头结点也无头指针。s为指 向链表中某个结点的指针,试编写算法删除结点* 向链表中某个结点的指针,试编写算法删除结点*s的直接前趋结点。 status DeleteNode( ListNode *s) { //删除单循环链表中指定结点的直接前趋结点 //删除单循环链表中指定结点的直接前趋结点 ListNode *p, *q; p=s; p->nextwhile( p->next->next!=s) { q=p; p=pp=p->next; } //删除结点 q->next=s; //删除结点 //释放空间 free(p); //释放空间 return OK; }
2.2 何时选用顺序表、何时选用链表作为线性表的存储 结构为宜? 结构为宜? 1.基于空间的考虑。当要求存储的线性表长度变化不大 1.基于空间的考虑。当要求存储的线性表长度变化不大 基于空间的考虑。当要求存储的线性表 ,易于事先确定其大小时,为了节约存储空间,宜采用 顺序表;反之,当线性表长度变化大,难以估计其存储 顺序表;反之,当线性表长度变化大,难以估计其存储 规模时,采用动态链表作为存储结构为好。 2.基于时间的考虑。若线性表的操作主要是进行查找, 基于时间的考虑。 查找, 基于时间的考虑 若线性表的操作主要是进行查找 很少做插入和删除操作时 采用顺序表 操作时, 顺序表做存储结构为宜 很少做插入和删除操作时,采用顺序表做存储结构为宜 ;反之, 若需要对线性表进行频繁地插入或删除等的操 反之, 作时,宜采用链表做存储结构。并且, 作时,宜采用链表做存储结构。并且,若链表的插入和 删除主要发生在表的首尾两端, 删除主要发生在表的首尾两端,则采用尾指针表示的单 循环链表为宜。 循环链表为宜。
2.6设有一个双链表,每个结点中除有prior、data和next三个域外,还有一个访问 2.6设有一个双链表,每个结点中除有prior、data和next三个域外,还有一个访问 设有一个双链表,每个结点中除有prior 频度域freq freq,在链表被起用之前,其值均初始化为零。每当在链表进行一次 频度域freq,在链表被起用之前,其值均初始化为零。每当在链表进行一次 LocateNode(L,s)运算时,令元素值为 的结点中freq域的值加1 运算时,令元素值为x freq域的值加 LocateNode(L,s)运算时,令元素值为x的结点中freq域的值加1,并调整表中结点 的次序,使其按访问频度的递减序排列,以便使频繁访问的结点总是靠近表头。 试写一符合上述要求的LocateNode LocateNode运算的算法。 试写一符合上述要求的LocateNode运算的算法。
2.5 在单链表、双链表和单循环链表中,若仅知道指针p指 在单链表、双链表和单循环链表中,若仅知道指针p 向某结点,不知道头指针,能否将结点* 向某结点,不知道头指针,能否将结点*p从相应的链表中删 若可以,其时间复杂度各为多少? 去?若可以,其时间复杂度各为多少? 单链表。当我们知道指针p 1. 单链表。当我们知道指针p指向某结点时,能够根据该指 针找到其直接后继,但是由于不知道其头指针,所以无法访 问到p指针指向的结点的直接前趋。因此无法删去该结点 无法删去该结点。 问到p指针指向的结点的直接前趋。因此无法删去该结点。 2. 双链表。由于这样的链表提供双向链接,因此根据已知结 点可以查找到其直接前趋和直接后继,从而可以 可以删除该结点 点可以查找到其直接前趋和直接后继,从而可以删除该结点 。其时间复杂度为O(1) O(1)。 。其时间复杂度为O(1)。 3. 单循环链表。根据已知结点位置,我们可以直接得到其 单循环链表。根据已知结点位置, 后相邻的结点位置(直接后继 又因为是循环链表, 直接后继), 后相邻的结点位置 直接后继 ,又因为是循环链表,所以我 们可以通过查找,得到p结点的直接前趋 因此可以删去p 结点的直接前趋。 可以删去 们可以通过查找,得到 结点的直接前趋。因此可以删去 所指结点。其时间复杂度应为O(n)。 所指结点。其时间复杂度应为 。