链表目的:
- 实现数组的功能
- 节省内存占用
建立链表
1 逆序建立
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
int main()
{
int i,n;
struct node *head,*p,*q;
scanf("%d",&n);
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;//定义头指针并指向null
for(i=0;i<n;i++)
{
p=(struct node*)malloc(sizeof(struct node));
scanf("%d",&p->data);
p->next=NULL;//上述三行目的是建立新节点,本行必须有,在判断链表末尾的时候用得到
p->next=head->next;//将头节点后面的节点先接到p上
head->next=p;//再把头节点与p接在一起
}
q=head->next;//用q新指针访问head的指针域
while(q!=NULL)//查看head后面有没有连接节点如果有那么q!=NULL
{
printf("%d",q->data);//输出q的数据
q=q->next;//将q指向下一个节点
}
return 0;
}
2 顺序建立
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
int main()
{
int i,n;
struct node *head,*p,*tail,*q;
scanf("%d",&n);
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;//先创造一个头节点
tail=head;//让尾指针指向head
for(i=0;i<n;i++)
{
p=(struct node*)malloc(sizeof(struct node));
scanf("%d",&p->data);
p->next=NULL;//创建一个新节点
tail->next=p;//让尾指针的指针域指向新节点
tail=p;//然后把指针移动到新节点上
}
q=head->next;
while(q!=NULL)
{
if(q->next==NULL)
printf("%d ",q->data);
else printf("%d ",q->data);
q=q->next;
}//这个输出方式网上抄的也行
return 0;
}
3 输出链表
struct node *p;
p=head->next;//将新的指针p指向head
while(p!=NULL)//如果头指针的指针域有下一个节点
{
printf("%d ",p->data);//先输出下一节点的数据
if(p->next!=NULL)//判断再下一个节点的指针域是不是有节点
printf(" ");//有就输出空格
else printf("\n");//否则换行结束
p=p->next;
}
4 节点的建立
1 q=(struct node*)malloc(sizeof(struct node));
q->data=s;
q->next=NULL;
2 q=(struct node*)malloc(sizeof(struct node));
scanf("%d",&p->data);
q->next=NULL;
5 节点的连接
q=(struct node*)malloc(sizeof(struct node));
q->data=s;
q->next=NULL;
q->next=p->next;//从此开始,先将p后面的节点连接到新节点q上
这样就保证了后面链表中的数据不会丢失
p->next=q;//再将q连接在p后面
5 链表的逆置
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
void creat()//建表部分
{
struct node *p,*q;
q=head;
int m;
while(scanf("%d",&m)!=EOF)
{
if(m==-1)break;
p=(struct node*)malloc(sizeof(struct node));
p->data=m;
p->next=NULL;
q->next=p;
q=p;
}
}
void process()//处理部分
{
struct node *p,*q;
p=head->next;//让p指向第一个元素
q=p->next;//让q指向第二个元素
head->next=NULL;//将头结点与链表断开
while(p)//判断的是p的指针域若不是NULL就执行
{
printf("b\n");
p->next=head->next;//将head后面的元素链接到p的后面,当然
第一次head后面没有元素而是NULL,第二次的时候head后面就是第一个元素
head->next=p;//将p链接到head后面
p=q;//让p指向下一项即q的位置
if(q)//判断q的后面是否还有元素
q=q->next;//如果有就让其指向下一个元素
}
}
void print()输出部分
{
struct node *p;
p=head->next;
while(p)
{
printf("%d",p->data);
if(p->next!=NULL)
printf(" ");
else printf("\n");
p=p->next;
}
}
int main()
{
head=(struct node *)malloc(sizeof(struct node));
head->next=NULL;
creat();
process();
print();
return 0;
}
6 链表的归并
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head1,*head2;
void creat(int n,struct node *head)//传入不同的链表节数和不同的头指针
{
struct node *p,*q;
int i;
q=head;
for(i=1;i<=n;i++)
{
p=(struct node*)malloc(sizeof(struct node));
scanf("%d",&p->data);
p->next=NULL;
q->next=p;
q=p;
}
}
void process()//处理部分
{
struct node *p,*q,*t;
p=head1->next;//让p指向head1,用于访问head1后面的元素
q=head2->next;//让q指向head2,用于访问head2后面的元素
t=head1;//让t也指向head1,t用来链接元素
free(head2);//因为要合并,所以保留一个head1,将head2释放掉
while(q&&p)//判断p和q的指针域
{
if(p->data>q->data)//判断p的大小把较小的连接到head上
{
t->next=q;
t=q;
q=q->next;
}
else
{
t->next=p;
t=p;
p=p->next;
}
}
if(p)//这里是将多余的不参与比较的部分连接到归并链表后面
{
t->next=p;
}
else
{
t->next=q;
}
}
void print()//输出部分
{
struct node*p;
p=head1->next;
while(p)
{
printf("%d",p->data);
if(p->next!=NULL)
printf(" ");
else printf("\n");
p=p->next;
}
}
int main()
{
int m,n;
head1=(struct node *)malloc(sizeof(struct node));
head2=(struct node *)malloc(sizeof(struct node));
head1->next=NULL;
head2->next=NULL;
scanf("%d %d",&m,&n);
creat(m,head1);
creat(n,head2);
process();
print();
return 0;
}
7 链表的指针
结构体作为自定义的数据结构,创建后系统只能返回整个结构体的首地址,所以只能用一个指针来接
8 双向链表的双向输出
void print()
{
struct node*p,*q;
p=head->next;
while(p)
{
printf("%d",p->data);
if(p->next!=NULL)
{
printf(" ");
}
else printf("\n");
q=p;//在最后一项的时候先让q指向最后一项的last域
p=p->next;
}
while(q)//判读元素的指针域
{
printf("%d",q->data);
if(q->last!=NULL)
{
printf(" ");
}
else printf("\n");
if(q->last!=head)//如果把这一行与while中的判断条件互换则最终会少输出一个元素。
q=q->last;
else break;
}
}
9 循环链表的应用
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node*head;
void creat(m)
{
int i;
struct node*p,*q;
q=head;
for(i=1;i<=m;i++)
{
p=(struct node*)malloc(sizeof(struct node));
p->data=i;
p->next=NULL;
q->next=p;
q=p;
}
q->next=head->next;
}
void process(m)
{
struct node *p;
int i;
p=head;
while(p->next!=p)
{
for(i=1;i<=m-1;i++)
{
p=p->next;
}
p->next=p->next->next;
}
printf("%d\n",p->data);
}
int main()
{
int n,m;
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
scanf("%d %d",&n,&m);
creat(n);
- List item
process(m);
return 0;
}
关于链表的指针
- 结构体指针与普通指针的区别。
1 结构体指针指向结构体,可以指向数据域(int,double...),可以指向
指针域(struct node *)
2 普通指针只能指向已经规定好的数据类型的数据。
哪里有不对的地方评论改正谢谢