单链表的19种操作.docx
- 文档编号:23828997
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:19
- 大小:17.61KB
单链表的19种操作.docx
《单链表的19种操作.docx》由会员分享,可在线阅读,更多相关《单链表的19种操作.docx(19页珍藏版)》请在冰豆网上搜索。
单链表的19种操作
单链表的19种操作
#include
#include
#defineNN12
#defineMM20
typedefintelemType;
//以下是关于线性表链接存储(单链表)操作的16种算法
structsNode{ //定义单链表结点类型
elemTypedata;
structsNode*next;
};
//1.初始化线性表,即置单链表的表头指针为空
voidinitList(structsNode**hl)
{
*hl=NULL;
return;
}
//2.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表
voidclearList(structsNode**hl)
{
//cp和np分别作为指向两个相邻结点的指针
structsNode*cp,*np;
cp=*hl;
//遍历单链表,依次释放每个结点
while(cp!
=NULL){
np=cp->next; //保存下一个结点的指针
free(cp);
cp=np;
}
*hl=NULL; //置单链表的表头指针为空
return;
}
//3.返回单链表的长度
intsizeList(structsNode*hl)
{
intcount=0; //用于统计结点的个数
while(hl!
=NULL){
count++;
hl=hl->next;
}
returncount;
}
//4.检查单链表是否为空,若为空则返回1,否则返回0
intemptyList(structsNode*hl)
{
if(hl==NULL){
return1;
}else{
return0;
}
}
//5.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行
elemTypegetElem(structsNode*hl,intpos)
{
inti=0; //统计已遍历的结点个数
if(pos<1){
printf("pos值非法,退出运行!
");
exit
(1);
}
while(hl!
=NULL){
i++;
if(i==pos){
break;
}
hl=hl->next;
}
if(hl!
=NULL){
returnhl->data;
}else{
printf("pos值非法,退出运行!
");
exit
(1);
}
}
//6.遍历一个单链表
voidtraverseList(structsNode*hl)
{
while(hl!
=NULL){
printf("]",hl->data);
hl=hl->next;
}
printf("");
return;
}
//7.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL
elemType*findList(structsNode*hl,elemTypex)
{
while(hl!
=NULL){
if(hl->data==x){
return&hl->data;
}else{
hl=hl->next;
}
}
returnNULL;
}
//8.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0
intupdatePosList(structsNode*hl,intpos,elemTypex)
{
inti=0;
structsNode*p=hl;
while(p!
=NULL){ //查找第pos个结点
i++;
if(pos==i){
break;
}else{
p=p->next;
}
}
if(pos==i){
p->data=x;
return1;
}else{
return0;
}
}
//9.向单链表的表头插入一个元素
voidinsertFirstList(structsNode**hl,elemTypex)
{
structsNode*newP;
newP=malloc(sizeof(structsNode));
if(newP==NULL){
printf("内存分配失败,退出运行!
");
exit
(1);
}
newP->data=x; //把x的值赋给新结点的data域
//把新结点作为新的表头结点插入
newP->next=*hl;
*hl=newP;
return;
}
//10.向单链表的末尾添加一个元素
voidinsertLastList(structsNode**hl,elemTypex)
{
structsNode*newP;
newP=malloc(sizeof(structsNode));
if(newP==NULL){
printf("内在分配失败,退出运行!
");
exit
(1);
}
//把x的值赋给新结点的data域,把空值赋给新结点的next域
newP->data=x;
newP->next=NULL;
//若原表为空,则作为表头结点插入
if(*hl==NULL){
*hl=newP;
}
//查找到表尾结点并完成插入
else{
structsNode*p=NULL;
while(p->next!
=NULL){
p=p->next;
}
p->next=newP;
}
return;
}
//11.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0
intinsetPosList(structsNode**hl,intpos,elemTypex){
inti=0;
structsNode*newP;
structsNode*cp=*hl,*ap=NULL;
//对pos值小于等于0的情况进行处理
if(pos<=0){
printf("pos值非法,返回0表示插入失败!
");
return0;
}
//查找第pos个结点
while(cp!
=NULL){
i++;
if(pos==i){
break;
}else{
ap=cp;
cp=cp->next;
}
}
//产生新结点,若分配失败,则停止插入
newP=malloc(sizeof(structsNode));
if(newP==NULL){
printf("内存分配失败,无法进行插入操作!
");
return0;
}
//把x的值赋给新结点的data域
newP->data=x;
//把新结点插入到表头
if(ap==NULL){
newP->next=cp; //或改为newP->next=*hl;
*hl=newP;
}
//把新结点插入到ap和cp之间
else{
newP->next=cp;
ap->next=newP;
}
return1; //插入成功返回1
}
//12.向有序单链表中插入元素x结点,使得插入后仍然有序
voidinsertOrderList(structsNode**hl,elemTypex)
{
//把单链表的表头指针赋给cp,把ap置空
structsNode*cp=*hl,*ap=NULL;
//建立新结点
structsNode*newP;
newP=malloc(sizeof(structsNode));
if(newP==NULL){
printf("内在分配失败,退出运行!
");
exit
(1);
}
newP->data=x; //把x的值赋给新结点的data域
//把新结点插入到表头
if((cp==NULL)||(x
newP->next=cp;
*hl=newP;
return;
}
//顺序查找出x结点的插入位置
while(cp!
=NULL){
if(x
break;
}else{
ap=cp;
cp=cp->next;
}
}
//把x结点插入到ap和cp之间
newP->next=cp;
ap->next=newP;
return;
}
//13.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行
elemTypedeleteFirstList(structsNode**hl)
{
elemTypetemp;
structsNode*p=*hl; //暂存表头结点指针,以便回收
if(*hl==NULL){
printf("单链表为空,无表头可进行删除,退出运行!
");
exit
(1);
}
*hl=(*hl)->next; //使表头指针指向第二个结点
temp=p->data; //暂存原表头元素,以便返回
free(p); //回收被删除的表头结点
returntemp; //返回第一个结点的值
}
//14.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行
elemTypedeleteLastList(structsNode**hl)
{
elemTypetemp;
//初始化cp和ap指针,使cp指向表头结点,使ap为空
structsNode*cp=*hl;
structsNode*ap=NULL;
//单链表为空则停止运行
if(cp==NULL){
printf("单链表为空,无表头进行删除,退出运行!
");
exit
(1);
}
//从单链表中查找表尾结点,循环结束时cp指向表尾结点,ap指向其前驱结点
while(cp->next!
=NULL){
ap=cp;
cp=cp->next;
}
//若单链表中只有一个结点,则需要修改表头指针
if(ap==NULL){
*hl=(*hl)->next; //或改为*hl=NULL;
}
//删除表尾结点
else{
ap->next=NULL;
}
//暂存表尾元素,以便返回
temp=cp->data;
free(cp); //回收被删除的表尾结点
returntemp; //返回表尾结点的值
}
//15.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行
elemTypedeletePosList(structsNode**hl,intpos)
{
inti=0;
elemTypetemp;
//初始化cp和ap指针,使cp指向表头结点,使ap为空
structsNode*cp=*hl;
structsNode*ap=NULL;
//单链表为空或pos值非法则停止运行
if((cp==NULL)||(pos<=0)){
printf("单链表为空或pos值不正确,退出运行!
");
exit
(1);
}
//从单链表中查找第pos个结点,找到后由cp指向该结点,由ap指向其前驱结点
while(cp!
=NULL){
i++;
if(i==pos){
break;
}
ap=cp;
cp=cp->next;
}
//单链表中没有第pos个结点
if(cp==NULL){
printf("pos值不正确,退出运行!
");
exit
(1);
}
//若pos等于1,则需要删除表头结点
if(pos==1){
*hl=(*hl)->next; //或改为*hl=cp->next;
}
//否则删除非表头结点,此时cp指向该结点,ap指向前驱结点
else{
ap->next=cp->next;
}
//暂存第pos个结点的值,以便返回
temp=cp->data;
free(cp); //回收被删除的第pos个结点
returntemp; //返回在temp中暂存的第pos个结点的值
}
//16.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0
intdeleteValueList(structsNode**hl,elemTypex)
{
//初始化cp和ap指针,使cp指向表头结点,使ap为空
structsNode*cp=*hl;
structsNode*ap=NULL;
//从单链表中查找值为x的结点,找到后由cp指向该结点,由ap指向其前驱结点
while(cp!
=NULL){
if(cp->data==x){
break;
}
ap=cp;
cp=cp->next;
}
//若查找失败,即该单链表中不存在值为x的结点,则返回0
if(cp==NULL){
return0;
}
//如果删除的是表头或非表头结点则分别进行处理
if(ap==NULL){
*hl=(*hl)->next; //或改为*hl=cp->next
}else{
ap->next=cp->next;
}
free(cp); //回收被删除的结点
return1; //返回1表示删除成功
}
//17.把链表逆序输出
voidreverse(structsNode*&head)
{
if(head==NULL)
return;
structsNode*pre,*cur,*ne;
pre=head;
cur=head->next;
while(cur!
=NULL)
{
ne=cur->next;
cur->next=pre;
pre=cur;
cur=ne;
}
head->next=NULL;
head=pre;
returnhead;
}
//************************************************************************
intmain(intargc,char*argv[])
{
inta[NN];
inti;
structsNode*p,*h,*s;
srand(time(NULL));
initList(&p);
for(i=0;i a[i]=rand()&MM; } printf("随机数序列: "); for(i=0;i printf("]",a[i]); } printf(""); printf("随机数逆序: "); for(i=0;i insertFirstList(&p,a[i]); } traverseList(p); printf("单链表长度: ]",sizeList(p)); for(h=p;h! =NULL;h=h->next){ while(deleteValueList(&(h->next),h->data)){ ; } } printf("去除重复数: "); traverseList(p); printf("单链表长度: ]",sizeList(p)); h=NULL; for(s=p;s! =NULL;s=s->next){ insertOrderList(&h,s->data); } printf("有序表序列: "); traverseList(h); clearList(&p); system("pause"); return0; } //**************************和上面不是一个部分***************************************** //18.已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序。 (保留所有结点,即便大小相同) Node*Merge(Node*head1,Node*head2) { if(head1==NULL) returnhead2; if(head2==NULL) returnhead1; Node*head=NULL; Node*p1=NULL; Node*p2=NULL; if(head1->data { head=head1; p1=head1->next; p2=head2; } else { head=head2; p2=head2->next; p1=head1; } Node*pcurrent=head; while(p1! =NULL&&p2! =NULL) { if(p1->data<=p2->data) { pcurrent->next=p1; pcurrent=p1; p1=p1->next; } else { pcurrent->next=p2; pcurrent=p2; p2=p2->next; } } if(p1! =NULL) pcurrent->next=p1; if(p2! =NULL) pcurrent->next=p2; returnhead; } //19.已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。 Node*MergeRecursive(Node*head1,Node*head2) { if(head1==NULL) returnhead2; if(head2==NULL)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单链表 19 操作