Ex1 不用额外的空间连接两个线性表
(1)将指针移到尾结点
(2)连接两个线性表a,b
(3)释放另一个线性表的头结点
代码比较简单我就不写了
Ex 2对两个链表进行排序
有两个单链表,其数据元素值由小到大进行连接,需要设计一个算法将两个链表混合,使混合链表的元素也是由小到大.
首先我们需要一个指针指向已经排好的链表的尾巴,两个指针用来遍历两个链表
画的可能稍显凌乱 我来解释一下
m指针 指向的就是已经排好的链表的尾结点
p = a->next; q = b->next; p用来遍历a链表 q用来遍历b链表
比较p和q指向的数据的大小
(1)当两个指针都没有遍历到空时:
如果p->data > q->data 则混合链表的下一个结点取q中的数据,m移到q上,q往前移动
如果p->data <= q->data 则混合链表的下一个结点取p中的数据 m移动到p上,p往前移动
(2)如果有一个表已经遍历到空的位置,则将为扫描完的表剩余的部分链接到混合表的尾部
void merge(slink*a,slink*b){
slink*m,*p,*q;
//初始化
m = a;
p = a->next;
q = b->next;
//根据pq结点的数据大小以此将表连接起来
while(p && q){
if(p->data > q->data){
m->next = q;
m = q;
q = q->next;
}else{
m->next = p;
m = p;
p = p->next;
}
}
//连接剩余的表
m -> next = p ? p : q;
free(b);
}
Ex 3 计算A和B的交集
假设我们已经把A和B中的元素都存入了ab两个链表,
(1)在a中依次搜索b中每个结点,若存在相同结点,则在a中删除.
遍历a需要一个指针,遍历b需要一个指针,删除元素还需要额外的一个指针 所以总共需要三个辅助指针
(2)搜索结束后,把b连接在a后面 a表即为所求
void Union(slink* a, slink* b) {
slink* p, * q, * r;
p = a->next;
q = b->next;
r = a;
int found = 0;
//外层循环遍历a链表
while (p) {
//内层循环遍历b链表
while (q) {
//如果发现相同元素则删除
if (q->data == p->data) {
r->next = p->next;
free(p);
p = r->next;
found = 1;
break;
}
q = q->next;
}
q = b->next; //记得要重置q!!
if (!found) { //如果已经进行了删除的操作 P指针已经向前移了 不需要再往前移
r = p;
p = p->next;
}
found = 0;
}
//将b链表连上a链表
r->next = b->next;
free(b);
}
我自己在写这段代码的时候还出了挺多的问题的...比如说一开始没有设置那个found变量,导致如果一个元素被删除了p已经向前移动了一个结点,出了while循环又要向前移动一个结点,就移动了两次;还有q最开始忘记每次循环开始都要重置一下。
Ex 4 链表逆序
将一个链表的元素逆序重新排列
其实不难联想到 我们在使用头插法创建链表的时候 比如说 你输入的值的顺序是 2 3 4 5 创完表后从表头往后的实际顺序是5 4 3 2 所以这道题我们可以使用头插法来解决
需要一个辅助指针来完成头插,另外一个辅助指针负责遍历链表
void reverse(slink* L) {
slink* p, * q;
//初始化
p = L->next;
q = p->next;
L->next = NULL;
while (p) {
//头插
p->next = L->next;
L->next = p;
p = q;
//如果q已经为空就不要移动了
if(q)
q = q->next;
}
}
Ex 5 计算两个多项式之和
我们设计一个结点:
typedef struct node {
int c; //记录变量系数
int e; //记录变量指数
struct node* next;
}polyList;
分析问题:
合并的多项式要满足从左往右指数依次增大,则存在一个排序问题,我们在ex2中分析过,需要两个指针p,q遍历两个链表,一个指针s记录已经排好序的链表末尾
我们逐步来看:
其实就是分为五种情况
(1)指数相同且系数相加不为0
p->c += q->c; s = p;
p = p->next; q = q->next;
(2)p的指数大于q的指数
s->next = p; p = p->next;
(3)p的指数小于q的指数
s->next = q; q = q->next;
(4) 指数相同且系数相加等于0
t = p; p = p->next; free(t);
t = q; q = q->next; free(t);
(5)p q中有一个为空
如果p为空
s->next = q
反之 s->next = p;
最后记得释放b的头结点即可
void calculate(polyList* a, polyList* b) {
polyList* s, * p, * q, * t;//s用于记录排列好的链表尾端,pq分别遍历两张表,t辅助删除结点;
//初始化;
s = a;
p = a->next;
q = b->next;
while (p && q) {
//第一种情况
if (p->e == q->e) {
p->c += q->c;
//如果相加不为零
if (p->c != 0) {
s = p;
p = p->next;
q = q->next;
}//如果相加为0 删除结点
else {
t = p; p = p->next; free(t);
t = q; q = q->next; free(t);
}
}//第二种情况
else if (p->e > q->e) {
s->next = p;
s = p;
p = p->next;
}//第三种情况
else if (p->e < q->e) {
s->next = q;
s = q;
q = q->next;
}
}
//当p q 中有一个指向了空节点;
s->next = p ? p : q;
free(b);//释放b的头结点
}
有什么问题欢迎在评论区批评指正!!