1.单链表拆分:
**题如下:**对于一个带头结点的单链表L={a1,b1,a2,b2,a3,b3,a4,b4…an,bn},现将单链表拆分成两个链表:L1={a1,a2,a3,a4,a5,a6…,an};L2={bn,bn-1…b3,b2,b1};其中L1沿用原节点L,L2则新建节点。
**思路分析:**对于所有a节点,依次指向下一个a节点,对于b节点,则采用头接法依次接入L2链表。
代码如下:
#include<stdio.h>
#include<stdlib.h>
struct sqlist{
int data;
sqlist *next;
};
sqlist *L,*L2=new sqlist; //建立L与L2节点,此处采用C++的方法,也可以写成sqlist *L2=(sqlist *)malloc(sizeof(sqlist));
sqlist *creat(int a[]){ //给定初始数组,生成链表L,并返回
sqlist *head=new sqlist, * temp;
head->next=NULL; //建立head头节点,指向NULL;
sqlist *p=head;
//sqlist *pre=head->next;
for(int i=0;a[i]!=0;i++){
temp=new sqlist; //逐个建立新节点,插入链表,此处采用尾接法,建立顺序链表。
temp->data=a[i];
p->next=temp;
p=temp;
}
p->next=NULL;
return head;
}
void cf(sqlist *&L,sqlist *&L2){ //拆分函数,引用输入L与L2
sqlist *p,*r,*q;
p=L->next;L2->next=NULL;
r=L2;
while(p!=NULL){ //p为a节点。
q=p->next; //q指向a对应的下个b节点。
p->next=q->next; //p指向下一个a节点。
q->next=r->next; //注意,必须要先将q指向头节点r的下一个节点,然后将头节点指向q,如果交换顺序的话,当r指向q后,将会导致r原本的链表断开,始终指向本身节点。
r->next=q;
p=p->next;
}
}
void show(sqlist *head){ //输出链表
sqlist *p=head->next;
while(p!=NULL){
printf("%d",p->data);
p=p->next;
if(p!=NULL) printf(" ");
else printf("\n");
}
}
int main(){
int array[20]={1,2,3,4,5,6,7,8,9,10,0}; //演示数组,将0之前的所有元素生成单链表。
L=creat(array);
printf("L的输出结果是:\n");
show(L);
cf(L,L2);
printf("拆分后L与L2的结果分别是:\n");
show(L);show(L2);
// system("pause");//由于DEV C++崩了,只能在VC 6.0上运行,为了观察结果写的暂停。
return 0;
}
2.删除最大值。
**题意简介:**若要删除链表最大值,且考虑程序运行效率,可以模仿数组,找到最大值对应的“下标”。设置max节点,存储最大值对应的节点,mpre存储最大节点的前导节点,随后mpre->next=max->next;delete(max);
代码如下://仅为功能函数对应部分,可以套入上面的框架中进行验证。
void deletemax(sqlist *&L){
sqlist *p,*max,*pre=L,*mpre; //设置pre及p遍历链表,设置max及mpre存储最大值及其前导节点。
p=L->next;
max=p;
while(p!=NULL){
if(p->data>max->data){
max=p;
mpre=pre;
}
pre=p;
p=p->next;
}
mpre->next=max->next;
delete(max);
}
3.单链表排序
**问题:**对于一给定的链表(保底有一个元素),在不借助其他存储结构的情况下,对该链表进行递增排序。
**思路解析:**对于该链表,先构造一个只有一个元素的有序链表,对于剩下的部分,逐个与有序链表对比,将其插入有序链表当中。
void sortsq(sqlist *&L){
sqlist *p=L->next->next,*pre,*q; //p为第二个元素,
L->next->next=NULL; //构造L为只有一个元素的链表,必须要设置p然后构造L,否则导致链表断开。
while(p!=NULL){ //从第二个元素开始遍历。
q=p->next; //存放下一个节点
pre=L; //从头开始遍历
while(pre->next!=NULL && pre->next->data<p->data) pre=pre->next; //在遍历结束前,在有序链表中找到大于等于p的节点,并在其前导节点后插入;
p->next=pre->next;
pre->next=p;
p=q;
}
}