单链表
- 特点
1.单链表的初始化
LinkList Initlist()//单链表的初始化函数
{
Linklist head;
head=(Node*)malloc(sizeof(Node));
head->next=NULL;
return head;
}
2.单链表的建立
在头部插入新节点建立单链表
(1)有头节点
void CreatByHead(LinkList head)//头插法创建单链表
{
Node*s;
char name[20];
int number;
head->next=NULL;
printf("请输入学生的姓名和学号:\n");
while(1)
{
scanf("%s",name);
scanf("%d",number);
if(number==0)
break;
s=(Node*)malloc(sizeof(Node));
strcpy(s->name,name);
s->number=number;
s->next=head->next;
head->next=s
}
}
本质上就是在头结点之后插入新结点
(2)无头节点
LinkList creatbyhead1(LinkList head)//头插法(无结点)
{
int number;
char name[20];
LinkList s;
while(1)
{
scanf("%s",name);
scanf("%d",&number);
if(number==0)
break;
s=(Node*)malloc(sizeof(Node));
strcpy(s->name,name);
s->number=number;
s->next=head;
head=s;
}
return head;
}
本质上是在head(第一个结点而非头结点)之前插入结点
- 在单链表的尾部插入新结点
(1)有头点
LinkList creatnodebyrear(LinkList head)//尾插法
{
int number;
char name[20];
LinkList r,s;
r=head;
while(1)
{
printf("请输入信息,名字和序号:\n");
scanf("%s",name);
scanf("%d",&number);
if(number==0)
break;
s=(Node*)malloc(sizeof(Node));
s->number=number;
strcpy(s->name,name);
r->next=s;
r=s;
}
r->next=NULL;
}
(2)无头结点
LinkList creatlist2()//尾插法(无头结点)
{
LinkList head=NULL;
int number;
char name[20];
LinkList r,s;
printf("请输入序号和姓名");
while(1)
{
scanf("%d",&number);
scanf("%s",name);
if(number==0)
break;
s=(Node*)malloc(sizeof(Node));
strcpy(s->name,name);
s->number=number;
s->next=NULL;
if(head==NULL)
{
head=s;
}
else
{
r->next=s;
}
r=s;
}
return head;
}
四种建立单链表的完整代码
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
}Node,*LinkList;
void CreatListByRear(LinkList head)//有头节点的尾插法
{
Node *r,*s;
r=head;
int n;
printf("输入数据的个数:\n");
scanf("%d",&n);
printf("要输入的数据:\n");
while(n--)
{
s=(Node*)malloc(sizeof(Node));
scanf("%d",&s->data);
r->next=s;
r=s;
}
r->next=NULL;
}
LinkList CreatListByRear1(LinkList head)//没有头节点的尾插法
{
Node *r,*s;
head=NULL;
int n;
printf("输入数据的个数:\n");
scanf("%d",&n);
printf("要输入的数据:\n");
while(n--)
{
s=(Node*)malloc(sizeof(Node));
scanf("%d",&s->data);
s->next=NULL;
if(head==NULL)
{
head=s;
r=head;
}
else
{
r->next=s;
r=s;
}
}
return head;
}
CreatListByHead(LinkList head)//有头节点的头插法
{
Node *r,*s;
int n;
head->next=NULL;
printf("输入数据的个数:\n");
scanf("%d",&n);
printf("要输入的数据:\n");
while(n--)
{
s=(Node*)malloc(sizeof(Node));
scanf("%d",&s->data);
s->next=head->next;
head->next=s;
}
}
LinkList CreatListByHead1(LinkList head)//不带头节点的头插法
{
Node *r,*s;
head=NULL;
int n;
printf("输入数据的个数:\n");
scanf("%d",&n);
printf("要输入的数据:\n");
while(n--)
{
s=(Node*)malloc(sizeof(Node));
scanf("%d",&s->data);
s->next=head;//与带头节点的不同就在于head->next改为head即可
head=s;
}
return head;
}
InputList(LinkList head)//输出
{
Node *p;
p=head;//无头结点
//p=head->next;//有头节点
printf("存入数据为:\n");
while(p)
{
printf("%d ",p->data);
p=p->next;
}
}
int main()
{
LinkList L1;
L1=(Node*)malloc(sizeof(Node));
//CreatListByRear(L1);尾插法有头节点
//L1=CreatListByRear1(L1); 尾插法无头节点
L1=CreatListByHead1(L1);// 头插法有头节点
InputList(L1);
}
3.单链表的删除
void deletenode(LinkList head,int pos)//删除结点(有头节点)
{
int j=0;
LinkList p,q;
p=head;
if(j<pos-1&&p)
{
p=p->next;
j++;
}
if(p==NULL||p->next==NULL)
printf("Error!");
else
{
q=p->next;
p->next=q->next;
free(q);
}
}
4.不带头结点的单链表
-
不带头结点单链表的插入
-
插入链表的首位置
- 新节点的指针s指向首结点head 再让s成为新head
-
其他位置与带头结点的一样
LinkList Delete(LinkList head,int i) { int j=1; Node *p,*q; if(i==1) { q=head; head=head->next; free(q); } else { while(j<i-1&&p) { p=p->next; j++; } if(p==NULL||p->next==NULL) if(p) { q=p->next; p->next=q->next; free(q); } } return head; }
-
- 不带头结点单链表的删除
-
删除链表的首结点
- 把让q指向head 再让head指向第二个结点成为新节点 free((q)) 这种情况需要返回新头指针
-
其他位置与带头结点相同
LinkList Insert(LinkList head,int i) { Node *s; Node *p; s=(Node*)malloc(sizeof(Node)); scanf("%s",s->name); scanf("%d",s->number); int j=1; Node *p; if(i==1) { s->next=head; head=s; } else { while(j<i-1&&p) { p=p->next; j++; } if(p) { s->next=p->next; p->next=s; } } return head; }
5.单链表的应用
- 5.1单链表的逆置
struct node2 *reverselink(struct node2 *head)
{
Node *pfirst,*pmid,*plast;
pfirst=head;
pmid=head->next;
plast=head->next->next;
if(head==NULL)
return NULL;
pmid->next=pfirst;
pfirst->next=NULL;
pfirst=pmid;
pmid=plast;
plast=plast->next;
while(plast)
{
pmid->next = pfirst;
pfirst=pmid;
pmid=plast;
plast=plast->next ;
}
pmid->next =pfirst;
return pmid;
}
6.数组模拟链表
//两个数组模拟链表
#include<stdio.h>
int main()
{
int a[101],s[101];
int n,t;
int x,i,j,len;
printf("存入数据的个数:\n");
scanf("%d",&n);
len=n+1;
printf("存入的数据:");
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<n;i++)
{
s[i]=i+1;
}
s[n]=0;
printf("要加入的数据:");
scanf("%d",&x);
a[len]=x;
t=1;
while(t!=0)
{
if(a[s[t]]>x)
{
s[len]=s[t];
s[t]=len;
break;
}
t=s[t];//实现递推
}
t=1;//让t重新归1
while(t!=0)
{
printf("%d ",a[t]);
t=s[t];//递推
}
}
本文详细介绍了单链表的基本操作,包括有头节点和无头节点的初始化、头插法与尾插法建立单链表、节点的删除以及单链表的逆置。此外,还探讨了不带头节点的单链表插入和删除的实现。这些内容对于理解和操作链表数据结构至关重要。
5759

被折叠的 条评论
为什么被折叠?



