单向链表的实现(初级)

1.笔者最近在学习数据结构中的链表,有了不少收获和思考,故来分享给大家,链表是线性表的一种,又称链式存储结构。相比于顺序表来讲,操作较为复杂,与顺序表各有利弊,因为链式存储才用的是动态内存存储方式,故在空间上的灵活性较高,可以避免一些空间上的浪费和重新分配,在做插入和删除的时候,比顺序表更加快速,但在访问元素的时候,需要依次向后遍历,导致时间上的开销较大。

 

                                                     

2.链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

3.问题描述,实现一些链表的基本操作。

 

4.下面会介绍一种利用尾插法实现的单向链表,闲话少说,上代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define ERROR 0
#define OK 1

typedef char ElemType;
typedef struct LNode {
	ElemType data;//数据域
	int length;
	struct LNode* next;//指针域
}LNode, * Linklist;//链表结点,LinkList是LNode*型的指针类型

//函数的声明
void Init_list(Linklist L);//初始化链表,构建一个空链表
void Print_length_elem(Linklist L);//输出链表的元素和长度
void Delete_list(Linklist L, int i);//删除链表第i个元素
void insert_list(Linklist L, int i, char f);//在第i个位置插入一个结点e
int Find_index_list(Linklist L, int i);//按照位置查找结点
int Find_elem_list(Linklist L, ElemType e);//按值查找
void CreatLL_H(Linklist L, int length);//(length)要创建的链表的长度,头插法实现
void CreatLL_R(Linklist L, int Length);//(length)是要创建的链表的长度尾插法实现
void Find_delete_elem(Linklist L, int i);//查找单链表上第i个元素
//如果在,则删除,如果不在,则输出找不到
void FreeLL(Linklist L);//释放单链表


//函数定义 
//初始化单链表
void Init_list(Linklist L)
{
	if (!L) {
		exit(0);//内存申请失败
	}
	else {
		;
	}
	L->next = NULL;//头结点指针域置为空
	L->length = 0;//链表长度置为0

}

//尾插法创建单链表
void CreateLL_R(Linklist L, int length)
{
	printf("Please input elem!\n");

	int i = 0;
	Linklist ptail;
	ptail = L;//头指针,最初指向头节点
	for (i = 0; i < length; i++) {
		Linklist pnew;
		pnew = (Linklist)malloc(sizeof(LNode));//申请存储空间
		ElemType data;
		scanf("%c", &data);
		ptail->next = pnew;
		pnew->data = data;
		pnew->next = NULL;//尾插法无后继,指针域置为空
		ptail = pnew;//向右移动一位,方便下一次插入
	}
}

//打印单链表节点数
void Print_length_elem(Linklist L)
{
	Linklist pnow;
	pnow = L->next;
	int Linklen = 0;
	if (!pnow) {
		printf("单链表为空!\n");
	}
	else {
		;
	}
	while (pnow) {
		printf("%c", pnow->data);//输出链表元素
		pnow = pnow->next;
		Linklen++;
	}
	L->length = Linklen;
	printf("\n单链表的长度(结点数)是%d", Linklen);//输出链表长度
}

//删除链表中第i个元素
void Delete_list(Linklist L, int i)
{
	LNode* p;//结点指针
	p = L->next;//首先存储第一个结点的地址
	int j = 1;
	//找到第i-1个结点,将指针p指向第i-1个结点
	while (p && j < i - 1) {
		p = p->next;
		++j;
	}
	if (!p || i < 1) {
		return ERROR;
	}
	else {
		p->next = p->next->next;
	}


}
//插入元素
void insert_list(Linklist L, int i, char f)
{
	Linklist p;
	p = L->next;
	Linklist F;
	F = (Linklist)malloc(sizeof(LNode));
	Linklist s = F;
	int j = 1;
	//找到第i-1结点,使结点指针p指向第i-1个元素
	//p->next指向的是第i个元素(插入前)
	while (p && j < i - 1) {
		p = p->next;//结点指针移动
		++j;
	}
	if (!p || i < j) {
		return ERROR;
	}
	else {
		s->next = p->next;
		s->data = 'f';
		p->next = s;
	}
	printf("\n插入元素的后继元素是%c", F->next->data);//test测试一下后继是否正确
}

//查找单链表第i个元素,若不在,则输出找不到,若在则将其删除
void Find_delete_elem(Linklist L, int index)
{
	Linklist ptail;
	Linklist p_delete;
	int i = 0;
	ptail = L;//指向头节点
	if (index > ptail->length) {
		printf("Find None!\n");
		return ERROR;
	}
	for (i = 0; i < index - 1; i++) {
		ptail = ptail->next;
	}//找到第index-1个元素,让ptail指向它
	p_delete = ptail->next;
	ptail->next = p_delete->next;
	printf("\n要删除的结点的data是%c", p_delete->data);
	free(p_delete);
	p_delete = NULL;

}

//按下标查找
int Find_index_list(Linklist L, int i)
{
	Linklist p;
	int j = 1;
	p = L->next;
	while (p && j < i) {
		p = p->next;
		++j;
	}
	if (!p || i < j) {
		return ERROR;//报错
	}
	else {
		printf("\n第%d个结点处的data是:%c", i, p->data);
		return OK;
	}

}

//按值查找
int Find_elem_list(Linklist L, ElemType e) {
	Linklist p;
	p = L->next;
	int index = 1;
	while (p) {
		if (p->data == e) {
			printf("\n存放%c的是第%d个结点", e, index);
			return index;
		}
		index++;
		p = p->next;
	}
	if (!p) {
		printf("\n找不到!");
		return ERROR;
	}
}

//释放单链表
void FreeLL(Linklist L)
{

	Linklist pnow;
	pnow = (Linklist)malloc(sizeof(LNode));
	while (pnow) {
		Linklist ptail;
		ptail = pnow;
		pnow = pnow->next;
		free(ptail);
		ptail = NULL;
	}
	L = NULL;
}

int main(void)
{
	Linklist L;
	Linklist F;
	L = (Linklist)malloc(sizeof(LNode));
	F = (Linklist)malloc(sizeof(LNode));
	Init_list(L);
	CreateLL_R(L, 4);//为保证是正序,这里使用尾插法实现单链表的创建
	Print_length_elem(L);
	Find_index_list(L, 3);
	char t_1 = 'a';
	Find_elem_list(L, t_1);
	char t_2 = 'f';
	insert_list(L, 4, t_2);
	Find_delete_elem(L, 3);
	FreeLL(L);
	return 0;
}

5.结语:本文主要介绍了单向链表的基本代码实现,欢迎小伙伴们来一起学习。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值