初学链表(菜鸟的链表入门)
1.静态链表
#include<stdio.h>
#define NULL 0
struct student
{
int num;
float score;
struct student *next;
};
void main()
{
struct student a,b,c,*head,*p;
a.num=1001;a.score=82.5;
b.num=1002;b.score=90.5;
c.num=1003;c.score=78.5;
head=&a; //头指针放第一个结点a的地址
a.next=&b;b.next=&c;c.next=NULL;
p=head; //p从头指针开始向后遍历
do
{
printf("\t%d\t%.lf\n",p->num,p->score);
p=p->next; //p向下一个结点
}while(p!=NULL);
}
2.malloc函数
p=(struct student *)malloc(sizeof(struct student ))
表示申请struct student类型长度的空间,并把该空间的起始地址赋给p
P=(int *)malloc(5*sizeof(int)) 分配一块长度为5个int’型数据大小的内存空间,并把该空间的起始地址赋给p
3.动态链表
#include<stdio.h>
#include<malloc.h>
#define NULL 0
struct student
{
int num;
float score;
struct student *next;
};
int n=0;
链表的建立
struct student *creat(void)
{
struct student *head,*p1,*p2;
head=NULL;
p1=p2=(struct student *)malloc(sizeof(struct student)); //p1,p2同时指向第一个结点
scanf("\t%d,%f",&p1->num,&p1->score);
while(p1->num!=0) //学号为0停止循环
{
n=n+1; //计数
if(n==1) //若p1所指为头结点
head=p1;
else
p2->next=p1; //否则令表尾指向p1
p2=p1; //p2指向新结点
p1=(struct student *)malloc(sizeof(struct student)); //申请新结点,让p1指向它
scanf("%d,%f",&p1->num,&p2->score); //输入新结点数据
}
p2->next=NULL; //表尾结点指向为空
free(p1);
return(head);
}
删除链表的结点
struct student *del(struct student *head,int num)
{
struct student *p1,*p2;
if(head==NULL) //链表为空时的情况
{
printf("\n the list is NULL\n");
return(head);
}
p1=head; //p1指向第一个结点
while(p1->num!=num&&p1->next!=NULL) //p1所指既不是要删的结点也不是尾节点时
{
p2=p1; //p2向后移动一个结点(到p1位置)
p1=p1->next; //p1向后移动一个结点
}
if(p1->num==num) //找到要删除的结点
{
if(p1==head) //若为第一个结点
head=p1->next;
else //若不是第一个结点
p2->next=p1->next;
free(p1);
printf("delete:%d\n",num);
n=n-1; //结点数减一
}
else
printf("%d is not been found \n",num); //找不到该结点
return(head);
}
插入链表结点
struct student *insert(struct student *head,struct student *stud)
{
struct student *p0,*p1,*p2;
p1=head; //p1指向第一个结点
p0=stud; //p0表示要插入的结点
if(head==NULL)
{ //若原链表为空
head=p0;
p0->next=NULL;
}
else
{
while((p0->num>p1->num)&&(p1->next!=NULL)) //新结点数据大于当前结点,且当前结点不是尾节点
{
p2=p1; //p2后移
p1=p1->next; //p1后移
}
if(p0->num<=p1->num) //若新结点数据小于当前结点
{
if(head==p1) //若p1为头结点
head=p0; //放在p1之前
else
p2->next=p0; //放在p2之后
p0->next=p1; //新结点next指向当前结点
}
else
{
p1->next=p0; //新结点插到尾节点之后
p0->next=NULL;
}
}
n=n+1; //结点数加一
return(head);
}
4.例题:
- 构建一个动态链表,输入一系列整数,输入0表示结束,输入指定节点的序号及新整数,在该结点前插入这个新整数,输出插入后的链表。
输入要求:每行输入一个整数,输入0表示结束,然后输入节点序号和新整数,每个数字独占一行
输出要求:输出插入后的链表,数字之间用空格隔开
样例输入:
1
2
3
4
5
0
3
9
样例输出:1 2 9 3 4 5
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct number)
struct number
{
int num;
struct number *next;
};
int main()
{
int n;
struct number newNumber,*head,*p0,*p1,*p2,*p;
head = NULL;
p1 = p2 =(struct number *)malloc(LEN);
scanf("%d",&p1->num);
head = p1;
p1 = (struct number *)malloc(LEN);
scanf("%d",&p1->num);
while(p1->num != 0)
{
p2->next = p1;
p2 = p1;
p1 = (struct number *)malloc(LEN);
scanf("%d",&p1->num);
}
p2->next = NULL;
free(p1);
scanf("%d",&n);
scanf("%d",&newNumber.num);
p0 = &newNumber;
p2 = head;
//插入新节点
if(n==1) //如果是头结点则直接插入
{
p0->next=p2;
head=p0;
}
else
{
while(n-2!=0) //没到位置则移动p2
{
p2=p2->next;
n--;
}
p1=p2->next; //p0插入p2与p1之间
p2->next=p0;
p0->next=p1;
}
//
p = head;
while(p != NULL)
{
printf("%d ",p->num);
p = p->next;
}
return 0;
}
- 构建一个动态链表,输入一系列整数,输入0表示结束,将该链表逆置,即原链头作新链尾,原链尾作新链头,输出新的链表。
输入要求:每行输入一个整数,输入0表示结束
输出要求:输出逆序后的链表元素,数字之间用空格隔开
样例输入:
1
2
3
4
5
0
样例输出:5 4 3 2 1
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct number)
struct number{
int num;
struct number *next;
};
int main()
{
struct number *head,*p1,*p2,*p3,*p;
head = NULL;
p1 = p2 =(struct number *)malloc(LEN);
scanf("%d",&p1->num);
head = p1;
p1 = (struct number *)malloc(LEN);
scanf("%d",&p1->num);
while(p1->num != 0)
{
p2->next = p1;
p2 = p1;
p1 = (struct number *)malloc(LEN);
scanf("%d",&p1->num);
}
p2->next = NULL;
free(p1);
p1 = head;
p2 = p3 =NULL;
//将该链表逆置
while(p1!=NULL)
{
p2=(struct number*)malloc(LEN); //每次开创一个新空间
p2->num=p1->num; //这个新空间先存当前结点的值
p2->next=p3; //当前p2的下一个为前一个开创的新空间,即p3
p3=p2; //p3移动到当前的新空间
p1=p1->next; //移动p1
}
//
p = p3;
while(p != NULL)
{
printf("%d ",p->num);
p = p->next;
}
return 0;
}
- 建立两个动态链表,将一系列整数输入其中,输入0表示结束,再将两个链表连接起来,并按数据值升序排列后输出。
输入要求:每行输入一个整数,输入0表示结束,进行两次
输出要求:输出满足要求的链表元素,数字之间用空格隔开
样例输入:
1
9
5
0
8
2
4
0
样例输出:1 2 4 5 8 9
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct number)
struct number{
int num;
struct number *next;
};
struct number *create()
{
struct number *head,*p1,*p2;
head = NULL;
p1 = p2 =(struct number *)malloc(LEN);
scanf("%d",&p1->num);
head = p1;
p1 = (struct number *)malloc(LEN);
scanf("%d",&p1->num);
while(p1->num != 0)
{
p2->next = p1;
p2 = p1;
p1 = (struct number *)malloc(LEN);
scanf("%d",&p1->num);
}
p2->next = NULL;
free(p1);
return head;
}
int main()
{
struct number *h1,*h2,*cur,*tail,*p;
int temp;
h1 = create();
h2 = create();
p = h1;
while(p->next != NULL)
{
p = p->next;
}
p->next = h2; //h1尾部与h2相连
cur=h1; //令新链表头为cur
tail=NULL;
while(cur!=tail)
//将两个链表连接起来,并按数据值升序排列
{
p=cur->next; //p是cur的下一个,用来与cur比较
while(p!=NULL) //寻找cur的按大小排序的下一个
{
if(p->num<cur->num) //冒泡
{
temp=p->num;
p->num=cur->num;
cur->num=temp;
}
p=p->next; //p移动
}
cur=cur->next; //cur移动
}
//
p = h1;
while(p != NULL)
{
printf("%d ",p->num);
p = p->next;
}
// printf("\n");
return 0;
}
- 构建一个动态链表,输入一系列正整数,输入0表示结束,删除链表中数据值相等的所有节点,只保留最前面的一个,将筛选后的链表输出。
输入要求:每行输入一个正整数,输入0表示结束
输出要求:输出筛选后的链表数据,数字之间用空格隔开
样例输入:
2
2
1
1
3
3
5
2
0
样例输出:2 1 3 5
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct number)
struct number{
int num;
struct number *next;
};
int main()
{
struct number *head,*p1,*p2,*p3,*p4,*p;
head = NULL;
p1 = p2 =(struct number *)malloc(LEN);
scanf("%d",&p1->num);
head = p1;
p1 = (struct number *)malloc(LEN);
scanf("%d",&p1->num);
while(p1->num != 0)
{
p2->next = p1;
p2 = p1;
p1 = (struct number *)malloc(LEN);
scanf("%d",&p1->num);
}
p2->next = NULL;
free(p1);
p2 = head;
//删除链表中数据值相等的所有节点
while(p2!=NULL)
{
p3=p2->next;
p4=p2;
while(p3!=NULL) //通过移动p3来判断下一个结点与当前p2是否相等
{
if(p3->num==p2->num) //若相等则跳过该结点
{
while(p4->next!=p3) //p4移动
p4=p4->next;
p4->next=p4->next->next;
}
p3=p3->next;
}
p2=p2->next; //移动p2,之后循环删除链表中与下一个数相同的结点
}
//
p = head;
while(p != NULL)
{
printf("%d ",p->num);
p = p->next;
}
printf("\n ");
return 0;
}