单链表的实现

本文介绍了单链表的概念,强调了链表在频繁插入和删除操作时的优势,并提供了单链表的C语言实现,包括初始化、插入、删除、查找、打印等操作。示例代码展示了如何创建、修改和遍历链表。
摘要由CSDN通过智能技术生成
 
/* *******************************************************************************
用链接存储方式存储的线性表——链表,可以克服顺序表的插入与删除时间复杂度为O(n)缺点。
但其获知表长与访问元素的时间复杂度O(n)较顺序表O(1)比较变差了
比较适合频繁进行插入与删除操作,访问操作较少的情况
链表中的结点用存储单元来存放,
一个结点对应一个存储单元,存储单元之间既可以是(空间上)连续的,也可以是不连续的,
甚至可以零散分布在存储空间中的任何位置。
链表中结点的逻辑次序和物理次序未必一致。 
为了能正确表示结点之间的逻辑关系,一个存储单元除了存放每个结点值data 以外,
还必须存有其后继结点的地址信息,这个信息被称为指针,记为next . 
因此,一个链表结点应由两个域构成:数据域与下一个结点的指针域
链表的第一个结点被称为头结点,指向头结点的指针被称为头指针。
链表的最后一个结点被称为尾结点
验证一个结点是否是表尾,只须考察该结点的next域值是否为NULL(空指针)。 
以下为单链表的实现
************************************************************************************* */
#ifndef LINKLIST_H
#define LINKLIST_H
#define INFINITY 65535
typedef int ElemType; //单链表的数据类型,自定义

typedef struct node{ //链表结点
	ElemType data; //数据域
	struct node *next; //指针域
}LinkNode,*LinkList;

void InitList(LinkList *l); //初始化单链表
void InsertList(LinkList l,int i,ElemType e); //在单链表的第i个位置插入元素e
void DeleteList(LinkList l,int i,ElemType *e); //删除单链表的第i个位置的元素,把删除的元素存入*e
int LocateElem(LinkList l,ElemType e); //在链表中查找元素e,找到返回位置,未找到返回-1
void GetElem(LinkList l,int i,ElemType *e); //返回链表中第i个位置的元素,存入*e
void Print(LinkList l); //打印链表
void Push_front(LinkList l,ElemType e); //倒序插入元素
void Push_back(LinkList l,ElemType e); //正序插入元素
void DestroyList(LinkList l); //清空链表
#endif //LINKLIST;

#include "LinkList.h"
#include <stdio.h>
#include <stdlib.h>
void InitList(LinkList *l) //初始化链表
{
	(*l) = (LinkList)malloc(sizeof(LinkNode)); //初始化l指向表头结点
	(*l)->next = NULL; //初始化表头结点的指针为NULL
}
void InsertList(LinkList l,int i,ElemType e) //在链表的第i个位置插入元素e
{
	LinkList p = l->next; //初始化p指向第一个结点
	int j = 1;
	while(p && j < i - 1) //使p成为要插入位置的前一个结点
	{
		p = p->next;
		++j;
	}
	if(!p)
	{
		printf("超出范围插入失败\n");
		return;
	}
	else 
	{
		LinkList temp = (LinkList)malloc(sizeof(LinkNode)); //分配一个新结点
		temp->data = e; //将要插入的元素赋值给新结点的数据域
		temp->next = p->next; //使新结点的指针域指向p的指针域所指向的位置
		p->next = temp; //使p的指针域指向新结点
	}
}
void DeleteList(LinkList l,int i,ElemType *e) //删除第i个位置的结点,将结点的数据赋值给*e
{
	LinkList p = l->next;
	int j = 1;
	while(p && j < i - 1) //移动到要删除的结点的前一个结点
	{
		p = p->next;
		++j;
	}
	if(p) //如果p不为NULL进行删除
	{
		LinkList temp = p->next; //使temp指向要删除结点
		p->next = temp->next; //使p->next指向要删除的结点的下一个结点
		*e = temp->data;
		free(temp); //删除结点
	}
}
void GetElem(LinkList l,int i,ElemType *e) //将第i个元素的位置存入*e
{
	LinkList temp = l->next;
	int j = 1;
	while(temp && j < i)
	{
		temp = temp->next;
		++j;
	}
	if(temp)
		*e = temp->data;
	else
		*e = INFINITY; //β值表示无穷大
}
int LocateElem(LinkList l,ElemType e) //在链表内查找元素e,如果找到返回所在位置,未找到返回-1
{
	int i = 0;
	LinkList p = l->next;
	while(p) //遍历链表
	{
		++i;
		if(p->data == e) //如果找到返回所在的位置
			return i;
		p = p->next;
	}
	return -1; //否则返回-1;
}
void Print(LinkList l) //打印链表
{
	LinkList p = l->next;
	while(p)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}
void Push_front(LinkList l,ElemType e) //倒序插入元素
{
	LinkList temp = (LinkList)malloc(sizeof(LinkNode)); //创建新结点
	temp->data = e; //将新结点的数据域初始化为e
	temp->next = l->next; //新结点的指针域指向头结点所指向的结点
	l->next = temp; //头结点指向新结点
}
void Push_back(LinkList l,ElemType e) //正序插入元素
{
	static LinkList order = l;
	LinkList temp = (LinkList)malloc(sizeof(LinkNode)); //创建新结点
	temp->data = e;
	temp->next = order->next;
	order->next = temp;
	order = order->next; //使order一直指向最后一个结点
}
void DestroyList(LinkList l) //清空链表
{
	while(l)
	{
		LinkList temp = l;
		l = l->next;
		free(temp);
	}
}

#include "LinkList.h"
#include <stdio.h>
int main()
{
	LinkList l;
	InitList(&l); //初始化链表
	for(int i = 1;i < 20;i += 2)
		Push_back(l,i);
	printf("链表的元素为:\n");
	Print(l);

	printf("在第11个位置插入元素:22,插入后的链表元素为:\n");
	InsertList(l,11,22);
	Print(l);

	printf("在第5个位置删除元素后的链表为:\n");
	int e;
	DeleteList(l,5,&e);
	Print(l);
	printf("被删除的元素为:%d\n",e);

	printf("链表第7个位置的元素为: ");
	GetElem(l,7,&e);
	printf("%d\n",e);
	int k = 13;
	if((e = LocateElem(l,k)) != -1)
		printf("在链表的第%d个位置找到元素%d\n",e,k);
	else
		printf("在链表的中未找到元素:%d\n",k);

	DestroyList(l); //销毁链表
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值