链表基础

主要写给自己看,欢迎指错,看了四五天才看出点头绪。很菜!

为什么要使用链表?

在知乎看到了一个比较好的例子:

举个生活中的例子,你上学的时候要站队升国旗,一列纵队,一人一个按顺序从0开始的编号。这就是数组。万一有一天,你们来了一个插班生,要站在队伍中间,那么他后面的人就要重新编号(全都+1),这就比较麻烦了因为要重新编号,最坏情况是所有都要重编。
但是我们如果试着用另外一种方式去记录位置,每个人只要记住他后面那个人的名字。那么每一次站队的时候,只要知道队首那个人,然后队首的小明一喊,我后面的是小黄,然后小黄就过来,小黄知道后面的是小黑,然后小黑就过来,直到所有人都找好位置。如果有一个人,小白插进来,比如小黄和小黑之间,我们只要和小黄说,你后面现在要改成小白,小白你后面是小黑。这样只要两个步骤就可以了。

总的来说,有些操作在数组中操作比较麻烦,而链表则可以方便的执行

 

 

 

 

下面,分步实现比较好理解(受知乎某答主启发)

①定义链表单个节点的数据结构

#include <iostream>
struct student
{
	int score;
	student *next;
};
int main()
{
	student p;
	p.score=60;
}

②用指针实现

#include <iostream>
struct student
{
	int score;
	student *next;
};
int main()
{
	student *p;
	p->score=60;
}

③使用指针前动态分配空间

#include <iostream>
#include <malloc.h>
struct student
{
	int score;
	student *next;
};
int main()
{
	student *p;
	p=(student*)malloc(sizeof(student));//需要头文件 
	p->score=60;
}

 ④实现两个节点的串联(链表本就是佛珠一样的,一个连着一个)

#include <iostream>
#include <malloc.h>
struct student
{
	int score;
	student *next;
};
int main()
{
	student *p1,*p2;
	p1=(student*)malloc(sizeof(student));//需要头文件 
	p1->score=60;
	p2=(student*)malloc(sizeof(student));
	p2->score=70;
        p1->next=p2;//第一个节点指向第二个
}

⑤增加链表最后一个节点的结束标志(NULL)

#include <iostream>
#include <malloc.h>
struct student
{
	int score;
	student *next;
};
int main()
{
	student *p1,*p2;
	p1=(student*)malloc(sizeof(student));//需要头文件 
	p1->score=60;
	p2=(student*)malloc(sizeof(student));
	p2->score=70;
	p1->next=p2;//第一个节点指向第二个节点
	p2->next=NULL;//在p2时指向NULL(空/0)结束 
}

⑥ 添加头指针

#include <iostream>
#include <malloc.h>
struct student
{
	int score;
	student *next;
};
int main()
{
	student *head; //添加头指针 
	student *p1,*p2;
	p1=(student*)malloc(sizeof(student));//需要头文件 
	p1->score=60;
	p2=(student*)malloc(sizeof(student));
	p2->score=70;
	p1->next=p2;//第一个节点指向第二个节点
	p2->next=NULL;//在p2时指向NULL(空/0)结束 
	head=p1;//指向第一个节点 
}

⑦利用循环进行n个节点的信息存储

#include <iostream>
#include <malloc.h>
using namespace std;
struct student
{
	int score;
	student *next;
};
int main()
{
	student *head; 
	student *p1,*p2;
	int n;
	cin>>n;
	head=NULL;
	for(int i=0;i<n;i++)
	{
		p1=(student*)malloc(sizeof(student));//执行一次开一个动态空间
		cin>>p1->score;//存储信息
		if(head==NULL)//判断是否为空链表
		{
			head=p1;
			p2=p1;
		}
		else//循环指向,个人认为较难理解
		{
			p2->next=p1;
			p2=p1;
		}
	}
	p2->next=NULL;//结束
	
}

⑧存储之后,当然是输出了

 

#include <iostream>
#include <malloc.h>
using namespace std;
struct student
{
	int score;
	student *next;
};
int main()
{
	student *head; 
	student *p1,*p2;
	int n;
	cin>>n;
	head=NULL;
	for(int i=0;i<n;i++)
	{
		p1=(student*)malloc(sizeof(student));
		cin>>p1->score;
		if(head==NULL)
		{
			head=p1;
			p2=p1;
		}
		else
		{
			p2->next=p1;
			p2=p1;
		}
	}
	p2->next=0;
	//下面为输出代码
	student *p;
	p=head;
	while(p!=NULL)
	{
		cout<<p->score<<endl;
		p=p->next;
	} 
	
}

⑨然后是链表节点的删除

 

#include <iostream>
#include <malloc.h>
using namespace std;
struct student
{
	int score;
	student *next;
};
int main()
{
	student *head; 
	student *p1,*p2;
	int n;
	cin>>n;
	head=NULL;
	for(int i=0;i<n;i++)
	{
		p1=(student*)malloc(sizeof(student));
		cin>>p1->score;
		if(head==NULL)
		{
			head=p1;
			p2=p1;
		}
		else
		{
			p2->next=p1;
			p2=p1;
		}
	}
	p2->next=0;
	//节点删除代码
	p1=head;
	while(p1->score!=60)//删除score为60的节点,当然这里与上面的存储有关,视情况更改数据即可 
	{
		p2=p1;
		p1=p1->next;
	}
	p2->next=p1->next;
	delete p1; 
	//下面为输出代码
	student *p;
	p=head;
	while(p!=NULL)
	{
		cout<<p->score<<endl;
		p=p->next;
	} 
	
}

⑩ 其他的还有插入节点,新增节点等功能,暂时不会。。。。

下面附一段较为完整的代码,此代码转自他人!!!!!(纯手打!)

//
//实现链表的基本操作
//
#include <stdio.h>
#include <malloc.h>

struct node//链表上的数据结构
{
	int data;
	node *next;
};

node *Create(void)//产生一条无序链表 
{
	node *p1,*p2,*head;//p2指向最后一个节点,p1指向插入节点 ,head指向头节点、 
	int a;
	head=0;
	printf("产生一条无序链表,请输入数据,以-1结束:\n");
	scanf("%d",&a);
	while(a!=-1)//1,3,2,4,-1
	{
		p1=(node*)malloc(sizeof(node));
		p1->data=a;
		if(head==0)//插入链表首部
		{
			head=p1;
			p2=p1;
		}
		else// 插入表尾
		{
			p2->next=p1;
			p2=p1;
		}
		scanf("%d",&a); 
	}	
	if(head)
	{
		p2->next=0;
	}
	return (head);
}
void Print(node *head)//输出各节点数据
{
	node *p;
	p=head;
	printf("链表上各节点的数据为:\n");
	while(p!=0)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
node *Delete_one_node(node *head,int num)//根据数值删除对应节点
{
	node *p1,*p2;
	if(head==0)
	{
		printf("链表为空,无节点可删除!\n");
		return 0;
	}
	if(head->data==num)//删去首节点 
	{
		p1=head;
		head=head->next;
		free((void*)p2);//释放节点空间 
		printf("删除了一个节点!\n");
	}
	else
	{
		printf("未找到要删除的节点!\n");
	}
	return head;
 } 
 node *Insert(node *head,node *p)//将一个节点插入链表中
 {
 	node *p1,*p2;
 	if(head==0)//空链表,插入链表首节点 
 	{
 		head=p;
 		p->next=0;
 		return head;
	}
	if(head->data>=p->data)//非空链表,插入到链表首节点
	{
		p->next=head;
		head=p;
		return head;
	}
	p2=p1=head;
	while(p2->next&&p2->data<p->data)//找到要插入的位置
	{
		p1=p2;
		p2=p2->next;
	}
	if(p2->data<p->data)//插入链表尾
	{
		p2->next=p;
		p->next=0;
	}
	else//插入在p1和p2所指向的节点之间
	{
		p->next=p2;
		p1->next=p;
	}
	return head;
}
node *Create_sort(void)//产生一条有序链表
{
	node *p1,*head=NULL;
	int a;
	printf("产生一条有序链表,请输入数据,以-1结束:\n");
	scanf("%d",&a);
	while(a!=-1)
	{
		p1=(node*)malloc(sizeof(node));//产生一个新的节点
		p1->data=a;
		head=Insert(head,p1);//将新节点插入表中
		scanf("%d",&a); 
	}
	return head;
}
void deletechain(node *head)//释放各节点占用的内存
{
	node *p1;
	while(head)
	{
		p1=head;
		head=head->next;
		free((void*)p1);
	}
}

int main()
{
	node *head;
	int num;
	head=Create();//产生一条无序链表   1,3,2,5,-1 
	Print(head);//输出各节点数据
	printf("输入要删除节点上的整数:\n");
	scanf("%d",&num);
	head=Delete_one_node(head,num);//删除链表上具有指定的节点  2,1 
	Print(head);
	node *p1=(node*)malloc(sizeof(node));
	p1->data=4;
	head=Insert(head,p1);//将新节点插入链表中
	Print(head);
	deletechain(head);//释放整个链表的节点空间 
	head=Create_sort();//产生一条有序链表   1,3,2,5,-1 
	Print(head);
	deletechain(head);//释放各节点空间 
	return 0; 
 } 

 吐槽:链表真tmd难。。

 

 

 

 

 

 

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值