C关于链表的那些事情~(创、查、改、增)

C关于链表的那些事情

链表可是c的重头戏!!!惊讶惊讶惊讶为啥说他很重要,首先他包括的方面很重要,他包括了C的指针老大和结构体。想必指针的地位不用我来多说吧!!!指针因为太灵活了,所以可以使用的方面有很多,而链表则将他和结构体结合在一起,是更难了嘛!!!答案是错误的!!!敲打敲打敲打其实结构体就是一种数据的集合,将一些数据集合在一个群体里面,并没有很难理解的东西,而指针则是给每个结构体提供指向的,这样所形成的数据就成为一种链状的结构,所以称为链表!!!(下面我将一个链表解析下来,具体给大家讲述一下链表的具体形态)

//链表的创建区域(链表由指针和结构体组成)
struct student				//此时该结构体就类似一个节点,节点包括姓名和年龄
{
	char name[20];
	int age;
	student *next;			//定义一个结构体指针指向下一个节点
};
在上面的程序是链表创建的第一步骤,首先你必须有个容器来容纳你的数据,而那个数据结构就是结构体!

其实数据啥的都不是重点,他只是暂时存在那个位置而已!关键是将他们链接在一起的指针,将每个数据集合串联起来看起来就像珠串一样,所以叫链表!
现在要进行数据的输入了,很简单跟结构体赋值一样,但是要将每个数据连接起来,因为他们是拴在一根绳子上的蚂蚱,这个要敲重点!!!
//数据的插入区域
	student c={"xiaoyu",28,NULL};				//不能用[]这个符号
	student b={"xiaozhu",27,&c};				//等会要将小猪删除
	student a={"xiaoling",23,&b};
	student *head=&a;			//头指针,指向a
上面就是将数据一个个输入的,定义一个head指针直接指向a数据域,其实理解一下就是将a当作head了,head指向的也是有数据的,而不是一个空的头,然后一个个连接起来,记得最后的指向要置为空因为你没有位置给他了,所以只利用 NULL将他置空,让他不要乱跑!!!

既然数据已经都搞定了,我们现在要实现一个正常对链表的操作问题吧!
首先就是查找数据的问题:
//链表的查找功能
	student *cpointer=head;      //建立一个指针指向头节点
	cout<<"查找姓名为xiaoyu的年龄:"<<endl;
	while(cpointer)				//遍历链表
	{
		if(strcmp(cpointer->name,"xiaoyu"))
		{
			cout<<"找到此人年龄为:"<<cpointer->age<<endl;
			break;				//跳出循环
		}
		cout<<cpointer->name<<","<<cpointer->age<<endl;	//输出节点里面的信息
		cpointer=cpointer->next;							//指针指向下一个节点
	}
		if(cpointer==NULL)
		{
			cout<<"没有此人"<<endl;
		}
既然它是利用链表将他一个链接起来,我们遍历他的时候肯定也需要一个可以移动的指针是吧!所以定义一个
student *cpointer=head;  //定义一个学生结构体类型的指针cpointer指向他的头指针,然后一个个遍历数据

(这里补充要提一下strcmp函数,这个函数是用来比较两个字符或者字符串是否一样的,如果一样返回0如果不一样前面大的话返回正值,后面大的返回一个负值)但是如果没有找到这个人呢,我们肯定也要机器返回一个值来告诉我们结果,所以用了if条件语句判断是否查找到最后的一个值,如果是的话指针指向NULL则没有此人。

查找结束后,就需要增加数据了,增加数据的话你必须先创造一个数据出来,不能平白无故产生数据!!!
/*待插入的数据如下*/
student d={"xiaodong",27,NULL}; //为什么也给他赋一个空值呢,因为不知道他的位置在哪里暂时先放着
就要先产生如上的一个数据,但是他的指向还是未知的,通过插入功能将数据插入。
//链表的插入功能(实现插入需要两个指针来执行操作)
	student *before=head;			//插入需要建立两个指针,可以都指向第一个位置
	student *pointer=before->next;		//第二个指针指向第一个数据域
	while(before)//遍历链表
	{
		if(strcmp(before->name,"xiaozhu")==0)	//strcmp函数的作用是比较两个字符串的大小,相同的话等于0
		{
			d.next=pointer;	//第一步
			before->next=&d;//第二步将d的首地址赋给before的下一个地址
			break;
		}
		before=before->next;			//两个指针都实现了移动
		pointer=pointer->next;			//都移动相同的距离
	}
	if(pointer==NULL)
	{
		cout<<"没有找到该学生无法插入!!!"<<endl;
	}
//显示插入的结果,我要将数据插到xiaozhu后面。
	pointer=head;
	cout<<"将数据插入后的结果:"<<endl;
	while(pointer)
	{
		cout<<pointer->name<<","<<pointer->age<<endl;
		pointer=pointer->next;
	}
切记,插入和删除都需要两个指针。而且断开要链表有个致命的点,不要将链表切断后再插入,因为一个链表本来就
是根据指针链接在一起的,如果强行先切断联系后这个链表后面的数据哪里去找地址存储呢,要将插入的数据先插到后一个数据的头位置,然后再断开,不然后面的数据全部缺少关联。(给你们画个图理解一下)

一定要有先后顺序哦!!!(图二那个×是切断的意思)

最后一共功能就是删除的功能!!!
//链表的删除功能(同样也需要两个指针来运行,单个指针不行,头节点不能删除掉,因为删除了就没了)
	student *ibefore=head;		//插入需要建立两个指针,可以都指向第一个位置
	student *ipointer=ibefore->next;
	while(ipointer)//遍历链表
	{
		if(strcmp(ipointer->name,"xiaoyu")==0)		
		{
			ibefore->next=ipointer->next;				
			break;
		}
		ibefore=ipointer;
		ipointer=ipointer->next;
	}
	if(ipointer==NULL)
	{
		cout<<"没有该数据无法删除!!!"<<endl;
	}
同样的需要两个指针,没毛病!!! 得意 得意 得意但是简单一点,不需要那么麻烦了。直接将.next指针跳到要删除的数据的下一个数据这里不做图示了。(作用就是将该数据屏蔽掉,直接跳过他的位置)
贴一下全部的源码:
// 链表的初始学习.cpp : 定义控制台应用程序的入口点。
//
//利用链表创建三个学生的信息,学生信息包括信息和年龄
#include "stdafx.h"
#include<iostream>
using namespace std;


//链表的创建区域(链表由指针和结构体组成)
struct student				//此时该结构体就类似一个节点,节点包括姓名和年龄
{
	char name[20];
	int age;
	student *next;			//定义一个结构体指针指向下一个节点
};
//链表的创建区域


int _tmain(int argc, _TCHAR* argv[])
{
//数据的插入区域
	student c={"xiaoyu",28,NULL};				//不能用[]这个符号
	student b={"xiaozhu",27,&c};				//等会要将小猪删除
	student a={"xiaoling",23,&b};
	student *head=&a;			//头指针,指向a
	/*待插入的数据如下*/
	student d={"xiaodong",27,NULL}; //为什么也给他赋一个空值呢,因为不知道他的位置在哪里暂时先放着


//链表的查找功能
	student *cpointer=head;      //建立一个指针指向头节点
	cout<<"查找姓名为xiaoyu的年龄:"<<endl;
	while(cpointer)				//遍历链表
	{
		if(strcmp(cpointer->name,"xiaoyu"))
		{
			cout<<"找到此人年龄为:"<<cpointer->age<<endl;
			break;				//跳出循环
		}
		cout<<cpointer->name<<","<<cpointer->age<<endl;	//输出节点里面的信息
		cpointer=cpointer->next;							//指针指向下一个节点
	}
		if(cpointer==NULL)
		{
			cout<<"没有此人"<<endl;
		}

	

	
//链表的插入功能(实现插入需要两个指针来执行操作)
	student *before=head;				//插入需要建立两个指针,可以都指向第一个位置
	student *pointer=before->next;		//第二个指针指向第一个数据域
	while(before)//遍历链表
	{
		if(strcmp(before->name,"xiaozhu")==0)		//strcmp函数的作用是比较两个字符串的大小,相同的话等于0
		{
			d.next=pointer;	//第一步
			before->next=&d;//第二步将d的首地址赋给before的下一个地址
			break;
		}
		before=before->next;			//两个指针都实现了移动
		pointer=pointer->next;			//都移动相同的距离
	}
	if(pointer==NULL)
	{
		cout<<"没有找到该学生无法插入!!!"<<endl;
	}
//显示插入的结果,我要将数据插到小猪后面。
	pointer=head;
	cout<<"将数据插入后的结果:"<<endl;
	while(pointer)
	{
		cout<<pointer->name<<","<<pointer->age<<endl;
		pointer=pointer->next;
	}



//链表的删除功能(同样也需要两个指针来运行,单个指针不行,头节点不能删除掉,因为删除了就没了)
	student *ibefore=head;		//插入需要建立两个指针,可以都指向第一个位置
	student *ipointer=ibefore->next;
	while(ipointer)//遍历链表
	{
		if(strcmp(ipointer->name,"xiaoyu")==0)		
		{
			ibefore->next=ipointer->next;				
			break;
		}
		ibefore=ipointer;
		ipointer=ipointer->next;
	}
	if(ipointer==NULL)
	{
		cout<<"没有该数据无法删除!!!"<<endl;
	}
//删除成功结果显示,我将b给删除了。	
	pointer=head;
	cout<<"将数据删除后的结果:"<<endl;
	while(pointer)
	{
		cout<<pointer->name<<","<<pointer->age<<endl;
		pointer=pointer->next;
	}


//将链表中所有元素输出的功能,我将它注释掉了,不过原理很简单(没啥好说的)
	/*pointer=head;
	while(pointer)
	{
		cout<<pointer->name<<","<<pointer->age<<endl;
		pointer=pointer->next;
	}*/
	return 0;
}




总结一下:链表就是这样的一个数据集合,没有其他的功能。数组其实有些的性质跟它也差不多,各有各的优点,关键看如何使用。
附(数组与链表关系图,各有各的优点嘛,关键要用的好)





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值