数据结构题集(严蔚敏版)题目——第二章 线性表
2014-10-18 18:35
218 查看
数据结构题集(严蔚敏版)题目——第二章 线性表题目选作。带星号的题基本上全都包含了,没带星号的题选作了大部分。
题目汇总:
代码实现:
题目汇总:
/** 1、设顺序表va中得数据元素递增有序,试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性 */ void InsertElemToOrderedTable(SqList *list, int x); /** 2、设A=(a1,...am)和B=(b1,...bm)均为线性表,A`和B`分别为A、B中除去最大共同前缀后的子表, 若A`B`均为空表,则A=B;若A`为空表而B`不是,并且A`的首元小于B`的首元,则A<B,否则为B<A 试写一个比较A、B大小的算法,不能破坏原表A、B,也不一定先求得A`B`才进行比较 */ void CompareTwoTable(SqList listA, SqList listB); /** 3、已知指针ha和hb分别指向两个单链表的头结点,并且两个链表的长度分别为m和n,试写一算法将这两个链表连接在一起 */ void UnionTwoLinkList(LinkList ha, LinkList hb, int m, int n); /** 4、la和lb为两个无头单链表,从la中删除自第i个元素起len个元素并插入到lb的第j个元素之前,若lb中只有j-1个元素。则插在表尾 #warning:由于该LinkList封装时为带头指针的链表,故无法正常运行,仅供参考算法。 */ Status DeleteElemsAndInsertToAnotherList(LinkList la, LinkList lb, int i, int len, int j); /** 5、已知线性表中元素以值递增有序排列,并以单链表做存储结构,试写一高效算法删除表中所有值大于mink且小于maxk的元素(若存在)。 要求释放被删除结点空间。mink和maxk是两个给定的参数,其值可以与表中元素相同,也可以不同 */ Status DeleteElemsBetweenMinkAndMaxk(LinkList list, int mink, int maxk); /** 6、试写一算法,实现单链表的就地逆置,即利用原表的存储空间将线性表(a1...an)逆置为(an...a1) */ void ReverseLinkList(LinkList list); /** 7、试写一算法,实现顺序表的就地逆置 */ void ReverseSqList(SqList *list); /** 8、设线性表A=(a1,a2...am),B=(b1,b2...bn),试写一算法按如下规则合并AB为C C=(a1,b1...am,bm,bm+1...bn)当m≤n时 或C=(a1,b1...an,bn,an+1...am)当m>n时 注意,要求利用原表(A表和B表)构建C表,且mn并未显式存储 */ void UnionTwoLinkListAlternately(LinkList listA, LinkList listB); /** 9、有两个递增单链表,编写算法将两表归并成递减的表C要求利用原表。 */ void UnionTwoLinkListDecrease(LinkList listA, LinkList listB); /** 10、两个递增的表A、B,求A与B的交集,要求:(1)、利用A表存放最终结果, (2)、求得的结果依旧递增,(3)、A、B中可能存在值相同的元素,但最终交集中不能有相同元素。 */ void IntersectionTwoSqList(SqList *listA, SqList *listB); /** 11、上一题的链表形式 */ void IntersectionTwoLinkList(LinkList *listA, LinkList *listB); /** 12、已知A,B和C是三个递增有序线性表,对A作如下操作:删去既在B中出现又在C中出现的元素,对顺序表编写实现上述操作的算法。 注意:题目中没有特别指明同一表中的元素值各不相同 */ void DeleteSameElemsInOtherTwoSqList(SqList *listA, SqList *listB, SqList *listC); /** 13、同上一题,对单链表编写算法,释放A表中无用的结点空间 */ void DeleteSameElemsInOtherTwoLinklist(LinkList *listA, LinkList *listB, LinkList *listC); /** 14、已知由一个线性链表表示的线性表中含有三种字符的数据元素(字母、数字和其他字符), 试编写算法将该链表分割为三个循环链表,每个循环链表中均只有一类字符。 */ void SegmentTheLinkListToThreeCycleList(LinkList list); /** 15、设以带头结点的双向循环链表表示的线性表L = (a1, a2...an)。 试写一时间复杂度为O(n)的算法将L改造为L = (a1,a3...,an,...a4,a2)。 */ void ChangeTheSequenceOfDoubleCycleLinkList(DoubleLinkList *list); /** 16、设一双向循环链表中添加一访问频度域freq,初始化为0,每次进行locate操作后被访问的值的freq加一, 同时调整结点次序使其按照访问品读非递增顺序排列。试写上述locate算法 */ typedef struct CDNode{ struct CDNode *next; struct CDNode *prior; ElemType data; int freq; }CDNode; typedef CDNode * CDLinkList; CDLinkList FreqLocate(CDLinkList *list, ElemType e);
代码实现:
void InsertElemToOrderedTable(SqList *list, int x) { int i; for (i = 1; i < list->length; i++) { if (x > list->data[i] && x < list->data[i + 1]) { ListInsert(list, i + 1, x); break; } } if (i == list->length) { ListInsert(list, list->length + 1, x); } } void CompareTwoTable(SqList listA, SqList listB) { SqList sublistA = {{0}, 0}, sublistB = {{0}, 0}; int i, j, k = 1; //忽略共同前缀 for (i = 1, j = 1; i <= listA.length && j <= listB.length; i++, j++) { if (listA.data[i] != listB.data[j]) { break; } } //构建A` for (; i <= listA.length; i++) { ListInsert(&sublistA, k++, listA.data[i]); } //构建B` k = 1; for (; j <= listB.length; j++) { ListInsert(&sublistB, k++, listB.data[j]); } printf("表A\n"); for (int m = 1; m <= sublistA.length; m++) { printf("%c ", sublistA.data[m]); } printf("\n表B\n"); for (int m = 1; m <= sublistB.length; m++) { printf("%c ", sublistB.data[m]); } printf("\n"); if (sublistA.length == 0 && sublistB.length == 0) { printf("equal\n"); } else if (sublistA.length == 0 || (sublistB.length > 0 && sublistA.data[1] < sublistB.data[1])) { printf("A < B\n"); } else { printf("A > B\n"); } } void UnionTwoLinkList(LinkList ha, LinkList hb, int m, int n) { Node *p, *q; if (m < n) { p = ha; q = hb; } else { p = hb; q = ha; } while (p->next != NULL) { p = p->next; } p->next = q->next; free(q); } //本题中所有return INFEASIBLE的判断块均为看答案后改正的 Status DeleteElemsAndInsertToAnotherList(LinkList la, LinkList lb, int i, int len, int j) { if (i < 0 || j < 0 || len < 0) { return ERROR; } int k = 1; Node *p, *q, *r, *prior = NULL; p = la; //找到第i个元素 while (p && k < i) { prior = p; p = p->next; k++; } if (!p) { return INFEASIBLE; } //找到i个元素后第len个元素 k = 1; q = p; while (q && k < len) { q = q->next; k++; } if (!q) { return INFEASIBLE; } //在la中进行删除操作 if (prior == NULL) { //当i等于1时,改变la的首元素为q的下一个元素 la = q->next; } else { prior->next = q->next; } //在lb中进行连接操作 if (j == 1) { //当j等于1时将la中得元素插入到lb之前,重新定位lb为p q->next = lb; lb = p; } else { k = 1; r = lb; while (r && k < j - 1) { r = r->next; } if (!r) { return INFEASIBLE; } q->next = r->next; r->next = p; } return OK; } Status DeleteElemsBetweenMinkAndMaxk(LinkList list, int mink, int maxk) { if (list == NULL) { return ERROR; } Node *priorA = NULL, *priorB, *p, *q; p = list->next; while (p && p->data < mink) { priorA = p; p = p->next; } q = p; while (q && q->data <= maxk) { priorB = q; q = q->next; } priorA->next = q; Node *r; while (p != q) { r = p; p = p->next; free(r); } return OK; } //答案给出的是头插法 void ReverseLinkList(LinkList list) { Node *p, *q, *r; //如果表不存在 if (list == NULL) { return; } p = list->next; //如果表为空表 if (p == NULL) { return; } q = p->next; //如果只有一个元素 if (q == NULL) { return; } r = q->next; p->next = NULL; //为了将最后一个元素也逆置,需要判定的是q,最后将头指针指向p即可 while (q != NULL) { q->next = p; p = q; q = r; if (r != NULL) { r = r->next; } } list->next = p; } void ReverseSqList(SqList *list) { int start, end, temp; for (start = 1, end = list->length; start < end; start++, end--) { temp = list->data[start]; list->data[start] = list->data[end]; list->data[end] = temp; } } void UnionTwoLinkListAlternately(LinkList listA, LinkList listB) { int count = 0; Node *p, *q, *r; LinkList listC = (Node *)malloc(sizeof(Node)); listC->next = listA->next; p = listA->next; q = listB->next; r = listC->next; while (p != NULL && q != NULL) { if (count % 2 == 0) { p = p->next; r->next = q; } else { q = q->next; r->next = p; } r = r->next; count++; } PrintLinkList(listC); } void UnionTwoLinkListDecrease(LinkList listA, LinkList listB) { Node *p, *q, *r; LinkList listC = (Node *)malloc(sizeof(Node)); p = listA->next; q = listB->next; r= listC; while (p != NULL && q != NULL) { if (p->data < q->data) { r->next = p; r = r->next; p = p->next; } else { r->next = q; r = r->next; q = q->next; } } if (p == NULL) { r->next = q; } else if (q == NULL) { r->next = p; } ReverseLinkList(listC); PrintLinkList(listC); } void IntersectionTwoSqList(SqList *listA, SqList *listB) { int i, j, k = 1; for (i = 1; i <= (*listA).length;) { for (j = 1; j <= (*listB).length;) { if ((*listA).data[i] == (*listA).data[i - 1]) { i++; continue; } else if ((*listB).data[j] == (*listB).data[j - 1]) { j++; continue; } if ((*listA).data[i] == (*listB).data[j]) { (*listA).data[k++] = (*listA).data[i]; i++; j++; } else if ((*listA).data[i] < (*listB).data[j]) { i++; } else { j++; } } } (*listA).length = k - 1; for (i = 1; i < k; i++) { printf("%d ", (*listA).data[i]); } printf("\n"); } #warning - 网上学习的 void IntersectionTwoLinkList(LinkList *listA, LinkList *listB) { //prior用于记录前驱指针 LinkList pa = (*listA)->next, pb = (*listB)->next, priorA = (*listA), priorB = (*listB); LinkList temp; //因为是求交集,所以当pa与pb的data不相等时删除该结点 while (pa && pb) { if (pa->data < pb->data) { temp = pa; pa = pa->next; priorA->next = pa; free(temp); } else if (pa->data > pb->data) { temp = pb; pb = pb->next; priorB ->next = pb; free(temp); } else { //相等时判定,因为A中可能有相同元素,所以应该删除这些相同元素 //B是不用判定的,因为接下来的比较中会将重复元素删除 if (pa->data == priorA->data) { temp = pa; pa = pa->next; priorA->next = pa; free(temp); } else { priorA = pa; pa = pa->next; } } } //处理A或B表的剩余结点 while (pa) { temp = pa; pa = pa->next; priorA->next = pa; free(temp); } while (pb) { temp = pb; pb = pb->next; priorB->next = pb; free(temp); } pb = (*listB); free(pb); } void DeleteSameElemsInOtherTwoSqList(SqList *listA, SqList *listB, SqList *listC) { //2 2 3 5 5 7 8 11 13 IntersectionTwoSqList(listB, listC); int i = 1, j = 1; int e; while (i <= (*listA).length && j <= (*listB).length) { if ((*listA).data[i] < (*listB).data[j]) { i++; } else if ((*listA).data[i] > (*listB).data[j]) { j++; } else { ListDelete(listA, i, &e); } } } void DeleteSameElemsInOtherTwoLinklist(LinkList *listA, LinkList *listB, LinkList *listC) { IntersectionTwoLinkList(listB, listC); LinkList p = (*listA)->next, q = (*listB)->next, temp; int cur = 1, e; while (p && q) { if (p->data < q->data) { cur++; temp = p; p = p->next; free(temp); } else if (p->data > q->data) { temp = q; q = q->next; free(temp); } else { LinkListDelete(listA, cur, &e); } } } void SegmentTheLinkListToThreeCycleList(LinkList list) { LinkList listA, listB, listC; //此处应该定义为循环链表 LinkList p = list->next; int i = 1, j = 1, k = 1; //三类字符,数字、字母和其他 while (p) { if (isalpha(p->data)) { LinkListInsert(&listA, i++, p->data); } else if (isnumber(p->data)) { LinkListInsert(&listB, j++, p->data); } else { LinkListInsert(&listC, k++, p->data); } p = p->next; } } void ChangeTheSequenceOfDoubleCycleLinkList(DoubleLinkList *list) { //此算法使用的数据结构应该为双向循环链表,此处仅以双向链表代替 DoubleLinkList p = (*list)->next; DoubleLinkList oddList, evenList; int count = 1, k = 1; while (p) { //此处应为循环链表的判尾条件 if (count % 2 == 0) { DLinkListInsert(&evenList, 1, p->data); //偶数逆序插入 } else { DLinkListInsert(&oddList, k++, p->data); //奇数顺序插入 } count++; } //联接两双向链表,用list记录返回 ConcatTowDLinkList(&oddList, &evenList, list); } CDLinkList FreqLocate(CDLinkList *list, ElemType e) { CDLinkList p = (*list)->next; //查找返回的结点 CDLinkList q = p; //比较优先级用 //1、定位 while (p != *list) { if (p->data == e) { break; } p = p->next; } if (p == *list) { return NULL; } //2、增加freq p->freq++; //3、删除结点 p->prior->next = p->next; p->next->prior = p->prior; //4、查找合适的位置 while (q != *list && p->freq < q->freq) { q = q->next; } //5、插入到q结点之前 p->next = q; p->prior = q->prior; q->prior->next = p; q->prior = p; return p; }
相关文章推荐
- 考研题目 第二章线性表
- 数据结构 清华 严蔚敏 第二章 线性表 知识点总结 附思维导图
- 数据结构题集(严蔚敏版)题目——第一章 绪论
- 考研题目 第二章 线性表 答案
- 《数据结构》严蔚敏版(java解)——第二章 线性表02 顺序线性表操作
- 《数据结构》严蔚敏版(java解)——第二章 线性表03 单链表操作
- 《数据结构》严蔚敏版(java解)——第二章 线性表05 双端链表操作
- 《数据结构》严蔚敏版(java解)——第二章 线性表04 顺序单链表合并
- 《数据结构》严蔚敏版(java解)——第二章 线性表01 基本操作
- 2-8-双循环链表链式存储结构-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版
- 算法设计题2.13-线性表-第2章-《数据结构习题集》-严蔚敏吴伟民版
- 数据结构题集(严蔚敏)1.17求k阶斐波那契序列的第n项值的函数算法
- 【思维导图】数据结构第二章 线性表
- 【知识导论图】数据结构第二章线性表
- 数据结构 第二章 线性表 英语成绩表的单链表实现
- 第二章 习题2.1-3 查找线性表
- 第二章 线性表
- 东北大学考研线性表相关历年真题题目整理
- 第二章线性表
- 第二章:线性表与realloc用法 学习记录