1.3.1单链表表示
单链表数据域:用与存放元素本身信息。
指针域:存放其后继结点的存储位置。最后一个元素没有后继,其指针不指向任何结点,称为空指针。
定义一个单链表假设llist是一个单链表的头指针,为LinkList,其存储结构如下:
struct Node; //单链表结构类型
typedef struct Node *PNode; //节点指针类型
struct Node{
int info;
PNode link;
};
typedef struct Node *LinkList; //单链表类型
存储结构图
设llist是一个单链表的头指针,为LinkList,其存储结构如下:
1.3.2 单链表代码实现
2.1 创建空链表
LinkList creatNullList(void){
LinkList llist=(LinkList)malloc(sizeof(struct PNde));
if(llist!-Null) llist->link=NULL;
else printf("溢出1!\n");
return llist;
}
2.2 判空
int isNullList(LinkList llist){ //llist指向的头结点非空
return(llist->link==NULL); //所以判断带头节点的单链表是否为空链表只要看llist->Link是否为空
}
2.3 求某元素的储存位置
PNode locate(LinkList llist,int x){ //查找下标为x的第一个元素
PNode r;
if(llist==NULL) return NULL; //链表为空
r=llist->link;
while(r!=NULL&&r->info!=x)
p=p->link;
return r; //返回下标为x的第一个元素
}
2.4插入元素
在带头文件的单链表中,欲在r所指的结点后插入值为x的结点。如图,先申请一个结点空间,赋值x。然后,将ki-1与k断开,新结点存放ki存储位置。最后,ki存放新结点存储位置。
int insertQ(LinkList llist,PNode r,int x){ //在r所指结点后插入x
PNode s=(PNode)malloc(sizeof(struct Node)); //申请新结点空间
if(s==NULL){
printf("溢出2!\n");
return 0;
}
else{
s->info=x; //赋值x
s->link=r->link; //新结点存放r后结点存储位置
r->link=q; //r结点存放新结点存放位置
return 1;}
}
2.5 求r所指结点前驱结点
PNode locateQ(LinkList llist,PNode r){ //求r所指结点前驱结点
PNode s;
if(llist==NULL) return NULL;
s=llist;
while(s!=NULL&&s->link!=p){
s=s->link;
}
return s;
}
2.6删除结点
在带头结点的单链表中删除第一个元素值为x的结点。首先从第一个结点开始,依次找出数据域与x相同的结点,将其前驱结点的存储位置记录在指针q中,然后通过指针变量修改语句p->link=p->link->link。
int delet(LinkList llist,int x){ //删除第一个值为x的结点
PNode r,s;
r=llist;
if(r==NULL) return 0; //单链表为空
while(r->link!=NULL&&r->link->info!=x) //查找值为x的结点的前驱结点的存储位置
r=r->link;
if(r->link==NULL){ //查找到最后一个元素
printf("不存在!\n");
return 0;
}
else{
s=r->link;
r->link=r->link->link; //删除值为x的结点
free(s);
return 0;
}
}
2.7输入输出代码
int input(LinkList llist){
PNode r=llist;
int x;
printf("请输入结点个数:\n");
scanf("%d",&llist->info);
for(int i=0;i<llist->info;i++){
PNode s=(PNode)malloc(sizeof(struct Node)) ;
if(s==NULL){
printf("结点分配失败!\n");
return -1;
}
printf("请输入结点元素:\n");
scanf("%d",&x);
s->info=x;
s->link=NULL;
r->link=s;
r=s;
}
r->link=NULL;
return 0;
}
void output(LinkList llist){
PNode r=llist->link;
while(r!=NULL){
printf("%d ",r->info);
r=r->link;
}
}
2.8测试代码
void text(LinkList llist){
int m;
LinkList llist1;
llist=creatNullList();
if(isNullList(llist));
printf("创建成功!\n");
printf("请输入最大结点个数:\n");
scanf("%d",&m);
input(llist);
output(llist);
printf("\n");
int x;
printf("请输入想查储存位置的结点的值");
scanf("%d",&x);
PNode p= locate(llist,x);
if(p!=NULL){
printf("%d\n",p->link);
}
else printf("不存在值为x的结点\n");
printf("在r所指结点后插入值为x的新结点\n");
printf("输入r: ") ;
int y;
scanf("%d",&y);
PNode r_insert=locate(llist,y);
if(r_insert!=NULL){
int z;
printf("输入想插入新结点的值x: ");
scanf("%d",&z);
insertQ( llist, r_insert,z);
output(llist);
}
else {printf("没有找到r所指结点\n");
}
printf("求r所指结点的前驱结点\n");
int x1;
printf("输入r所指结点");
scanf("%d",&x1);
PNode r1=locate(llist,x1);
if(r1!=NULL){
PNode r2=locateQ(llist,r1);
if(r2!=NULL){
printf("前驱结点是:%d\n",r2->info);
}
}
printf("删除第一个值为x的结点");
int x3;
scanf("%d",&x3);
delet(llist,x3);
output(llist);
}
2.9完整代码
#include <stdio.h>
#include<stdlib.h>
struct Node; //单链表结构类型
typedef struct Node *PNode; //节点指针类型
struct Node{
int info;
PNode link;
};
typedef struct Node *LinkList; //单链表类型
LinkList creatNullList(void){
LinkList llist=(LinkList)malloc(sizeof(struct Node));
if(llist!=NULL) llist->link=NULL;
else printf("溢出1!\n");
return llist;
}
int isNullList(LinkList llist){ //llist指向的头结点非空
return(llist->link==NULL); //所以判断带头节点的单链表是否为空链表只要看llist->Link是否为空
}
PNode locate(LinkList llist,int x){ //查找下标为x的第一个元素
PNode r;
if(llist==NULL) return NULL; //链表为空
r=llist->link;
while(r!=NULL&&r->info!=x)
r=r->link;
return r; //返回下标为x的第一个元素
}
int insertQ(LinkList llist,PNode r,int x){ //在r所指结点后插入x
PNode s=(PNode)malloc(sizeof(struct Node)); //申请新结点空间
if(s==NULL){
printf("溢出2!\n");
return 0;
}
else{
s->info=x; //赋值x
s->link=r->link; //新结点存放r后结点存储位置
r->link=s; //r结点存放新结点存放位置
return 1;}
}
PNode locateQ(LinkList llist,PNode r){ //求r所指结点前驱结点
PNode s;
if(llist==NULL) return NULL;
s=llist;
while(s!=NULL&&s->link!=r){
s=s->link;
}
return s;
}
int delet(LinkList llist,int x){ //删除第一个值为x的结点
PNode r,s;
r=llist;
if(r==NULL) return 0; //单链表为空
while(r->link!=NULL&&r->link->info!=x) //查找值为x的结点的前驱结点的存储位置
r=r->link;
if(r->link==NULL) { //查找到最后一个元素
printf("不存在!\n");
return 0;
}
else {
s=r->link;
r->link=s->link; //删除值为x的结点
free(s);
return 1;
}
}
int input(LinkList llist){
PNode r=llist;
int x;
printf("请输入结点个数:\n");
scanf("%d",&llist->info);
for(int i=0;i<llist->info;i++){
PNode s=(PNode)malloc(sizeof(struct Node)) ;
if(s==NULL){
printf("结点分配失败!\n");
return -1;
}
printf("请输入结点元素:\n");
scanf("%d",&x);
s->info=x;
s->link=NULL;
r->link=s;
r=s;
}
r->link=NULL;
return 0;
}
void output(LinkList llist){
PNode r=llist->link;
while(r!=NULL){
printf("%d ",r->info);
r=r->link;
}
}
int main()
{ int m;
LinkList llist;
llist=creatNullList();
if(isNullList(llist));
printf("创建成功!\n");
printf("请输入最大结点个数:\n");
scanf("%d",&m);
input(llist);
output(llist);
printf("\n");
int x;
printf("请输入想查储存位置的结点的值");
scanf("%d",&x);
PNode p= locate(llist,x);
if(p!=NULL){
printf("%d\n",p->link);
}
else printf("不存在值为x的结点\n");
printf("在r所指结点后插入值为x的新结点\n");
printf("输入r: ") ;
int y;
scanf("%d",&y);
PNode r_insert=locate(llist,y);
if(r_insert!=NULL){
int z;
printf("输入想插入新结点的值x: ");
scanf("%d",&z);
insertQ( llist, r_insert,z);
output(llist);
}
else {printf("没有找到r所指结点\n");
}
printf("求r所指结点的前驱结点\n");
int x1;
printf("输入r所指结点");
scanf("%d",&x1);
PNode r1=locate(llist,x1);
if(r1!=NULL){
PNode r2=locateQ(llist,r1);
if(r2!=NULL){
printf("前驱结点是:%d\n",r2->info);
}
}
printf("删除第一个值为x的结点");
int x3;
scanf("%d",&x3);
delet(llist,x3);
output(llist);
return 0;
}