前文:
#include<stdio.h>
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
1、链表的头插法
代码如下:
void CreateList_L(LinkList &L,int n){
//逆位序输入n个元素的值,建立带表头结点的单链线性表L
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL; //先建立一个带头结点的单链表
for(i=n;i>0;i--){
p=(LinkList)malloc(sizeof(LNode)); //生成新的结点
scanf(&p->data); //输入元素值
p->next = L->next; //p的next指向L的next
L->next = p; //L的next指向p
}
}
图解:
2、链表的尾插法
代码如下:
void CreateLink_L(LinkList &L,int n){
InitList(L);
LinkList p,r=L;
for(int i=0;i<n;i++){
p=(LinkList)malloc(sizeof(LNode));
scanf(&p->data);
r->next = p; //r的next指向p
r=p; //将r更新为p,r仍为最后
}
r->next = NULL;
}
图解:
3、删除第i个元素
代码如下:
Status ListDelete_L(LinkList &L,int i,ElemType &e){
//在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
p = L;j = 0;
while(p->next && j<i-1){
//当j=i-1时循环结束,此时p指向的是i-1
//寻找第i个结点,并令p指向其前驱
p=p->next;
++j;
}
if(!(p->next) || j>i-1) return ERROR; //删除位置不合理
//p->next是要删除的元素,也就是下文的q
q = p->next;
p->next=q->next;//或者p->next=p->next->next;
e = q->data; //将第i个结点的数据存放到e中
free(p); //释放p的空间
return ok;
}
while( p->next && cnt < i)
p->next表示的意思是p的next是否为空,为空退出循环
当删除操作时,若p指向最后一个结点,再执行p=p->next,那么删除的是个空位置
详解见:单链表的删除算法中循环条件(p->next&&j<i)和插入算法中的循环条件(p&&(j<i))有什么区别?
4、两个有序链表并为一个有序链表
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
//已知单链线性表La和Lb的元素按值非递减排列
//归并La和Lb得到新的单链线性表Lc,Lc的元素也按非递减排列
LinkList pa,pb,pc;
pa=La->next;//初始化pa的初值指向表La的第一个结点
pb=Lb->next;
Lc=pc=La;//用La的头结点作为Lc的头结点,pc的初值指向Lc的头结点
while(pa && pb){
//当两个表非空,依次取出两表中较小的结点插入到Lc表的最后
if(pa->data<=pb->data){
pc->next=pa;pc=pa;pa=pa->next;
}
else{
pc->next=pb;pc=pb;pb=pb->next;
}
}
pc->next=pa?pa:pb;//插入剩余结点
free(Lb);
return OK;
}
[表达式]?a:b;
其含义就是:如果表达式为真,则返回a的值,反之如果表达式为假,则返回b的值。
具体代码展示:
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define OVERFLOW 0
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
//建立一个空链表
int InitList_L(LinkList &L){
L=(LinkList)malloc(sizeof(LNode));
if(!L){
exit(OVERFLOW);
}
L->next=NULL;
return OK;
}
int CreateList_L(LinkList &L,int n){
LinkList p,q;
int i;
printf("Input the datas in increasing order:");
q=L;
for(i=0;i<n;i++){
p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next=q->next;
// p->next=L->next;
q->next=p;
q=p;
}
return OK;
}
int MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
LinkList pa,pb,pc;
pa=La->next;//初始化pa的初值指向表La的第一个结点
pb=Lb->next;
Lc=pc=La;//用La的头结点作为Lc的头结点,pc的初值指向Lc的头结点
while(pa && pb){ //当两个表非空,依次取出两表中较小的结点插入到Lc表的最后
if(pa->data<=pb->data){
pc->next=pa;pc=pa;pa=pa->next;
}else{
pc->next=pb;pc=pb;pb=pb->next;
}
}
pc->next=pa?pa:pb;//插入剩余结点
free(Lb);
return OK;
}
int TraverseList_L(LinkList L){
LinkList p;
p=L->next;
while(p){
printf("%d",p->data);
p=p->next;
}
return OK;
}
main(){
int n;
LinkList La,Lb,Lc;
InitList_L(La);
InitList_L(Lb);
printf("Input the length of the list La:");
scanf("%d",&n);
CreateList_L(La,n);
printf("Input the length of the list Lb:");
scanf("%d",&n);
CreateList_L(Lb,n);
MergeList_L(La,Lb,Lc);
printf("Output the data in Lc:");
TraverseList_L(Lc);
printf("\n");
}
结果:
android@android-Latitude-E4300:~/work/c/danlianbiao$ ./mergelist
Input the length of the list La:3
Input the datas in increasing order:1 3 5
Input the length of the list Lb:4
Input the datas in increasing order:2 4 6 8
Output the data in Lc:1234568