无头单链表的各种操作

//本源码采用二级指针,实现了无头单链表的各种操作

#include<stdio.h>
#include<stdlib.h>
typedef int elemtype;
typedef struct node
{
elemtype data;
struct node *link;
}NODE,*NODEP,**LINKP;
//typedef bool (*remove_fn)(NODEP const v);
/**********建立一个不带头结点的单链表*******************/
NODEP init()
{
NODEP head;
head=(NODEP)malloc(sizeof(NODE));
head->link=NULL;
return head;
}
/*************以尾接法建立单链表**************/
//注意linkp永远指向指向尾结点的指针,对于开始linkp指向head
void rear_create(LINKP linkp)
{
NODEP newnode;
printf("请输入第一个数(-1代表结束):");
scanf("%d",&(*linkp)->data);
while((*linkp)->data!=-1)
{
newnode=(NODEP)malloc(sizeof(NODE));
printf("请输入下一个数(-1代表结束):");
scanf("%d",&newnode->data);
if(newnode->data==-1) break;
(*linkp)->link=newnode;
newnode->link=NULL;
linkp=&(*linkp)->link;
}
free(newnode);
}
/*************以头插法建立单链表**************/
//注意linkp永远指向指向头指针的指针,即linkp永远指向head
void front_create(LINKP linkp)
{
NODEP newnode;
printf("请输入第一个数(-1代表结束):");
scanf("%d",&(*linkp)->data);
while((*linkp)->data!=-1)
{
newnode=(NODEP)malloc(sizeof(NODE));
printf("请输入下一个数(-1代表结束):");
scanf("%d",&newnode->data);
if(newnode->data==-1) break;
newnode->link=*linkp;
*linkp=newnode;
}
free(newnode);
}
/*************输出单链表**************/
//注意linkp永远指向指向待输出结点的指针,对于开始linkp指向head
void output(LINKP linkp)
{
int length=0;
while((*linkp)!=NULL)
{
printf("%-4d",(*linkp)->data);
linkp=&(*linkp)->link;
length++;
}
printf("\n");
printf("length=%d\n",length);
}
/***************将一个数插入到升序单链表中,使新的表依然有序******************/
void insert(LINKP linkp,int new_data)
{
NODEP newnode;
while(*linkp!=NULL&&(*linkp)->data<new_data) //注意&&的求值顺序,不要把*linkp放到右边
linkp=&(*linkp)->link;

newnode=(NODEP)malloc(sizeof(NODE));
if(newnode==NULL)
{
printf("插入失败");
exit(1);
}
newnode->data=new_data;
newnode->link=*linkp;
*linkp=newnode;
}
/**************将单链表2接在单链表1的后面*****************/
void lianjielist(LINKP linkp1,LINKP linkp2)
{
while((*linkp1)!=NULL) linkp1=&(*linkp1)->link;
*linkp1=*linkp2;
// free(*linkp2);
}
/*******************合并两个线性表******************/
//已知单链表*linkp1和linkp2的元素按值非递减排列
//合并以上两个单链表得到新的单链表,使的新单链表中的元素也按值非递减排列
void mergelist(LINKP linkp1,LINKP linkp2)
{
NODEP head1,head2;
LINKP p3;
head1=*linkp1;
head2=*linkp2; //head1,head2分别指向链表1,链表2中待比较的元素
p3=linkp1; //用指向单链表1头指针的指针做指向新链表头指针的指针
while(head1&&head2)
{
if(head1->data<=head2->data)
{
*p3=head1;
head1=head1->link;
p3=&(*p3)->link;
}
else
{
*p3=head2;
head2=head2->link;
p3=&(*p3)->link;
}
}
*p3=head1?head1:head2;
}
/*******************销毁链表1******************/
//head1最终等于NULL
void remove_if(LINKP head)
{
NODEP entry;
LINKP curr;
for(curr=head;*curr;)
{
entry=*curr;
//若删除一个结点,执行下面两条语句
*curr=entry->link;
free(entry);
//若不删除一个结点,执行下面一条语句
//curr=&entry->linkp;
}
}






int main()
{
int new_data;
NODEP head1,head2,head3;
head1=init();
head2=init();
head3=init();


printf("***********先是尾接法建立链表1************\n");
rear_create(&head1);
output(&head1);
printf("请输入要插入的值:");
scanf("%d",&new_data);
insert(&head1,new_data);
output(&head1);
printf("***********再是尾接法建立链表2************\n");
rear_create(&head2);
printf("***********将链表2接在链表1后面************\n");
lianjielist(&head1,&head2);
output(&head1);
printf("***********以下为合并算法************\n");
printf("***********先是头插法建立链表1************\n");
front_create(&head1);
output(&head1);
printf("***********再是头插法建立链表2************\n");
front_create(&head2);
output(&head2);
printf("***********二者合并************\n");
mergelist(&head1,&head2);
output(&head1);
printf("***********销毁链表1************\n");
remove_if(&head1);
output(&head1);
return 0;


}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值