c语言之单链表简单操作

C语言之--单链表的基本操作

          最近在学习有关单链表的增删改查,这块的代码不是很好理解,所以自己也找了些视频看,以自己的理解敲出了以下几个代码。链表和数组一样都是为了存储一串数据,但是数组在使用前要定义其数组长度,会造成空间的浪费,而且数组的增删也极其不方便。所以创建链表是为了在需要时动态申请内存,而且其增删也方便很多。

一、链表的创建

          创建链表有俩种方式,一种是头插法,一种是尾插法,俩种方法大同小异,在此我介绍尾插法。用图示的方法很好理解。
         
         上图是链表的示意图,first是链表的头指针,它指向首结点的首地址。每一个结点里都有两个部分,一个数据域,一个指针域,指针域存放下一个结点的地址,用来连接每一个结点使其链表创建成功。
下面是用尾插法创建链表的代码:
struct student
{
 char name[20];
 int score;
 struct student *next;//指向本结构体的指针类型
};
int n;//记录存放数据数目
struct student *create()
{
 struct student *head;
 struct student *p1,*p2;
 p1=p2=(struct student *)malloc(sizeof(struct student));//分配动态内存
 printf("please put in the name:\n");
 scanf("%s",p1->name);
 printf("please put in the score:\n");
 scanf("%d",&p1->score);
 head=NULL;n=0;
 //创建开始
 while(p1->score!=0)
 {
  n++;
  if(n==1) head=p1;
  else p2->next=p1;
  p2=p1;
  p1=(struct student *)malloc(sizeof(struct student));
  printf("please put in the name:\n");
  scanf("%s",p1->name);
  printf("please put in the score:\n");
  scanf("%d",&p1->score);
 }
 p2->next=NULL;
 return head;
}//创建过程结束


这里声明了两个指针变量p1和p2,不断地用p1指向新的结点,紧跟着p2=p1,再用p1指向p2的next,以此往复,直至NULL,链表就建成了。

二、链表的遍历

          这里用到了print函数,其功能就是将数据进行输出。代码如下:
void print(struct student *head)
{
	struct student *p;//临时指针
	p=head;//把头指针赋给p
	if(p)
	{
		do
		{
			printf("%s成绩为:%d\n",p->name,p->score);
			p=p->next;
		}while(p);//当p不为空时
	}
}

      这里的输出是比较简单的,然后整个链表的创建输出就完成了,只要在主函数里调用它们就行了。接下来我们说说链表的插入与删除。

三、链表的插入

     插入有三种方式:头插,中间插和尾插。头插和尾插的思想都比较简单,大家可以自己思考一下,在此我只介绍中间插入法。它就是使得要插入的结点与其前一个和后一个结点相连,它的代码如下:
struct student *insert(struct student *head,int inumber)
{
	struct student *p=head,*p1;
	while(p&&p->number!=inumber) p=p->next;//inumber为要在其后插入数据的学号
	p1=(struct student *)malloc(sizeof(struct student));
	printf("please put in the number:\n");
	scanf("%d",&p1->number);
	printf("please put in the score:\n");
	scanf("%d",&p1->score);
	p1->next=p->next;
	p->next=p1;
	n++;
	return head;	
}

记得在主函数中要先调用这个函数再进行输出。

四、链表的删除

          链表的删除和插入都是同一个思路,使要删除的前一个结点与要删除的之后的那个结点连在一起,具体的代码如下:
void Delete(struct student *head,int iIndex) 
{
	int i;
	struct student *p;
	struct student *pre;//删除的结点的前一个结点
	p=head;
	pre=p;
	printf("删除第%d个学生\n",iIndex);
	for(i=1;i<iIndex;i++)
	{
		pre=p;
		p=p->next;
	}
	pre->next=p->next;
	n--;
}

这个要遍历找到要删除的结点,时间复杂度为o(n),大家可以想想怎样能不遍历就能删除这个结点,使其时间复杂度为o(1).
emmm,今天链表的介绍就到这里,感兴趣的同学可以自己敲敲看。

猜你喜欢

转载自blog.csdn.net/wangaiji/article/details/80028428
今日推荐