初学链表

初学链表(菜鸟的链表入门)

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.例题:

  1. 构建一个动态链表,输入一系列整数,输入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;
}

  1. 构建一个动态链表,输入一系列整数,输入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;
}

  1. 建立两个动态链表,将一系列整数输入其中,输入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;
}

  1. 构建一个动态链表,输入一系列正整数,输入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;
}

发布了10 篇原创文章 · 获赞 7 · 访问量 337

猜你喜欢

转载自blog.csdn.net/weixin_44026026/article/details/103414653