- 设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点
void Del_X_3(Linklist &L,ElemType x){
LNode *p;
if(L==NULL){
return;
}
if(L->data==x){
p=L;
L=L->next;
free(p);
Dex_X_3(L,x);
}else{
Del_X_3(L->next,x);
}
}
- 在带头结点的单链表L中,删除所有值为X的结点,并释放其空间,假设值为X的结点不唯一,试编写算法实现以上的操作
void Del_X_1(Linklist &L,ElemType x){
LNode *pre=L,*p=L->next,*q;
while(p->next!=null){
if(p->data==X){
q=p;
p=p->next;
pre->next=p;
free(q);
}else{
pre=p;
p=p->next;
}
}
}
- 设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值
void Lprint(Linklist &L){
if(L->next!=NULL){
Lprint(L->next);
}
if(L!=null) print(L->data);
}
void R_Ignore_Head(Linklist &L){
if(L->next!=NULL) Lprint(L->next);
}
- 试编写算法将带头结点的单链表就地逆置,指辅助空间复杂度为O(1)
void Reverse(Linklist L){
LNode *pre,*p=L->next,*r=p->next;
p->next=NULL;
while(r!=NULL){
pre=p;
p=r;
r=r->next;
p-next=pre;
}
L->next=p;
return L;
}
//使用前插法
LinkList Reverse(LinkList L){
LNode *p,*r;
p=L->next;
L->next=NULL;
while(p!=NULL){
r=p->next;
p->next=L->next;
L->next=p;
p=r;
}
return L;
}
- 试编写算法将带头结点的单链表L中删除一个最小值结点的高效算法
LinkList Delete_Min(LinkList &L){
LNode *pre=L,*p=pre->next;
LNode *minpre=pre,*minp=p;
while(p!=NULL){
if(p->data<minp->data){
minp=p;
minpre=pre;
}
pre=p;
p=p->next;
}
minpre->next=minp->next;
free(minp);
return L;
}
- 有一个带头结点的单链表L,设计一个算法使其元素递增有序
void sort(LinkList &L){
LNode *p=L->next,*pre;
LNode *r=p->next;
p->next=NULL;
p=r;
while(p!=NULL){
r=p->next;
pre=L;
while(pre->next!=NULL&&pre->next->data<p->data){
pre=pre->next;
}
p->next=pre->next;
pre->next=p;
p=r;
}
}
- 设在一个带表头结点的单链表中所有的元素结点都无序,试编写一个函数删除表中所有介于给定两个之间的元素的元素
void RangeDelete(LinkList &L,int min,int max){
LNode *pr=L,*p=L->next;
while(p!=NULL){
if(p->data>min&&p->data<max){
pr->next=p->next;
free(p);
p=pr->next;
}else{
pr=p;
p=p->next;
}
}
}
- 给定两个单链表,编写算法找出两个链表的公共结点
LinkList Search_lst_Common(LinkList L1.LinkList L2){
int len1=Length(L1);
int len2=Length(L2);
LinkList longList,shortList;
if(len1>len2){
longList=L1->next;
shortList=L2->next;
dist=len1-len2;
else{
longList=L2->next;
shortList=L1->next;
dist=len2-len1;
}
while(dist--){
longList=longList->next;
}
while(longList!=NULL){
if(longList==shortList) return longList;
else{
longList=longList->next;
shortList=shortList->next;
}
}
return NULL;
}
9.给定一个带表头结点的单链表,设head为头指针,结点结构为(data,next),data为整形元素,next为指针,试写出算法:按照递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间(要求:不允许舒勇数组作为辅助空间)
/*
算法思想:对链表进行遍历,在每次遍历中找出整个链表的最小值元素,输出并释放结点所占空间;再查找次小值元素,输出并释放空间,如此下去,直至链表为空,最后释放头结点所占 存储空间。该算法的时间复杂度为 O(n^2)。
*/
void MinDelete(LinkList &head){
while(head->next!=NULL){
LNode *pre=head;
LNode *p=pre->next;
while(p->next!=NULL){
if(p->next->data<pre->next->data){
pre=p;
}
p=p->next;
}
print(pre->next->data);
u=pre->next;
pre->next=u->next;
free(u);
}
free(head);
}
- 将一个带头结点的单链表A分解为两个带头结点的单链表A和B使得A表中含有原表中序号为基数的元素,而B表中含有原表中序号为偶数的元素,且保持相对顺序不变
LinkList DisCreat_1(LinkList &A){
//将表A中结点按序号的奇偶性分解到表A或表B中
int i=0; //1记录表A中结点的序号
LinkList B=(LinkList)malloc(sizeof(LNode)); //创建B表表头
B->next=NULL; //B表的初始化
LNode *ra=A,*rb=B,*p;//ra和rb将分别指向将创建的A表和B 表的尾结点
p=A->next; //p为链表工作指针,指向待分解的结点
A->next=NULL; //置空新的A表
while(p!=NULL){
i++;//序号加1
if(i%2==0){ //处理序号为偶数的链表结点
rb->next=p; //在B表尾插入新结点
rb=p; //rb指向新的尾结点
} else{ //处理原序号为奇数的结点
ra->next=p; //在A表尾插入新结点
ra=p;
}
p=p->next; //将p恢复为指向新的待处理结点
} //while结束
ra->next=NULL;
rb->next=NULL;
return B;
}
- 设C={a1,b1,a2,b2,…,an,bn}为线性表采用带头结点的hc单链表存放设计一个算法将其拆分为两个为两个线性表使得A={a1,a2,a3…,an},B={b1,b2,b3…bn}.
LinkList DisCreat2(LinkList &A){
LinkList B=(LinkList)malloc(sizeof(LNode));//创建B表表头
B->next-NULL; //B表的初始化
LNode*p=A->next,*qi;//p为工作指针
LNode*ra=A; //ra始终指向A的尾结点
while(p!=NULL){
ra->next=p;
ra=p; //将*p链到A的表尾
p=p->next;
if(p!=null){ //头插后,*p将断链,因此用q记忆*p的后继
q=p->next;
p->next=B->next; //将*p插入到B的前端
B->next=p; (
p=q; //A尾结点的next域置空
}
}
ra->next=NULL;
return B;
}
- 在一个递增有序的线性表中,有数值相同的元素存在。若存储的方式为单链表,设计算法去掉数值相同的元素使表中不再有重复元素
/*
算法思想:由于是有序表,所有相同值域的结点都是相邻的。
用p扫描递增单链表L,若*p 结点的值域等于其后继结点的值域,则删除后者,否则p移向下一个结点。
*/
void DelSame(LinkList&L){
//L是递增有序的单链表,本算法删除表中数值相同的元素
LNode *p=L->next,*q; //p为扫描工作指针
if(p==NULL) return;
while(p->next!=NULL){
q=p->next; //q指向*p的后继结点
if(p->data=q->data){ //找到重复值的结点
p->next=q->next; //释放*q结点
free(q) //释放相同元素值的结点
} else {
p=p->next;
}
}
}
- 假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表
/*
算法思想:两个链表已经按元素值递增次序排序,将其合并时,均从第一个结点起进行比较,
将小的结点链入链表中,同时后移工作指针。该问题要求结果链表按元素值递减次序排列,
故新 链表的建立应该采用头插法。比较结束后,可能会有一个链表非空,
此时用头插法将剩下的结点依次插入新链表中即可
*/
void MergeList(LinkList &La,LinkList &Lb){
LNode *r,*pa=La->next,*pb=Lb->next;
La->next=NULL;//当两链表均不为空时,循环
while(pa&&pb)
if(pa->data<-pb->data){ //r暂存pa的后继结点指针
r=pa->next;
pa->next=La->next; //将pa结点链于结果表中,同时逆置
La->next=pa;
pa=r;
} //恢复pa为当前待比较结点
else{//r暂存pb的后继结点指针
r=pb->next;
pb->next=La->next; //将pb结点链于结果表中,同时逆置
La->next=pb; //恢复pb为当前待比较结点
pb=r;
}
if(pa) pb=pa; //通常情况下会剩一个链表非空,处理 剩下的部分
while(pb){ //处理剩下的一个非空链表
r=pb->next; //依次插入到La中(头插法)
pb->next-La->next;
La->next=pb;
pb=r;
}
free(Lb);
}
14.设A和B是两个带头结点的单链表,其中元素递增有序。设计一个算法从A和B中的公共元素产生链表C,要求不破坏A,B的结点。
//算法思想:表A、B都有序,可从第一个元素起依次比较A、B两表的元素,若元素值不等,
//则值小的指针往后移,若元素值相等,则创建一个值等于两结点的元素值的新结点,
//使用尾插法 插入到新的链表中,并将两个原表指针后移一位,直到其中一个链表遍历到表尾
void Get_Common(LinkList A,LinkList B)(//本算法产生单链表A和B的公共元素的单链表C
LNode *p=A->next,*q=B->next,*r,*s; //r始终指向C的尾结点
LinkList C=(LinkList)malloc(sizeof(LNode));
r=C;
while(p!=NULL&&q!=NULL){ //循环跳出条件
if(p->data<q->data) p=p->next; //若A的当前元素较小,后移指针
elseif(p->data>q->data)
q=q->next; //若B的当前元素较小,后移指针
else{ //找到公共元素结点
s=(LNode*)malloc(sizeof(LNode));
s->data=p->data;
r->next=s;
r=s;
p=p->next;
q=q->next;
}
}
r->next=NULL;
}
15.已知两个链表A,B分别表示两个集合,其元素递增排序,编制函数求A,B的交集,并存放于A链表中
/*
算法思想:采用归并的思想,设置两个工作指针pa和pb,对两个链表进行归并扫描,
只同时出现在两集合中的元素才链接到结果表中且仅保留一个,
其他的结点全部释放。当一个链 遍历完毕后,释放另一个表中剩下的全部结点。
*/
LinkList Union(LinkList &la,LinkList &lb)(
pa=la->next; //设工作指针分别为pa和pb
pb=lb->next;
pc=la; //结果表中当前合并结点的前驱指针
while(pa&&pb){
if(pa->data==pb->data){ //交集并入结果表中
pc->next=pa; //A中结点链接到结果表
pc=pa;
pa=pa->next;
u=pb;//B中结点释放
pb=pb->next;
free(u);
}
else if(pa->data<pb->data){
u=pa;
pa=pa->next;
free(u);
}
else {
u=pb;
pb=pb->next;
free(u);
}
}
while(pa){
u=pa;
pa=pa->next;
free(u);
}
while(pb){
u-pb;
pb=pb->next;
free(u);
}
pc->next=NULL;
free(lb);
return la;
}