单链表的12个基本操作

单链表的12个基本操作

定义常量

/*一些经常用到的头文件,预定义常量等*/
//常用头文件
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
//函数结果状态代码
#define TRUE	1
#define FALSE	0
#define OK		1
#define ERROR	0
#define INFEASIBLE	0
//新建函数类型,表示函数运行结果
typedef int Status;

结构体定义与函数声明

/*动态单链表的结构体定义*/ 
//定义结构体
typedef int ElemType;
typedef struct LNode
{
	ElemType data;	//数据域
	struct LNode* next;	//指针域
}LNode, *LinkList;

/*动态单链表的12个基本操作和2个辅助函数声明*/
Status InitList(LinkList* L);
Status DestoryList(LinkList* L);
Status ListEmpty(LinkList L);
Status ClearList(LinkList L);
int ListLength(LinkList L);
Status GetElem(LinkList L, int i, ElemType* e);
int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));
Status PriorElem(LinkList L, ElemType cur_e, ElemType* pre_e);
Status NextElem(LinkList L, ElemType cur_e, ElemType* next_e);
Status ListInsert(LinkList L, int i, ElemType e);
Status ListDelete(LinkList L, int i, ElemType* e);
Status ListTraverse(LinkList L, Status (*visit)(ElemType));

Status compare(ElemType x, ElemType y);
Status visit(ElemType); 

函数定义

/*动态单链表的12个基本操作函数定义*/

Status InitList(LinkList* L)
{
	*L = (LinkList)malloc(sizeof(LNode));
	if (!(*L))	return ERROR;	//空间分配失败
	(*L)->next = NULL;	//指针域为空
	return OK;
}

Status DestoryList(LinkList *L)
{
	LinkList p;
	while (*L)			//当*L为空时循环结束
	{
		p = (*L)->next;	//p指向下一个结点
		free(*L);		//释放*L
		*L = p;
	}
	return OK;
}

Status ListEmpty(LinkList L)
{
	if (L->next)	return FALSE;
	else return TRUE;
}

Status ClearList(LinkList L) //不改变头结点和主调函数中的头指针,使用一级指针即可
{
	LinkList p, q;
	p = L->next;	//p指向链表第一个结点
	while (p)		//当p指向空时循环结束
	{
		q = p->next;
		free(p);
		p = q;
	}
	L->next = NULL;	//头结点指针域为空
	return OK;
}

int ListLength(LinkList L)
{
	int i = 0;	//计数
	LinkList p = L->next;	//p指向第一个元素
	while (p)
	{
		i++;
		p = p->next;
	}
	return i;
}

Status GetElem(LinkList L, int i, ElemType* e)
{
	LinkList p = L->next;	//p指向头结点后的第一个节点
	int j = 1;	//计数器
	while (p && j < i) //当j = i时,p指向的内容即为所求,结束循环
	{
		p = p->next;
		j++;
	}
	if (!p || j > i) return ERROR;	//当p为空或者i不符合范围时
	*e = p->data;	//获取第i个元素
	return OK;
}

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 1;
	LinkList p = L->next;
	while (p && !(*compare)(p->data, e))
	{
		i++;
		p = p->next;
	}

	if (!p)	return 0;
	else	return i;
}

Status PriorElem(LinkList L, ElemType cur_e, ElemType* pre_e)
{
	LinkList p = L->next;	//p指向第一个结点
	LinkList q;	//q为p的后继
	while (p->next)	//当p指向的结点的下一个结点为空时循环结束
	{
		q = p->next;
		if (q->data == cur_e)	//若e与q的数据域相等
		{
			*pre_e = p->data;	//p的数据域赋值给*pre
			return OK;
		}
		p = p->next;	//p后移
	}
	return INFEASIBLE;
}

Status NextElem(LinkList L, ElemType cur_e, ElemType* next_e)
{
	LinkList p;
	p = L->next;
	while (p->next)	//当p指向的结点的下一个结点为空时循环结束
	{
		if (p->data == cur_e)
		{
			*next_e = p->next->data; //将p下一个元素数据域赋值给*next
			return OK;
		}
		p = p->next;
	}

	return INFEASIBLE;
}

Status ListInsert(LinkList L, int i, ElemType e)	//在带头节点单链表中第i个元素之前插入元素e
{
	LinkList p = L;
	int j = 0;	//计数器
	while (p && j < i - 1) //当p为空或者j=i-1时结束循环,此时p指向第i-1个结点
	{
		p = p->next;
		j++;
	}

	if (!p || j > i - 1)	return ERROR;	//当p为空

	//创建一个新的节点储存e
	LinkList s = (LinkList)malloc(sizeof(LNode));
	if (!s)	return ERROR;
	s->data = e;

	//连接
	s->next = p->next;	//先后连
	p->next = s;	//在前挂

	return OK;
}

Status ListDelete(LinkList L, int i, ElemType* e)
{
	LinkList p = L;
	int j = 0;	//计数器

	//当第i个结点为空,或者j = i-1时结束循环,此时p指向第i-1个结点
	while (p->next && j < i - 1)
	{
		p = p->next;
		j++;
	}

	if (!(p->next) || j > i - 1)	return ERROR;

	LinkList q = p->next;	//q保存删除结点地址
	p->next = p->next->next; 	//删除
	*e = q->data;	//e存放删除节点的数据
	free(q);	//释放

	return OK;
}

Status ListTraverse(LinkList L, Status (*visit)(ElemType))
{
	LinkList p = L->next;
	while (p)	//当p为空时结束循环
	{
		(*visit)(p->data);	//每一个数据都进行visit函数操作,例如visit可以是打印函数
		p = p->next;
	}
	printf("\n");
	return OK;
}

测试

int main()
{
	//初始化链表
	LinkList L;
	if (InitList(&L))	 printf("初始化成功!\n");
	else				printf("初始化失败!\n");
	//判表空
	if (ListEmpty(L))	 printf("空!\n");
	else				printf("非空!\n");
	//表长
	printf("表长为:%d\n", ListLength(L));
	//插入元素
	ElemType i;
	for (i = 1; i <= 8; i++)
	{
		if (ListInsert(L, 1, i))	printf("头插入成功:%d\n", i);
		else					printf("头插入失败!\n");
	}
	//判表空
	if (ListEmpty(L))	printf("空!\n");
	else				printf("非空!\n");
	//表长
	printf("表长为:%d\n", ListLength(L));
	//遍历
	ListTraverse(L, visit);
	//取元素
	if (GetElem(L, 2, &i))	printf("取第2个元素:%d\n", i);
	else					printf("获取失败!\n");
	//定位元素
	int n = LocateElem(L, 2, compare);
	if (i != 0)	   printf("与2相关的元素是第%d个\n", n);
	else		  printf("定位失败!\n");
	n = LocateElem(L, 9, compare);
	if (n != 0)	   printf("与9相关的元素是第%d个\n", n);
	else		  printf("定位失败!\n");
	//前后继元素
	if (PriorElem(L, 2, &i))		printf("2的前元素:%d\n", i);
	else						  printf("获取失败!\n");
	if (PriorElem(L, 8, &i))		printf("8的前元素:%d\n", i);
	else						  printf("获取失败!\n");
	if (NextElem(L, 2, &i))		    printf("2的后元素:%d\n", i);
	else						  printf("获取失败!\n");
	if (NextElem(L, 1, &i))		    printf("1的后元素:%d\n", i);
	else						  printf("获取失败!\n");
	//删除
	if (ListDelete(L, 1, &i))	    printf("删除第%d个元素:%d\n", 1, i);
	else						  printf("删除失败!\n");
	if (ListDelete(L, 3, &i))	    printf("删除第%d个元素:%d\n", 3, i);
	else						  printf("删除失败!\n");
	//表长
	printf("表长为:%d\n", ListLength(L));
	//遍历
	ListTraverse(L, visit);
	//清空
	if (ClearList(L))	 printf("清空成功!\n");
	else				printf("清空失败!\n");
	//判表空
	if (ListEmpty(L))	 printf("空!\n");
	else				printf("非空!\n");
	//表长
	printf("表长为:%d\n", ListLength(L));
	//遍历
	ListTraverse(L, visit);
	//销毁链表
	if (DestoryList(&L))	printf("销毁成功!\n");
	else				   printf("销毁失败!\n");

	return 0;
}

Status compare(ElemType x, ElemType y)
{
	if (x == y)
		return OK;
	else
		return ERROR;
}

Status visit(ElemType e)
{
	printf("%d ", e);
	return OK;
}

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值