创建链表的三种算法(C语言实现)——正向、逆向、递归

链表分为静态链表和动态链表,本文主要讨论动态链表的创建。

静态链表是用两个数组模拟一个链表,其中一个数组中存实际数据,可以称之为数据数组。另一个数组中存数据数组中各元素的下标,我们称之为地址数组(注意地址数组中存的并不是地址值,而是整形的数)。静态数组的好处是避免了指针的操作,不足之处是占用了较多的存储空间。

静态链表不是本文讨论的重点,下面主要讨论创建动态链表的三个常用算法。

这里链表每个节点中的数据域以一个int型的数据为例,并且数据是通过数组传入,而不是用户直接输入的。

此外,本文只是说明创建链表的方法,创建成功之后无法再次在链表中加入节点。


创建链表的方法大致有三种:

1.正向创建链表:最容易理解,即为每次在链表末尾插入一个节点。

2.逆向创建链表:即为每次在原链表的头结点之前插入一个节点。

3.递归创建链表:递归创建链表的特点在于,递归调用时申请空间并对数据域赋值,递归返回时挂链。所以创建出来的是一个逆向的链表。


#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
	int data;
	struct Node *next;
}ElemSN;

ElemSN* CreatLink1(int data[],int n);//正向(尾插法)创建无表头链表
ElemSN* CreatLink2(int data[],int n);//逆向(头插法)创建无表头链表
ElemSN* CreatLink3(int data[],int n);//递归法创建链表

void PrintLink(ElemSN *h);//正向输出链表的数据
void DeleteLink(ElemSN *h);//删除链表 
int main(void)
{
	ElemSN *head1=NULL,*head2=NULL,*head3=NULL;
	int data[8]={3,2,5,8,4,7,6,9};
	head1=CreatLink1(data,8);//正向(尾插法)创建无表头链表
	PrintLink(head1);
	head2=CreatLink2(data,8);//逆向(头插法)创建无表头链表
	PrintLink(head2);
	head3=CreatLink3(data,8);//递归法创建链表
	PrintLink(head3);
	DeleteLink(head1);//删除链表 
	DeleteLink(head2);
	DeleteLink(head3);
	return 0;
}

ElemSN* CreatLink1(int data[],int n)//正向(尾插法)创建无表头链表
{
	ElemSN *h=NULL,*p=NULL,*t=NULL;
	int i;
	for(i=0;i<n;i++){
		p=(ElemSN *)malloc(sizeof(ElemSN));
		p->data=data[i];
		p->next=NULL;
		if(h==NULL){
			t=h=p;
		}
		t=t->next=p;
	}
	return h;
}
ElemSN* CreatLink2(int data[],int n)//逆向(头插法)创建无表头链表 
{
	ElemSN *h=NULL,*p=NULL;
	int i;
	for(i=n-1;i>=0;i--){
		h=(ElemSN *)malloc(sizeof(ElemSN));
		h->data=data[i];
		if(!h){//if(h==NULL)
			p=h;
			h->next=NULL;
		}
		h->next=p;
		p=h;
	}
	return h;
}
ElemSN* CreatLink3(int data[],int n)//递归法创建链表
{
	ElemSN *p=NULL;
	if(n==0)
		return NULL; 
	p=(ElemSN *)malloc(sizeof(ElemSN));
	p->data=data[n-1];	
	p->next=CreatLink3(data,n-1);
	return p;
}

void PrintLink(ElemSN *h)//正向输出链表的数据 
{
	ElemSN *p=NULL;
	for(p=h;p!=NULL;p=p->next){
		printf("%4d",p->data);
	}
	printf("\n链表输出结束!\n");
}

void DeleteLink(ElemSN *h)//删除链表
{
	ElemSN  *delp=NULL,*q=NULL;
	delp=h->next;
	h->next=NULL;
	while(delp!=NULL){
		q=delp->next;
		free(delp);
		delp=q;
	} 
} 



C语言中,利用链表结构来建立人事管理系统是一个常见的应用,因为它允许动态地添加、删除和查找员工信息,而不需要预先设定固定大小的数据结构。下面简要概述一下如何使用链表构建一个基础的人事管理系统: 1. **定义数据结构**:首先,创建一个包含员工基本信息的数据结构,如`struct Employee`,包括字段如ID、姓名、职位、入职日期等。 ```c typedef struct Employee { int id; char name[50]; char position[50]; date_t hire_date; // 其他相关信息... } Employee; ``` 2. **链接列表**:创建一个`Node`结构,用于存储单个员工,并有指向下一个节点的指针`next`。 ```c typedef struct Node { Employee employee; struct Node* next; } Node; ``` 3. **初始化链表**:设计一个全局链表变量`head`作为列表的起点,初始时为NULL。 4. **添加员工**:编写函数`addEmployee()`来插入新员工到链表头部,如果需要,还可以提供其他位置插入的功能。 5. **删除员工**:编写`deleteEmployee()`函数,通过遍历链表找到指定ID的员工并移除。 6. **查找员工**:实现`findEmployee()`函数,根据员工ID搜索链表并返回匹配的员工信息。 7. **显示链表内容**:为了管理,可以创建一个函数`displayEmployees()`遍历整个链表并打印所有员工的信息。 8. **输入/输出操作**:处理用户输入,获取员工信息或修改信息,然后更新链表
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值