本文为CSDN博主coder_gxd原创
转载请注明:https://blog.csdn.net/coder_gxd/article/details/79827262
本文介绍数据结构中单链表的常用算法(C/C++版),欢迎各位同学讨论指正。
#include <stdlib.h>//函数malloc(),free()所在头文件
//本文单链表为含有头结点的单链表
//单链表结点的定义
typedef struct LNode{
int data;//数据域 data ,以 int类型 为例 ;
struct LNode *next;//后继结点指针域;
}LNode;
//尾插法建立单链表,算法复杂度O(n);
//将数组a[]中的数据依次插入到单链表尾部,数组a[]中共 n 个元素;
void creatlistR(LNode *&C,int a[],int n){
LNode *s;//s用来指向新申请的结点
LNode *r;//r用来指向链表C的终端结点
C=(LNode *)malloc(sizeof(LNode));
C->next=NULL;//这两句建立链表C的头结点
r=C;//r指向C,此时头结点就是终端节点
for(int i=0;i<n;i++){
s=(LNode *)malloc(sizeof(LNode));//s用于指向新申请的结点
s->data=a[i];//新申请的节点接收a[]中元素
r->next=s;//将新结点链在终端结点后
r=r->next;//终端结点后移一个
}
r->next=NULL;//a[]中元素导入完毕,C的终端结点指向NULL;
}
//头插法建立单链表,算法复杂度O(n);
//将数组a[]中的数据依次插入到单链表头部,数组a[]中共 n 个元素;
void creatlistF(LNode *&C,int a[],int n){
LNode *s;//s用来指向新申请的结点
C=(LNode *)malloc(sizeof(LNode));
C->next=NULL;//这两句建立链表C的头结点
for(int i=0;i<n;i++){
s=(LNode *)malloc(sizeof(LNode));//s用于指向新申请的结点
s->data=a[i];//新申请的节点接收a[]中元素
s->next=C->next;//将新结点链在头结点后
C->next=s;//终端结点后移一个
}
}
//尾插法建立单链表,单链表的归并操作 ,算法复杂度O(max(p.length,q.length))
//A,B是两个单链表,带头结点,其中,元素递增有序。将A,B归并成一个按元素值“非递减”有序的链表C,C中结点由A和B组成
void mergeR(LNode *A,LNode *B,LNode *&C){
LNode *p=A->next;//p用来跟踪A中最小的结点;
LNode *q=B->next;//q用来跟踪B中最小的结点;
LNode *r;//r用来指向C的终点结点
C=A;C->next=NULL;//用A的头结点来做C的头结点;
free(B);// B的头结点已无用,释放掉;
r=C;//r指向C结点,此时头结点也是重点节点;
while(p!=NULL&&q!=NULL){
if(p->data<=q->data){//p结点的数据小于q结点的数据,p结点尾插入C的尾端;
r->next=p;
p=p->next;
r=r->next;
}
else{//q结点的数据小于p结点的数据,q结点尾插入C的尾端;
r->next=q;
q=q->next;
r=r->next;
}
}
r->next=NULL;//可以省略,因为下面两个if语句必然执行一个
if(p!=NULL) r->next=p;
if(q!=NULL) r->next=q;//这两句将剩余的结点链在C的尾部
}
//头插法建立单链表,单链表的归并操作 ,算法复杂度O(p.length+q.length)
//A,B是两个单链表,带头结点,其中,元素递增有序。将A,B归并成一个按元素值“非递增”有序的链表C,C中结点由A和B组成
void mergeL(LNode *A,LNode *B,LNode *&C){
LNode *p=A->next;//p用来跟踪A中最小的结点;
LNode *q=B->next;//q用来跟踪B中最小的结点;
LNode *s;//s用来指向被操作结点(p或者q),方便操作,相当于中间变量;
C=A;C->next=NULL;//用A的头结点来做C的头结点;
free(B);// B的头结点已无用,释放掉;
while(p!=NULL&&q!=NULL){
if(p->data<=q->data){//p结点的数据小于q结点的数据,p结点尾插入C的开始结点处;
s=p;p=p->next;
s->next=C->next;
C->next=s;
}
else{//q结点的数据小于p结点的数据,q结点尾插入C的开始结点处;
s=q;q=q->next;
s->next=C->next;
C->next=s;
}
}
while(p!=NULL){//将A中剩余的结点逐个键连在C的开始结点处;
s=p;p=p->next;
s->next=C->next;
C->next=s;
}
while(p!=NULL){//将B中剩余的结点逐个键连在C的开始结点处;
s=q;q=q->next;
s->next=C->next;
C->next=s;
}
}
//查找链表中元素并删除;
//查找链表C(带头结点)中值为x的一个结点,若存在,删除并返回1,否则返回0;
int findAndDlete(LNode *&C,int x){
LNode *p;//q结点用来查找目标结点的前一个结点
LNode *q;//q结点用来要被删除的结点
p=C;//p结点从C头结点开始遍历
while(p->next!=NULL){//查找目标结点
if(p->next->data==x){
break;
}
p=p->next;
}
if(p->next==NULL) return 0;//查询失败,返回 0;
else{//查询成功,删除结点
q=p->next;//目标结点赋给 q ;
p->next=q->next;
free(q);
return 1;
}
}