数据结构学习(二)、线性表的练习
学习新的知识,只是单纯的看书,当时你跟随着作者的思路可能很容易就懂了,脱离书本后,发现似懂非懂,
到了实际的应用时,更加会感觉似是而非。所以,适量的练习,是非常有利于理解新知识的。
1、将一个带结点的单向链表逆序。
根据是否改变头结点分为2种方法。
变换头结点
思路:
1.声明三指针变量p,q,r,其中p指向头结点,q指向第一个结点;
2. 循环(q不为空)
-
- 将q->next赋值给r
- 将q->next设为p
- 将q的值赋给p
- 将q赋值给p
- 将r赋值给q
3. 将原头指针指向NULL
4. 将最后一个结点p设为头指针
Status ListReverse(LinkList *L){ LinkList p,q,r; p = *L; q= (*L)->next; while(q){ r = q->next; q->next = p;
p->data = q->data; p = q; q = r; } (*L)->next = NULL; *L = p; }
不变换头结点
思路:
1.声明三指针变量p,q,r,其中p指向第一个结点,q指向第二个结点;
2. 循环(q不为空)
-
- 将q->next赋值给r
- 将q->next设为p
- 将q赋值给p
- 将r赋值给q
3. 将第一个结点指向NULL
4. 将头结点指向最后一个结点
Status ListReverse1(LinkList *L){ LinkList p,q,r; p= (*L)->next; q= (*L)->next->next; while(q){ r=q->next; q->next=p; p = q; q = r; } (*L)->next->next = NULL; (*L)->next = p; return OK; }
2.已知两个链表各自有序并且顺序相同,请把它们合并成一个链表依然有序。
其实简单的说就是根据data改变结点的指向的改变,接下来我们详细分析其演变过程,假设二个列表如下图
最开始有平p1、p2指针分开指向链表的第一个结点,比较被指针指向结点的值,小于或等于的结点指针向下移动一位。
第一步:1<4 将p1向下移动,新链表尾结点设为a1
第二步:3<4 将p1向下移动,结点a1(新链表的尾结点)指向结点a2
第三步:5>4 将p2向下移动,结点a2(新链表的尾结点)指向结点b1
第四步:5<6 将p1向下移动,结点b1(新链表的尾结点)指向结点a3
第五步:p1指向空,结点a3(新链表的尾结点)指向结点b2
总结规律:通过观察可以发现,将二个有序列表合并成一个有序列表的过程其实就是不断的比较当前指向的二结点的data值,
将新链表的尾结点指向data较小的结点,当某一链表结束,则将新链表的尾结点指向另一链表当前指针所指向的结点。
① 递归实现
LinkList UnionLinkList(LinkList a,LinkList b) { if(a==NULL) return b; if(b==NULL) return a; if(a->data<=b->data) { a->next = UnionLinkList(a->next,b); return a; } if(a->data>b->data) { b->next = UnionLinkList(a.b->next); return b; } }
②循环实现
LinkList UnionLinkList(LinkList a,LinkList b){ LinkList head,p1,p2,last; last = head; p1 = a; p2 = b; while(p1 && p2){ if(p1->data<=p2->data) { last->next = p1; p1 = p1->next; last = last->next; }else { last->next = p2; p2 = p2->next; last = last->next; } } if(p1) last->next = p1; else last->next = p2; return head; }