链表的创建(单向链表+头插法)

链表的创建

以下介绍内容:节点的产生,访问,插入,删除。
以下涉及内容:结构体 指针 函数 循环 数组 选择等。
  • 创建一个单向链表(含表头节点)
    1.定义节点的结构类型,说明表头指针。
    2.按照结构大小分配·一块内存空间。
    3.将该区域地址赋值给表头指针
    4.继续分配新的内存区域
    5.将新区域的首地址分配给前一个节点的指针变量
    6.重复4和5

  • 在创建之前得了解一下需要得库函数
    stdlib.h 该库函数包括函数malloc,free
    malloc
    原型void * malloc (int size)
    功能 动态分配长度为size个字节得存储区
    返回值 若分配成功则返回该区域得首地址,否则返回0
    因为一般系统返回指向void型数据得指针,故应该用强制类型转换
    例如:
    struct stud *ps; ps = (struct stud *)malloc( sizeof( struct stud));
    接下来是释放内存函数 free( ps )
    ps是指最近一次调用malloc函数的返回值

    具体的创建单向链表过程
  • 调用的库函数

#include <stdio.h>
#include <stdlib.h>
  • 定义节点的结构,说明表头指针
	struct node 
	{
		char name[20];
				struct node *link;//指向结构体本身,也就是指向下一个节点
	} 
	typedef struct node NODE; //给结构体取个别名,typedef
  • 申请存储空间建立表头节点
//这是一个空链表
	NODE *p;
	NODE *head;
    p = (NODE *)malloc (sizeof(NODE));//申请存储这个结构体的空间区域并返回地址给表头节点p
	p -> link =NULL;//将表头节点的link置为NULL
	head = p;//head指向表头节点p
  • 创建新节点
int creat(NODE *head,int n)
{
   NODE *p;
   for(;n>0;n--)
   {
   	p = (NODE *)malloc(sizeof(NODE));
   	gets(p->name);
   	p->link=head->link;//p2->p1 head->p1
   	head->link=p;//head->p2->p1 head->pn...->p1->null 
   }
   return 0;
}
  • 访问链表的全部节点(用头插的话会逆序输出)
	output(NODE *head)
	{
		NODE *p; 
		p=head->link;
		while(p!=NULL)
		{
			puts(p->name);
			p=p->link;
		}
	} 
  • 加个内容 求链表长度(就是求有多少个节点)
	length(NODE *p)
	{
		int len;
		NODE *p;
		for(len=0,p=head->link;p!=NULL;len++)//从头节点开始一直循环到尾节点
		{
			p=p->link;
		}
		return len;
   }
  • 从表头开始将i个数据节点插入链表(头插)
	p = (NODE *)malloc(sizeof(NODE));
    gets(p->name);//需要主函数中提前给定节点p
int insert(NODE *head,NODE *p,int i)//插入到第i个后面 
{
   	NODE *q;int n=0;
   	for( q=head ; n<i&&q->link!=NULL; ++n)
   		q=q->link;//找到第i个节点 
   	p->link=q->link;//例p1->p2,让q->p2 
   	q->link=p;//让p1->q->p2 
   return 0;
}
  • 删除第i个节点
Del( NODE *head,int i)
{
	NODE *q,*p;
	int n=0;
	for( q=head;n<i-1 && q=q->link!=NULL;++n)
		q=q->link;//让q指向第i-1个节点
	if(i>0&&q->link!=NULL)
	{
		p=q->link;//让p指向第i个节点
		q->link=p->link;//将p的link给q的link,就是让第i-1个节点的首地址给第i+1个节点,直接跳过第i个
		free(p);//把被摘掉的链的空间释放
	}

以下是我的测试代码

#include <stdio.h>
#include <stdlib.h>

struct node //定义一个结构体 
{
	char name[20];
	struct node * link;
};
typedef struct node NODE; 
 
 
int main()
{
	NODE *p;
	NODE *head;
	int i,m,n;
	p = (NODE *)malloc(sizeof(NODE));
	p->link=NULL;
	head = p;//head->p->null
	
	
	scanf("%d",&n);//创建新节点
	char c=getchar();
	int creat(NODE *head,int n);
	creat(head,n);
	
	scanf("%d",&i);//插入新节点
	char d=getchar();
	p = (NODE *)malloc(sizeof(NODE));
	gets(p->name);
	int insert(NODE *head,NODE *p,int i);
	insert(head,p,i);
	
	int output(NODE *head);//访问全部链表
	output(head);

	scanf("%d",&m);//删除任意位置的节点
	char e=getchar();//这是为了吸收scanf缓冲区里的回车
	int Del(NODE *head,int m);
	Del(head,m);
	
	output(head);//访问删除之后的链表
	
	return 0;
}
int creat(NODE *head,int n)//
{
	NODE *p;
	for(;n>0;n--)
	{
		p = (NODE *)malloc(sizeof(NODE));
		gets(p->name);
		p->link=head->link;//p2->p1 head->p1
		head->link=p;//head->p2->p1 head->pn...->p1->null 
	}
	return 0;
}
int output(NODE *head)
{
	NODE*p;
	p=head->link;//p指向p1 
	while(p!=NULL)
	{
		puts(p->name);
		p=p->link;//p1->p2...->null
	}
	return 0;
}
int insert(NODE *head,NODE *p,int i)//插入到第i个后面 
{
		NODE *q;int n=0;
		for( q=head ; n<i&&q->link!=NULL; ++n)
			q=q->link;//找到第i个节点 
		p->link=q->link;//例p1->p2,让q->p2 
		q->link=p;//让p1->q->p2 
	return 0;
}
int Del(NODE *head,int m)
{
	NODE *p,*q;
	int n=0;
	for(q=head;n<m-1&&q->link!=NULL;++n)
		q=q->link;
	if(m>0&&q->link!=NULL)
	{
		p=q->link;
		q->link=p->link;
		free(p);
	}
}

2019/12/10 19:25

发布了21 篇原创文章 · 获赞 5 · 访问量 751

猜你喜欢

转载自blog.csdn.net/weixin_45862170/article/details/103464500